关于 Java module 的讨论

2023-10-08 16:41:43 +08:00
 Dlin
之前一直没有用起来 module 这个特性,就算项目升级到 11 或 17,也是顺利过渡(未添加 module-info.java )但是最近报错未命名模块不能访问 java.base 模块下的未 open 的内容,所以今天学习了一下 module 这个特性。

因此也产生了疑惑。情景如下:
我建立了两个项目,项目 A 创建了 module-info.java 导出了但未进行 open com.txcf,包下有一个类 AA ,其中有一个私有变量 a ;


另一个项目 B 实验情况如下:
第一次创建了 module-info.java 我试图通过反射访问 A 模块 AA 类的私有变量 a,报错:InaccessibleObjectException ,这是预期发生的情况。
第二次我删除了 module-info.java ,该模块变为未命名模块,我试图通过反射访问 AA 类的私有变量 a,却能访问了。

奇怪的是我在第一次和第二次的情况中都不能访问 java.util 中的类的私有成员变量,比如 ArrayList 中的 size 变量。

我在通过 debug 时发现,第一次的情况,调用类和被调用类的 class 获取到的 Module 是两个不同的模块(这也符合预期情况),但是第二次的情况获取的 Module 却是相同的 Module 实例(都是未命名模块)

问题:
1 、非 jdk 官方模块在被未命名模块导入时,被导入模块无论是否命名都会直接导入到未命名模块吗?
2 、问题 1 成立(实验似乎也如此)的话,为何 jdk 官方只保护自己的模块,不保护第三方已命名模块呢?或者说是可以有参数开启保护的呢?
1507 次点击
所在节点    Java
3 条回复
hengyunabc
2023-10-08 18:41:23 +08:00
java module 不太可能被太规模应用在业务系统里。它设计之初就是为了 jdk 本身拆分的,它也比较好的完成了这个任务。后面出现的 jlink, jpackage 尽管好像没有太规模应用起来,但应用可以很轻松打包出一个自己的轻量化 jdk 了。

比如这个: https://github.com/hengyunabc/lite-jdk

为了兼容,不同版本的 jdk 对于 unnamed module 的访问控制不一样,是慢慢收紧的。jdk 9/11 ,应该是 unnamed module 还可以反射访问 jdk 内部的模块。只会打印出提示信息。

在 jdk 17 之后,反射访问 jdk 内部模块是直接非法的。

这个工具可以运行时动态打开 jdk 的 module ,可以减少一些 export/open 的 jvm 参数配置: https://github.com/hengyunabc/jpms-tools
infoscope
2023-10-08 21:24:30 +08:00
和当年用过的 osgi 有点像
Dlin
2023-10-08 22:07:48 +08:00
@hengyunabc 好的,感谢大佬的解答,就说怎么那么 github 主页那么眼熟,原来是 arthas 的维护者😃

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/979916

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX