在Java 9中创建了多少个未命名的模块?

时间:2017-09-17 10:51:57

标签: java java-9 java-module unnamed-module

我试图了解JPMS的工作原理。

来自here

  

类路径尚未完全消失。所有JAR(模块化或非模块化)   类路径中的类将包含在未命名模块中。   与自动模块类似,它导出所有包并读取所有包   其他模块。但显然它没有名字。为了那个原因   原因是,它不能被命名的应用程序模块所需和读取。   未命名的模块又可以访问所有其他模块。

请注意...on the classpath will be contained in the Unnamed Module。模块是单数。

来自here

  

为了兼容性,类路径上的所有代码都打包为   特殊的未命名模块,没有隐藏包和完全访问权限   整个JDK。

再次unnamed module。模块是单数。

我是否理解JPMS中始终只有一个未命名的模块?是否意味着在Java9之前开发但未针对Java9更新的应用程序将作为一个未命名的模块加载?

2 个答案:

答案 0 :(得分:6)

  

我是否理解JPMS中始终只有一个未命名的模块?

简而言之

一般来说,没有。但是让我们这样说:如果你在类路径上放置一些甚至所有JAR,并且你的应用程序没有创建类加载器来加载任何其他内容,那么你只需要关注一个未命名的模块。

更详细

每个ClassLoader都有its own unnamed module,用于表示从类路径加载的类。这是必要的,因为模块系统要求所有内容都在模块中。

正如nullpointer's answer详细解释的那样,默认情况下,应用程序将使用三个单独的类加载器。它可能会启动自己的类加载器,例如加载插件。但是,如果它不这样做,所有应用程序代码将最终在系统/应用程序类加载器中,因此在同一个未命名的模块中。这就是为什么通常只有一个你需要关心的原因。

  

是否意味着在Java9之前开发但未针对Java9更新的应用程序将作为一个未命名的模块加载?

这与代码(应用程序,框架,库)是否以Java 9为目标无关 - 它只取决于您在类路径或module path上放置JAR的路径。

如果它在类路径上,它最终会在未命名的模块中与其他类路径内容一起结束。对于没有模块描述符的普通JAR,以及包含一个的模块化JAR也是如此。

如果它在模块路径上,它将获得自己的模块。如果它是模块化JAR,它将获得一个显式模块those described throughout the State of the Module System - 普通JAR变为automatic modules(注意复数:每个JAR一个自动模块)。

答案 1 :(得分:4)

我是否理解JPMS中始终只有一个未命名的模块?

是的,有一个未命名的模块。未命名的模块与unnamed package的现有概念非常相似。

在使用分层文件系统存储包的Java SE平台的实现中,一种典型的策略是将未命名的包与每个目录相关联;一次只能观察到一个未命名的包,即与"当前工作目录"相关联的包。 "当前工作目录的确切含义"取决于主机系统。

是否意味着在Java9之前开发但未针对Java9更新的应用程序将作为一个未命名的模块加载?

是的,对于那些放在类路径上的jar将被视为一个未命名的模块。具有未命名模块概念的bottom up migration用类似的示例说明了这一点:

  

假设,例如,上面显示的应用程序最初是   为Java SE 8构建,作为一组类似命名的JAR文件   班级路径。如果我们在Java SE 9上按原样运行它,那么类型就在   JAR文件将在未命名的模块中定义。

这里可能出现的实际问题是 哪个类加载器是未命名的模块? The State of Module System about unnamed module对此进行了澄清。

  

事实证明,每个类加载器都有自己独特的未命名模块,   这是由新的 ClassLoader::getUnnamedModule 方法返回的。   如果类加载器加载未在命名模块中定义的类型那么   该类型被认为是在该加载器的未命名模块中,即,   该类型getModule对象的 Class 方法将返回其   loader的未命名模块。该模块通俗地称为“   未命名的模块“然后,只是应用程序的未命名模块   类加载器,它在类路径中加载类型   包未由任​​何已知模块定义。

Java-9中修订的 ClassLoader 表示:

  

Java运行时具有以下内置类加载器:

     
      
  • Bootstrap class loader :虚拟机的内置类加载器......

  •   
  • Platform class loader :...   允许升级/覆盖定义到平台的模块   类加载器,以及升级模块读取定义到类的模块的位置   那么平台类加载器及其祖先以外的加载器   平台类加载器可能必须委托给其他类加载器,   例如,应用程序类加载器。 换句话说,课程在   命名模块定义为除平台类之外的类加载器   平台类加载器可以看到加载器及其祖先。

  •   
  • System class loader 也称为应用程序类加载器,与平台类加载器不同。系统   类加载器通常用于定义应用程序上的类   类路径,模块路径和JDK特定工具。平台类   loader是系统类加载器的父级或祖先   平台类是可见的。

  •