9

我试图了解 JPMS 是如何工作的。

这里

类路径还没有完全消失。类路径上的所有 JAR(模块化或非模块化)和类都将包含在未命名模块中。与自动模块类似,它导出所有包并读取所有其他模块。但它显然没有名字。因此,命名的应用程序模块不能要求和读取它。未命名的模块反过来可以访问所有其他模块。

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

这里

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

再次unnamed module。模块是单数的。

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

4

2 回答 2

10

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

简而言之

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

更详细

每个ClassLoader都有自己的未命名模块,用于表示从类路径加载的类。这是必要的,因为模块系统要求一切都在一个模块中。

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

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

这与代码(应用程序、框架、库)是否针对 Java 9 无关——它只取决于您放置 JAR 的路径、类路径或模块路径

如果它在类路径上,它会与其他类路径内容一起出现在未命名的模块中。这适用于没有模块描述符的普通 JAR,但也适用于包含模块描述符的模块化 JAR。

如果它在模块路径上,它将获得自己的模块。如果它是一个模块化 JAR,它会得到一个显式模块,正如在整个模块系统状态中所描述的那样——普通的 JAR 会变成自动模块(注意复数:每个 JAR 一个自动模块)。

于 2017-09-17T11:59:25.357 回答
6

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

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

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


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

是的,对于放置在类路径上的那些 jar,将被视为一个未命名的模块。使用未命名模块概念的自下而上迁移通过一个类似的示例说明了这一点:

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


这里可能出现的实际问题 是未命名模块关联的是哪个类加载器? 关于未命名模块的模块系统状态对此进行了澄清。

事实证明,每个类加载器都有自己独特的未命名模块,该模块由新ClassLoader::getUnnamedModule方法返回。 如果类加载器加载了一个未在命名模块中定义的类型,则该类型被认为在该加载器的未命名模块中,即,该类型对象的方法将返回其加载器的未命名模块。通俗地称为“未命名模块”的模块只是应用程序类加载器的未命名模块,当它们位于任何已知模块未定义的包中时,它会从类路径加载类型。getModuleClass

Java-9 中的ClassLoader修订说明:

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

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

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

  • System class loader:也称为应用类加载器,区别于平台类加载器。系统类加载器通常用于在应用程序类路径、模块路径和 JDK 特定工具上定义类。平台类加载器是系统类加载器的父类或祖先,所有平台类对它都是可见的。

于 2017-09-17T11:27:44.447 回答