[jdk17]java.lang.reflect.InaccessibleObjectException:module java.base does not “opens java.util“

文章描述了一个在SpringBoot应用中集成Drools规则引擎时,由于使用了JDK17导致的初始化错误。错误源于JDK9及以上版本的模块化设计限制了某些API的访问。解决方案包括降级JDK版本至如JDK8,或者通过在启动命令中添加特定的模块开放选项来解决这一问题。

springboot2.3.1+drools+jdk17整合报错

错误信息

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'ruleInstance': Invocation of init method failed; nested exception is java.lang.ExceptionInInitializerError
	at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:160)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:415)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1791)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:594)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:516)
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:324)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:322)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
	at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1307)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1227)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:657)
	... 37 common frames omitted
Caused by: java.lang.ExceptionInInitializerError: null
	at com.thoughtworks.xstream.XStream.setupConverters(XStream.java:990)
	at com.thoughtworks.xstream.XStream.<init>(XStream.java:593)
	at com.thoughtworks.xstream.XStream.<init>(XStream.java:515)
	at com.thoughtworks.xstream.XStream.<init>(XStream.java:484)
	at com.thoughtworks.xstream.XStream.<init>(XStream.java:430)
	at com.thoughtworks.xstream.XStream.<init>(XStream.java:397)
	at org.kie.soup.commons.xstream.XStreamUtils.createTrustingXStream(XStreamUtils.java:119)
	at org.drools.compiler.kproject.models.KieModuleModelImpl$kModuleMarshaller.<init>(KieModuleModelImpl.java:170)
	at org.drools.compiler.kproject.models.KieModuleModelImpl$kModuleMarshaller.<init>(KieModuleModelImpl.java:169)
	at org.drools.compiler.kproject.models.KieModuleModelImpl.<clinit>(KieModuleModelImpl.java:167)
	at org.drools.compiler.kie.builder.impl.KieServicesImpl.newKieModuleModel(KieServicesImpl.java:276)
	at org.drools.compiler.kie.builder.impl.KieBuilderImpl.buildKieModuleModel(KieBuilderImpl.java:524)
	at org.drools.compiler.kie.builder.impl.KieBuilderImpl.init(KieBuilderImpl.java:160)
	at org.drools.compiler.kie.builder.impl.KieBuilderImpl.buildAll(KieBuilderImpl.java:212)
	at org.drools.compiler.kie.builder.impl.KieBuilderImpl.buildAll(KieBuilderImpl.java:192)
	at com.viewhigh.arctic.dis.clinical.config.RuleInstance.reloadDrl(RuleInstance.java:57)
	at com.viewhigh.arctic.dis.clinical.config.RuleInstance.lambda$init$0(RuleInstance.java:43)
	at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625)
	at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:762)
	at com.viewhigh.arctic.dis.clinical.config.RuleInstance.init(RuleInstance.java:42)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:389)
	at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:333)
	at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:157)
	... 49 common frames omitted
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make field private final java.util.Comparator java.util.TreeMap.comparator accessible: module java.base does not "opens java.util" to unnamed module @1fa268de
	at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354)
	at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)
	at java.base/java.lang.reflect.Field.checkCanSetAccessible(Field.java:178)
	at java.base/java.lang.reflect.Field.setAccessible(Field.java:172)
	at com.thoughtworks.xstream.core.util.Fields.locate(Fields.java:40)
	at com.thoughtworks.xstream.converters.collections.TreeMapConverter.<clinit>(TreeMapConverter.java:50)
	... 76 common frames omitted

解决方案

  • 原因:
    这是由于自jdk9之后,Jdk采用模块化改造,同时限定了对未命名模块间的部分API访问权限
  • 解决方案:
    • 第一种:降低jdk版本,比如将jdk17降级为jdk8;
    • 第二种:参考官方文档: https://docs.oracle.com/javase/9/migrate/toc.htm#JSMIG-GUID-12F945EB-71D6-46AF-8C3D-D354FD0B1781,针对于本项目可以添加上如下内容
      在这里插入图片描述
