【问题标题】:How many unnamed modules are created in Java 9?Java 9 中创建了多少个未命名的模块?
【发布时间】:2018-02-26 01:03:33
【问题描述】:

我正在尝试了解 JPMS 的工作原理。

来自here

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

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

来自here

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

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

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

【问题讨论】:

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


    【解决方案1】:

    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 方法返回。 如果类加载器加载了一个未在命名模块中定义的类型,那么 该类型被认为在该加载程序的未命名模块中,即 类型的 Class 对象的 getModule 方法将返回其 loader 的未命名模块。该模块通俗地称为“ 未命名的模块”就是应用程序的未命名模块 类加载器,当它们在时从类路径加载类型 未由任何已知模块定义的包。

    Java-9 中修订的 ClassLoader 声明:

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

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

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

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

    【讨论】:

      【解决方案2】:

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

      简而言之

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

      更详细的

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

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

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

      这与代码(应用程序、框架、库)是否针对 Java 9 无关 - 它仅取决于您将 JAR 放置在哪个路径、类路径或 module path

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-14
        • 1970-01-01
        • 1970-01-01
        • 2022-12-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多