Java 9重叠非导出包
各种资源( infoq , jigsaw-dev , osdir )表明在不同的java模块中具有相同的包将导致LayerInstantiationException
,即使包是模块的内部(未导出)。
这似乎与要求所说的完全相反:
Java编译器,虚拟机和运行时系统必须确保包含相同名称的包的模块不会相互干扰。 如果两个不同的模块包含相同名称的包,那么从每个模块的角度来看,该包中的所有类型和成员仅由该模块定义。
那么(将)应用程序使用的两个模块能够包含同名的私有包吗?
编辑
这是斯坦尼斯拉夫·卢基亚诺夫指出的JMPS 问题
正如您所讨论的讨论所述,问题在于类加载器和模块之间的映射。
当您通过类加载器CL
加载两个模块M1
和M2
都包含非导出(也称为隐藏)的包P
,JPMS必须拒绝这样的配置,否则两个关键的JPMS原则 – 强大的封装和可靠的配置 – 都可能被打破。 通过在此处抛出exception,JPMS实际上实现了您引用的要求,并确保在执行期间不会发生任何冲突。
另一方面,当你通过两个加载器CL1
和CL2
加载M1
和M2
,你实际上创建了两个运行时包{CL1, P}
和{CL2, P}
,所以没有碰撞而且Layer
可以被实例化。
这里的可用性问题是java
对应用程序层的所有模块使用单个加载器(“起始”模块,从命令行参数创建)导致LayerInstantiationException
。 这是目前JPMS列表中的一个未解决的问题,请参见[此处]( http://openjdk.java.net/projects/jigsaw/spec/issues/#AvoidConcealedPackageConflicts )。 但无论问题的解决方案如何,如果需要,你应该能够通过编写一个小的主类来处理拆分包,这个主类将创建你需要的Configuration
(BTW一个支持JPMS的应用程序容器可能会为你做这个)。
该定义可以解释。 它仍然是正确的,因为Jigsaw确保两个模块永远不会通过在发生此类冲突时崩溃类加载来定义共享包。
如果您查看Java 9的类加载器实现,您可以看到包名称被映射到单个模块。 因此,它不可能有两个模块来声明所有权。 但是,子父关系中的两个类加载器可能定义相同的包。