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

简介: Java9之后的模块化烦恼解决(由RocketMQ升级OpenJDK11想到的)
本文基于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-exportsopens--add-opensrequires--add-reads

然后拼接启动参数:


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

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

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

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

相关实践学习
消息队列RocketMQ版:基础消息收发功能体验
本实验场景介绍消息队列RocketMQ版的基础消息收发功能,涵盖实例创建、Topic、Group资源创建以及消息收发体验等基础功能模块。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
相关文章
|
4月前
|
Java 测试技术 API
Java新纪元:模块化设计重塑开发体验,让代码如艺术品般优雅!
【8月更文挑战第30天】Java模块化设计是一种通过将应用程序分解为独立、可重用模块来提高代码可维护性和可扩展性的方法。其核心是自Java 9引入的Java Platform Module System(JPMS)。模块化设计增强了封装性,简化了依赖管理和系统维护,并通过按需加载模块提升了性能。每个模块有明确职责和接口,通过`module-info.java`文件定义。实战示例展示了如何创建和使用模块。最佳实践包括明确模块职责、减少依赖、使用模块描述符及模块化测试,从而构建健壮、可维护的应用程序。
63 2
|
4月前
|
Java
【思维导图】JAVA网络编程思维升级:URL与URLConnection的逻辑梳理,助你一臂之力!
【思维导图】JAVA网络编程思维升级:URL与URLConnection的逻辑梳理,助你一臂之力!
60 1
|
1月前
|
消息中间件 存储 Java
RocketMQ文件刷盘机制深度解析与Java模拟实现
【11月更文挑战第22天】在现代分布式系统中,消息队列(Message Queue, MQ)作为一种重要的中间件,扮演着连接不同服务、实现异步通信和消息解耦的关键角色。Apache RocketMQ作为一款高性能的分布式消息中间件,广泛应用于实时数据流处理、日志流处理等场景。为了保证消息的可靠性,RocketMQ引入了一种称为“刷盘”的机制,将消息从内存写入到磁盘中,确保消息持久化。本文将从底层原理、业务场景、概念、功能点等方面深入解析RocketMQ的文件刷盘机制,并使用Java模拟实现类似的功能。
41 3
|
2月前
|
存储 消息中间件 安全
JUC组件实战:实现RRPC(Java与硬件通过MQTT的同步通信)
【10月更文挑战第9天】本文介绍了如何利用JUC组件实现Java服务与硬件通过MQTT的同步通信(RRPC)。通过模拟MQTT通信流程,使用`LinkedBlockingQueue`作为消息队列,详细讲解了消息发送、接收及响应的同步处理机制,包括任务超时处理和内存泄漏的预防措施。文中还提供了具体的类设计和方法实现,帮助理解同步通信的内部工作原理。
JUC组件实战:实现RRPC(Java与硬件通过MQTT的同步通信)
|
1月前
|
SQL Java OLAP
java实现“数据平滑升级”
java实现“数据平滑升级”
44 2
|
1月前
|
SQL Java OLAP
java实现“数据平滑升级”
java实现“数据平滑升级”
20 0
|
2月前
|
消息中间件 存储 JSON
rabbitmq基础教程(ui,java,springamqp)
本文提供了RabbitMQ的基础教程,包括如何使用UI创建队列和交换机、Java代码操作RabbitMQ、Spring AMQP进行消息发送和接收,以及如何使用不同的交换机类型(fanout、direct、topic)进行消息路由。
33 0
rabbitmq基础教程(ui,java,springamqp)
|
2月前
|
消息中间件 前端开发 Java
java高并发场景RabbitMQ的使用
java高并发场景RabbitMQ的使用
119 0
|
3月前
|
Java API 开发者
【Java模块化新飞跃】JDK 22模块化增强:构建更灵活、更可维护的应用架构!
【9月更文挑战第9天】JDK 22的模块化增强为开发者构建更灵活、更可维护的应用架构提供了强有力的支持。通过模块化设计、精细的依赖管理和丰富的工具支持,开发者可以更加高效地开发和管理应用,提高应用的性能和可维护性。
100 10
|
3月前
|
Oracle Java 关系型数据库
【颠覆性升级】JDK 22:超级构造器与区域锁,重塑Java编程的两大基石!
【9月更文挑战第6天】JDK 22的发布标志着Java编程语言在性能和灵活性方面迈出了重要的一步。超级构造器和区域锁这两大基石的引入,不仅简化了代码设计,提高了开发效率,还优化了垃圾收集器的性能,降低了应用延迟。这些改进不仅展示了Oracle在Java生态系统中的持续改进和创新精神,也为广大Java开发者提供了更多的可能性和便利。我们有理由相信,在未来的Java编程中,这些新特性将发挥越来越重要的作用,推动Java技术不断向前发展。
下一篇
DataWorks