我有一个使用 Java 11 的 spring-boot 项目。项目依赖于 redis,因此我在 pom.xml 中包含了 spring-boot-starter-data-redis 依赖项。 spring-data-redis jar 有一个名为 JedisClientUtils 的类,它在类级别有一个默认的访问修饰符。
当我使用 mvn spring-boot:run 运行此项目时,我收到 JedisClientUtils 类的 NoClassDefFound 错误。 在调试问题时,我发现使用 Java 8 时同一项目可以成功运行。 我的pom.xml有插件如下:
<build>
<finalName>${war.name}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>11</source>
<target>11</target>
</configuration>
<dependencies>
<dependency>
<!-- update compiler plugin dependency on ASM for Java 11 compatibility -->
<groupId>org.ow2.asm</groupId>
<artifactId>asm</artifactId>
<version>6.2</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
使用默认访问类构建 java 11 项目还需要什么吗 日志供引用:
spring-boot-data-redis 版本:2.1.1.RELEASE jedis.版本:2.9.0java.lang.reflect.InvocationTargetException at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (Native Method) at jdk.internal.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62) at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke (Method.java:566) at org.springframework.boot.maven.AbstractRunMojo$LaunchRunner.run (AbstractRunMojo.java:558) at java.lang.Thread.run (Thread.java:834) Caused by: java.lang.NoClassDefFoundError: Could not initialize class org.springframework.data.redis.connection.jedis.JedisClientUtils at org.springframework.data.redis.connection.jedis.JedisConnection.isQueueing (JedisConnection.java:339)
最佳答案
我遇到了类似的问题,但您的问题中没有足够的细节来确保它是相同的。
但是,如果这有帮助,这就是我所拥有的:
ForkJoinPool
实现在 java 8 之后的某个地方发生了更改,它可能会影响您的某些代码。一般来说,当 Java 中创建一个新线程时,它要么在构造函数中获取特定的类加载器,要么重用父级的类加载器。 Java 8 版本的 ForkJoinPool
没有为其线程指定类加载器(即使用父级线程),但 Java 11 的 ForkJoinPool
指定了系统类加载器。现在,当您尝试在 ForkJoinPool 线程中的某个位置按名称加载类而未指定正确的类加载器(如 JedisClientUtils 那样)时,默认情况下它将使用系统类加载器,而系统类加载器不知道您的应用程序类。 CompletableFuture 和并行 Streams 使用 ForkJoinPool 因此是此问题的潜在问题。
这是一个失败的示例:
@Repository
public interface RedisRepo extends CrudRepository<Statistic, Long> {
}
@SpringBootApplication
public class Start {
...
public static void main(String[] args) {
new SpringApplication(Start.class).run(args);
CompletableFuture.runAsync(() -> {
redisRepo.deleteAll();
});
}
}
可能的修复:
public static void main(String[] args) {
new SpringApplication(Start.class).run(args);
CompletableFuture.runAsync(() -> {
ClassLoader contextClassLoaderBackup = Thread.currentThread().getContextClassLoader();
try {
Thread.currentThread().setContextClassLoader(Start.class.getClassLoader());
redisRepo.deleteAll();
} finally {
Thread.currentThread().setContextClassLoader(contextClassLoaderBackup);
}
});
}
关于maven - 具有默认访问权限的类会导致 java 11 的 Spring Boot 项目在运行时出现 NoClassDefFound 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56967408/