为什么Java 9不会简单地将类路径上的所有JAR转换为自动模块?

时间:2017-07-18 12:32:11

标签: java java-9 jigsaw

为了理解我们的类别:

  • 平台显式模块
  • 应用程序显式模块
  • 打开模块
  • 自动模块
  • 未命名的模块

类路径中的所有类和jar都将是未命名模块的一部分。但为什么我们需要什么呢?自动模块的优势在哪里?我可以“要求”那些该死的传统罐子,使它们成为一个自动模块。我没有把它包括在内吗?

2 个答案:

答案 0 :(得分:9)

至少有两个原因:

  • 正如常规模块一样,自动模块对模块系统的某些检查是可疑的,例如not splitting packages。由于类路径上的JAR可以(并且偶尔会)拆分包,因此强制检查它们将是向后兼容的并且会破坏许多应用程序。
  • 未命名的模块可以读取所有平台模块,而自动模块只能读取那些进入模块图的模块。这意味着需要 java.desktop 模块(例如)的JAR将从类路径开始工作,但不能从模块图中工作,除非 java.desktop 也使其进入图形(通过依赖或--add-modules)。

我现在没时间检查第二个,但那是the State of the Module system所说的:

  

因此,在解析模块图之后,会使自动模块读取所有其他命名模块,无论是自动还是显式

解决方案适用于声明的依赖项,自动模块声明无。

答案 1 :(得分:0)

除了接受的答案中列出的项目外,还有另外一个区别:未命名的模块可以访问Java附带的所有模块软件包,即使它们没有被导出。 只要该类是公共的,访问就可以工作-与Java 9之前的工作相同。但是,从模块路径运行jar时,它将只能访问导出的包。

例如,如果某些.jar具有以下代码:

com.sun.jmx.remote.internal.ArrayQueue c = new com.sun.jmx.remote.internal.ArrayQueue(10);

当放置在类路径上时,它将正常运行而没有任何警告,但是当从模块路径(作为自动模块)运行时,它将在运行时失败:

Exception in thread "main" java.lang.IllegalAccessError: class test1.C 
(in module test1) cannot access class com.sun.jmx.remote.internal.ArrayQueue 
(in module java.management) because module java.management does not export 
com.sun.jmx.remote.internal to module test1

请注意,这与众所周知的非法反射访问警告不同,后者使用反射来访问私有字段或方法。在这里,我们正在静态(非反射地)访问公共类(但从非导出包中访问)。