Java9之后的模块化烦恼解决(由RocketMQ升级OpenJDK11想到的)

JDK源码剖析 同时被 2 个专栏收录
22 篇文章 2 订阅
4 篇文章 0 订阅

本文基于OpenJDK11

最近从OpenJDK8升级到了OpenJDK11,系统业务MQ用的RocketMQ,升级RocketMQ过程中,在已修改好JVM参数的情况下(参考我另一篇文章),遇到如下异常:

java.lang.IllegalStateException: java.lang.reflect.InaccessibleObjectException: Unable to make public void jdk.internal.ref.Cleaner.clean() accessible: module java.base does not "exports jdk.internal.ref" to unnamed module @3590fc5b
        at org.apache.rocketmq.store.MappedFile$1.run(MappedFile.java:105) ~[rocketmq-store-4.5.0.jar:4.5.0]
        at java.base/java.security.AccessController.doPrivileged(Native Method) ~[na:na]
        at org.apache.rocketmq.store.MappedFile.invoke(MappedFile.java:98) ~[rocketmq-store-4.5.0.jar:4.5.0]
        at org.apache.rocketmq.store.MappedFile.clean(MappedFile.java:94) ~[rocketmq-store-4.5.0.jar:4.5.0]
        at org.apache.rocketmq.store.MappedFile.cleanup(MappedFile.java:434) ~[rocketmq-store-4.5.0.jar:4.5.0]
        at org.apache.rocketmq.store.ReferenceResource.release(ReferenceResource.java:63) ~[rocketmq-store-4.5.0.jar:4.5.0]
        at org.apache.rocketmq.store.ReferenceResource.shutdown(ReferenceResource.java:47) ~[rocketmq-store-4.5.0.jar:4.5.0]
        at org.apache.rocketmq.store.MappedFile.destroy(MappedFile.java:442) ~[rocketmq-store-4.5.0.jar:4.5.0]
        at org.apache.rocketmq.store.index.IndexFile.destroy(IndexFile.java:89) ~[rocketmq-store-4.5.0.jar:4.5.0]
        at org.apache.rocketmq.store.index.IndexService.load(IndexService.java:71) ~[rocketmq-store-4.5.0.jar:4.5.0]
        at org.apache.rocketmq.store.DefaultMessageStore.load(DefaultMessageStore.java:195) ~[rocketmq-store-4.5.0.jar:4.5.0]
        at org.apache.rocketmq.broker.BrokerController.initialize(BrokerController.java:256) ~[rocketmq-broker-4.5.0.jar:4.5.0]
        at org.apache.rocketmq.broker.BrokerStartup.createBrokerController(BrokerStartup.java:218) ~[rocketmq-broker-4.5.0.jar:4.5.0]
        at org.apache.rocketmq.broker.BrokerStartup.main(BrokerStartup.java:58) ~[rocketmq-broker-4.5.0.jar:4.5.0]
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make public void jdk.internal.ref.Cleaner.clean() accessible: module java.base does not "exports jdk.internal.ref" to unnamed module @3590fc5b
        at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:340) ~[na:na]
        at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:280) ~[na:na]
        at java.base/java.lang.reflect.Method.checkCanSetAccessible(Method.java:198) ~[na:na]
        at java.base/java.lang.reflect.Method.setAccessible(Method.java:192) ~[na:na]
        at org.apache.rocketmq.store.MappedFile$1.run(MappedFile.java:102) ~[rocketmq-store-4.5.0.jar:4.5.0]
        ... 13 common frames omitted

这个就是模块化导致的缺陷了,我们知道,在Java9之后引入了模块化的概念,是将类型和资源封装在模块中,并仅导出其他模块要访问其公共类型的软件包。如果模块中的软件包未导出或打开,则表示模块的设计人员无意在模块外部使用这些软件包。 这样的包可能会被修改或甚至从模块中删除,无需任何通知。 如果仍然使用这些软件包通过使用命令行选项导出或打开它们,可能会面临破坏应用程序的风险!

那么对于上面这个异常,我们怎么解决呢?可以通过加入启动参数。

首先,这类异常一般符合下面这个模板:

Unable to make {member} accessible: module {A} does not '{operation} {package}' to {B}

我们根据operation,决定要加的启动参数:

operationjvm启动参数
exports–add-exports
opens–add-opens
requires–add-reads

然后拼接启动参数:

{上面的jvm启动参数} {A}/{package}={B}

上面的异常需要的参数就是(ALL-UNNAMED代表所有jdk编译出来的匿名类):

--add-exports java.base/jdk.internal.ref=ALL-UNNAMED

更多请参考Java 9 揭秘(9. 打破模块封装)

  • 1
    点赞
  • 4
    评论
  • 1
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
©️2020 CSDN 皮肤主题: 酷酷鲨 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值