在Java 9中如何避免拆分软件包

时间:2018-08-13 17:55:53

标签: java java-9 modularization

我是Java 9的新手,正在参加Java在YouTube上的模块化视频讲座。 他们提到了模块化的3个好处- 1.没有遗漏的依赖 2.没有周期性的依赖 3.没有拆分包。

据我对拆分包的了解,假设一个应用程序依赖于多个依赖关系,并且说abc.pqr.xyz包存在于超过1个jar中。 这样就有可能从jar1中使用该包中的某些类,而从jar2中使用其他类。 这可能会在运行时导致一些问题,这些问题将很难调试。

视频说模块化解决了这个问题。 但这就是我要理解的方式?

假设有test.module1,其模块信息如下-

module test.module1{
exports abc.pqr.xyz;
}

具有以下模块信息的另一个module2-

module test.module2{
 exports abc.pqr.xyz;
}

现在让我们说在我的应用程序中,我添加了这两个模块的依赖关系-

module test.myapp{
 requires test.module1;
 requires test.module2;
}

再次,我有2个模块依赖项,其中有一些类可能会出现在这两个模块中。 那么,在运行时如何从哪个模块中解析类定义呢? Java 9如何避免拆分包问题?

2 个答案:

答案 0 :(得分:5)

Java模块系统通过在JVM启动时拒绝这种情况来解决拆分包问题。 JVM启动时,它将立即开始解析模块图,并且在test.myapp的模块路径中遇到两个模块时,JVM将抛出错误,指示test.module1test.module2正在尝试导出同一包。

答案 1 :(得分:4)

使用问题中描述的方案,您将开始面临错误阅读:

  

模块test.myapptest.module1test.module2读取包

The State of the Module System中的模块的

可读性 阐述了以下模块的使用,并应引起您的用例关注(强调我的意思):

  

模块图中定义的可读性关系是基础   可靠配置的证明:模块系统确保

     
      
  • 每个依赖关系都由另一个模块完全满足
  •   
  • 模块图是非循环的
  •   
  • 每个模块最多读取一个定义给定程序包的模块
  •   
  • ,并且定义同名程序包的模块不会互相干扰
  •   

在模块系统中暗示相同的好处也得到了详细说明

  

可靠的配置不仅更加可靠; 也可以是   更快。当模块中的代码引用包中的类型时,则表示   保证可以在该模块或该模块中定义包   正是该模块读取的模块之一。

     

寻找   因此,无需搜索特定类型的定义   在多个模块中,或者在整个课程路径上更糟糕


也就是说,当前实现的解决方案是

  • 如果模块test.module1test.module2显式模块,则可以选择在之一中实现abc.pqr.xyz包他们 或者,您可以将它们从两者中拉出到自己的单独模块test.mergeModule中,此模块随后可以在其客户端中用作独立模块。

  • 如果这些(或其中任何一个)是自动模块,则可以使用bridge extended to the classpath并将此类jar保留在类路径上,并视为未命名模块,默认情况下应导出其所有软件包。同时,在读取其他所有命名模块的同时,任何自动模块也将读取 unnamed module

    再次引用该文档并举例说明,以便您可以与问题关联:

      

    如果显式模块com.foo.app中的代码引用了   com.foo.bar,例如,该类型的签名指的是   其中一个JAR文件仍在类路径中,然后在   自com.foo.appcom.foo.app将无法访问该类型   无法依赖未命名的模块。

         

    可以通过暂时将com.foo.app视为自动模块来补救,以使其   代码可以从类路径访问类型,直到   类路径上的相关JAR文件可以视为自动   模块或转换为显式模块。