当前位置: 首页 > 知识库问答 >
问题:

在java 11的spring boot project中,具有默认访问权限的类在运行时会导致NoClassDefound错误

井旺
2023-03-14

我有一个使用Java11的spring-boot项目。项目依赖于redis,所以我在pom.xml中包含了spring-boot-starter-data-redis依赖项。spring-data-redis jar有一个名为JedisClientUtils的类,它在类级别上有一个默认的访问修饰符。

当我使用mvn spring-boot:run运行这个项目时,对于JedisClientUtils类,我得到一个错误noClassDefound错误。在调试这个问题时,我发现同一个项目在使用Java8时成功运行。我的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>

构建一个带有默认访问类日志的Java11项目还需要什么吗:

jdk.internal.reflect.invocationtargetexception(原生方法)jdk.internal.reflect.nativeMethodAccessorImpl.Invoke(nativeMethodAccessorImpl.java:62)jdk.internal.reflect.delegatingmethodAccessorImpl.java:43)java.lang.reflect.methodInvoke(delegatingmethodAccessorImpl.java:566)org.springframework.boot.maven.abstractrunmojo$launchrunner.run(abstractrunmoja:558)java.lang.thread.run(thread.java:834)原因:java.lang..NoClassDefoundError:无法在org.springframework.data.redis.connection.jedis.jedisclientutils中初始化类org.springframework.data.redis.connection.jedis.jedisconnection.isqueueing(jedisconnection.java:339)

spring-boot-data-redis verison:2.1.1。发行版:jedis.version:2.9.0

共有1个答案

卫高明
2023-03-14

您可以配置ForkJoinPool的线程工厂来设置应用程序范围内的类加载器,而不是每次运行任务时都设置上下文类加载器。请参见CompletableFuture/ForkJoinPool Set Class Loader(非脏答案)。

需要注意的是,这个突破性的变化似乎是由一个断言引起的,即不能依赖于应用程序生命周期中某个特定点的公共池初始化线程(例如,公共池线程可以在创建初始化spring应用程序的类加载器之前初始化)。

特别是对于Spring应用程序来说,考虑到Java9中引入的重大变化,以及无法保证使用Spring应用程序所需的类加载器初始化公共池(即使使用自定义工厂),配置自定义ForkJoinPool并将任务提交给该ForkJoinPool并将任务提交给该ForkJoinPool似乎是谨慎的做法,而不是依赖commonPool。类似于:

@Bean
public ForkJoinPool myForkJoinPool() {
    int threads = Runtime.getRuntime().availableProcessors();
    return new ForkJoinPool(threads, makeFactory("MyFactory"), null, false);
}

private ForkJoinWorkerThreadFactory makeFactory(String prefix) {
    return pool -> {
        final ForkJoinWorkerThread worker = ForkJoinPool.defaultForkJoinWorkerThreadFactory.newThread(pool);
        worker.setName(prefix + worker.getPoolIndex());
        worker.setContextClassLoader(Application.class.getClassLoader());
        return worker;
    };
}

您的池被注入到执行并行操作的组件中,并被调用:

myForkJoinPool.submit(myTask)
 类似资料:
  • 关于下面的示例代码,虽然类测试内部的Test()构造函数是公共的,但类测试本身不是公共的,因此不能从它自己的包外部调用Test()构造函数。 这是否使public关键字变得多余?如果是这样,我想知道为什么javac在一个访问被隐式声明为default(“package private”)的类内部使用时,不发出关于public的冗余使用的警告? 需要说明的是:就是在我编译test.java的时候,我

  • 我试图理解Java8中引入的新日期和时间API。 我在日志文件中有一个unix时间戳,我需要对它进行处理,以确定它属于今天或昨天的哪个小时。 我遇到了一个不寻常的错误在Android Studio,想更好地理解它。

  • 我试图理解Java8中引入的新日期和时间API。 我在日志文件中有一个unix时间戳,我需要对它进行处理,以确定它属于今天或昨天的哪个小时。 我在Android Studio中遇到了一个不寻常的错误,我想更好地理解它。

  • 我有关于Android 6(Marshmallow)运行时权限的问题。如果用户想从图库中挑选一张照片,我们是否应该要求权限? 似乎我可以访问画廊,即使我关闭了存储权限。

  • 我在Windows 10中使用cmake构建了一个C项目(Visual Studio 2019,尽管它只使用了构建工具而不是GUI,实际使用的编译器是clang)。如果我在没有编译器优化的情况下构建它,它会构建得很好,但是如果我使用< code > set(CMAKE _ CXX _ FLAGS _ RELEASE“-O3”)传递< code>-O3,那么编译后的二进制文件会有某种权限问题。cte

  • java.security.访问控制异常:拒绝访问(java.net.SocketPersion127.0.0.1:1099连接,解析) 我的服务器端工作正常,服务器上没有错误。。当我运行客户端代码时,我得到了这个拒绝访问的错误(“java.net.SocketPermission”“127.0.0.1:1099”“connect,resolve”)。 请任何专家帮助我:( 这是我的客户代码