8

各种资源(infoqjigsaw-devosdir)表明,在不同的 java 模块中拥有相同的包将导致 a LayerInstantiationException,即使包在模块内部(非导出)也是如此。
这似乎与要求所说的完全相反:

Java 编译器、虚拟机和运行时系统必须确保包含同名包的模块不会相互干扰。如果两个不同的模块包含同名的包,那么从每个模块的角度来看,该包中的所有类型和成员都仅由该模块定义。

那么(将)应用程序使用的两个模块是否能够包含同名的私有包?

编辑
这是Stanislav Lukyanov 指出的 JMPS问题

4

2 回答 2

7

正如您在链接的讨论中所说,问题是关于类加载器和模块之间的映射。

当您通过类加载器加载两个模块M1并且M2都包含非导出(又名隐藏)包时, JPMS 必须拒绝此类配置,因为否则两个关键 JPMS 原则 - 强封装和可靠配置 - 可能会被破坏。通过在此处抛出异常,JPMS 实际上实现了您引用的要求,并确保在执行期间没有冲突可能会破坏任何内容。PCL

另一方面,当您通过两个加载M1器加载时,您实际上是在创建两个运行时包and ,因此没有冲突并且可以实例化。M2CL1CL2{CL1, P}{CL2, P}Layer

这里的可用性问题是java对应用层的所有模块(“启动”模块,从命令行参数创建)使用单个加载器,这会导致LayerInstantiationException. 这目前是 JPMS 列表上的一个未解决问题,请参阅 [此处] ( http://openjdk.java.net/projects/jigsaw/spec/issues/#AvoidConcealedPackageConflicts )。但无论问题的解决方案如何,如果需要,您应该能够通过编写一个将创建您需要的小型主类来处理拆分包Configuration(顺便说一句,JPMS 感知应用程序容器可能会为您完成)。

于 2016-11-16T19:33:03.807 回答
1

这个定义可以解释。它仍然是正确的,因为 Jigsaw 确保两个模块永远不会通过在发生此类冲突时使类加载崩溃来定义共享包。

如果您查看 Java 9 的类加载器实现,您可以看到包名映射到单个模块。因此不可能两个有两个模块来声明所有权。然而,有可能两个处于子父关系的类加载器定义了同一个包。

于 2016-11-16T15:25:50.793 回答