【发布时间】:2020-07-16 21:03:01
【问题描述】:
从 Java 8 迁移到 Java 11 打开 JDK。出现奇怪的错误,其中来自 java.base 模块的一个类 (java.util.Arrays) 无法从 java.base 模块访问另一个名为 (jdk.internal.util.ArraysSupport) 的类。
如果我查看 java.base 模块的模块信息 jdk.internal.util 包没有导出。我尝试了--add-export java.base/jdk.internal.util=ALL-UNNAMED,但得到了同样的错误。因为--add-export 有助于将包导出到另一个模块。这里的问题是来自同一模块的一个类无法访问来自同一模块的另一个类。不知道这里出了什么问题,正在寻找建议。
java.lang.NoClassDefFoundError: Could not initialize class jdk.internal.util.ArraysSupport
at java.base/java.util.Arrays.equals(Arrays.java:2873)
at java.base/sun.security.util.ObjectIdentifier.equals(ObjectIdentifier.java:345)
at java.base/sun.security.pkcs.PKCS7.parse(PKCS7.java:185)
at java.base/sun.security.pkcs.PKCS7.parse(PKCS7.java:154)
at java.base/sun.security.pkcs.PKCS7.<init>(PKCS7.java:136)
at java.base/sun.security.util.SignatureFileVerifier.<init>(SignatureFileVerifier.java:127)
at java.base/java.util.jar.JarVerifier.processEntry(JarVerifier.java:297)
at java.base/java.util.jar.JarVerifier.update(JarVerifier.java:230)
at java.base/java.util.jar.JarFile.initializeVerifier(JarFile.java:757)
at java.base/java.util.jar.JarFile.ensureInitialization(JarFile.java:1034)
at java.base/java.util.jar.JavaUtilJarAccessImpl.ensureInitialization(JavaUtilJarAccessImpl.java:69)
at java.base/jdk.internal.loader.URLClassPath$JarLoader$2.getManifest(URLClassPath.java:870)
at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:788)
at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:700)
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:623)
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
at java.base/java.lang.Class.forName0(Native Method)
at java.base/java.lang.Class.forName(Class.java:315)
at org.apache.commons.dbcp2.BasicDataSource.createConnectionFactory(BasicDataSource.java:2124)
at org.apache.commons.dbcp2.BasicDataSource.createDataSource(BasicDataSource.java:2033)
at org.apache.commons.dbcp2.BasicDataSource.getConnection(BasicDataSource.java:1533)
at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:158)
at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:116)
at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:79)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:371)
at org.springframework.jdbc.core.JdbcTemplate.batchUpdate(JdbcTemplate.java:590)
at com.rbccm.sales.hub.employee.tasklet.SalesHubSQLExecutionTasklet.execute(SalesHubSQLExecutionTasklet.java:45)
at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:406)
at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:330)
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:140)
at org.springframework.batch.core.step.tasklet.TaskletStep$2.doInChunkContext(TaskletStep.java:272)
at org.springframework.batch.core.scope.context.StepContextRepeatCallback.doInIteration(StepContextRepeatCallback.java:81)
at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:375)
at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:215)
at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:145)
at org.springframework.batch.core.step.tasklet.TaskletStep.doExecute(TaskletStep.java:257)
at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:200)
at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:148)
at org.springframework.batch.core.job.flow.JobFlowExecutor.executeStep(JobFlowExecutor.java:66)
SalesHubSQLExecutionTasklet类的代码如下
@Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
JdbcTemplate jdbcTemplate = new JdbcTemplate(this.getDataSource());
long start = System.currentTimeMillis();
try {
if (!StringUtils.isBlank(this.getSql())) {
if (this.getSql().toUpperCase().startsWith("UPDATE")) {
int result = jdbcTemplate.update(this.getSql());
LOGGER.info("{} records updated executing SQL [{}]", result, this.getSql());
}
else {
jdbcTemplate.execute(this.getSql());
}
}
else if (this.sqls != null && this.sqls.length > 0) {
int[] result = jdbcTemplate.batchUpdate(sqls);
for (int i=0; i<sqls.length; i++) {
LOGGER.info("SQL [{}] result [{}].", sqls[i], result[i]);
}
}
}
catch (Exception ex) {
LOGGER.error("Error executing SQL [{}]", this.getSql(), ex);
}
LOGGER.info("Step {} execute SQL [{}] finished in {} ms.", chunkContext.getStepContext().getStepName(), this.getSql(), (System.currentTimeMillis()-start));
return RepeatStatus.FINISHED;
}
第 45 行是
int[] result = jdbcTemplate.batchUpdate(sqls);
我试图在 Unix 机器上加载一个单独的普通类。而且效果很好
Class<?> classToLoad = Class.forName("jdk.internal.util.ArraysSupport");
它成功加载了类,所以不确定这里有什么问题!
【问题讨论】:
-
您能发布您的 SalesHubSQLExecutionTasklet 代码吗?和你的框架版本(春季批次),或检查this
-
也尝试在简单的命令行驱动程序中加载相同的类。
-
感谢@MatteoZanini 回复。我刚刚添加了上面的代码
-
感谢@efekctive:我尝试加载类 Class.forName("jdk.internal.util.ArraysSupport");在 unix box 上的一个普通类中,它工作得很好。不知道为什么整个服务运行时它没有加载:(
-
使用导出选项毫无意义。这两个类都在同一个模块中,因此它们不需要导出选项即可相互访问。并且错误消息并没有说一个类“无法访问另一个类”,它清楚地表明“无法初始化”该类。由于初始化在正常情况下工作,因此必须改变环境,例如执行代码检测。
标签: java spring spring-jdbc java-11