# 待添加的命令
--add-opens
java.base/java.util=ALL-UNNAMED
--add-opens
java.base/java.lang.reflect=ALL-UNNAMED
--add-opens
java.base/java.text=ALL-UNNAMED
--add-opens
java.desktop/java.awt.font=ALL-UNNAMED
--add-opens
java.base/java.lang=ALL-UNNAMED
<think>好的,我现在需要帮助用户解决在JMeter中遇到的java.lang.reflect.InaccessibleObjectException异常,特别是与Java 11相关的问题。首先,我得理解这个异常的原因。根据用户的描述,异常信息是“Unable to make field private final java.util.Comparator java.util.TreeMap.comparator accessible: module java.base does not opens java.util to unnamed module”。这看起来和Java模块系统的访问限制有关,尤其是在使用反射访问私有字段时。 Java 9引入了模块系统(JPMS),这加强了类封装性。默认情况下,非导出或未开放的包中的类不能被反射访问。用户可能在JMeter中运行某些脚本或插件,这些代码尝试通过反射访问java.util.TreeMap的私有字段comparator,而Java 11加强了这一限制,导致异常。 接下来,我需要考虑可能的解决方案。常见的解决方法包括: 1. **添加JVM参数**:使用`--add-opens`来开放相应的模块。例如,`--add-opens java.base/java.util=ALL-UNNAMED`,这会允许未命名模块(如JMeter的类路径上的代码)访问java.util包中的类。用户可能需要将类似的参数添加到JMeter的启动脚本中,比如在`jmeter.bat`或`jmeter.sh`中修改JVM_OPTS。 2. **降级Java版本**:如果用户不需要Java 11的新特性,暂时降级到Java 8可能解决问题,因为Java 8没有模块系统的限制。但长期来看,这可能不是最佳方案,因为Java 8已逐渐被淘汰。 3. **更新JMeter和相关插件**:检查是否有更新的JMeter版本或插件版本,可能开发者已经修复了与Java 11的兼容性问题。用户应该访问JMeter官网或插件仓库,确认版本兼容性。 4. **检查测试脚本或自定义代码**:用户的测试脚本中可能使用了反射访问JDK内部API,需要检查是否有这样的代码,并尝试修改,避免使用反射访问私有字段。例如,是否有第三方库或自定义的JSR223脚本导致此问题。 此外,用户提供的引用内容似乎涉及Java继承、Spring配置和AOP配置,可能与当前问题关联不大,但需要确认是否有相关配置错误导致反射调用。例如,是否在Spring的Bean定义中错误配置了某些需要反射的类,但可能性较低。 需要注意的是,JMeter自身在较新版本中对Java 11的支持可能更好,因此确保JMeter版本至少为5.4.1或更高,这些版本开始支持Java 11。同时,用户可能使用的某些插件,如自定义的JAR包或监听器,可能尚未适配Java 11,需要更新或寻找替代方案。 最后,应建议用户综合以上方法,优先尝试添加JVM参数,因为这是最直接的解决方案,同时检查JMeter和插件的更新状态。如果问题依旧,再考虑其他方法如降级Java版本。</think>### 解决JMeter中`java.lang.reflect.InaccessibleObjectException`异常的方法 #### **问题原因** 此异常是由于Java 11加强了模块系统的访问控制,阻止了通过反射访问JDK内部私有字段(如`java.util.TreeMap.comparator`)。JMeter或相关插件可能依赖反射操作此类字段,但Java 11默认禁止此类操作[^1]。 --- #### **解决方案** 1. **添加JVM参数开放模块访问** - 在JMeter启动脚本(如`jmeter.bat`或`jmeter.sh`)中,添加以下参数: ```bash JVM_ARGS="--add-opens java.base/java.util=ALL-UNNAMED" ``` 若需其他模块,可追加类似参数,例如: ```bash --add-opens java.base/java.lang=ALL-UNNAMED ``` - **操作步骤**: 1. 打开`jmeter`脚本文件。 2. 找到`JVM_ARGS`配置行,添加上述参数。 3. 保存并重启JMeter。 2. **降级至Java 8** - 如果无需Java 11特性,安装Java 8并配置JMeter使用该版本: ```bash export JAVA_HOME=/path/to/java8 ``` 3. **更新JMeter及插件** - 确保JMeter版本≥5.4.1(支持Java 11)。 - 更新插件(如通过`Plugins Manager`检查更新)。 4. **检查测试脚本或自定义代码** - 检查是否有脚本(如JSR223)直接调用反射访问JDK内部类。 - 替换依赖反射的代码逻辑,改用标准API。 --- #### **验证方法** 1. 添加JVM参数后,重新运行JMeter测试。 2. 如果异常消失,说明模块访问已开放。 3. 若仍存在异常,检查参数语法或尝试其他模块(如`java.base/java.lang.reflect`)。 --- #### **附加说明** - **引用[1]**提到Java的继承机制,但此问题与模块系统更相关。 - **引用[2][3]**涉及Spring配置,若JMeter测试中集成了Spring Bean或AOP,需检查相关配置是否触发反射调用。但可能性较低,建议优先按上述步骤解决。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值