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

How many unnamed modules are created in Java 9?

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

来自here

The classpath is not completely gone yet. All JARs (modular or not) and classes on the classpath will be contained in the Unnamed Module. Similar to automatic modules, it exports all packages and reads all other modules. But it does not have a name, obviously. For that reason, it cannot be required and read by named application modules. The unnamed module in turn can access all other modules.

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

来自here

For compatibility, all code on the classpath is packaged up as a special unnamed module, with no hidden packages and full access to the whole JDK.

再次unnamed module。模块是单数。

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

我理解的对吗,JPMS里总是只有一个未命名的模块?

是的,有一个未命名的模块。未命名模块与 unnamed package.

的现有概念非常相似

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


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

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

Suppose, e.g., that the application shown above had originally been built for Java SE 8, as a set of similarly-named JAR files placed on the class path. If we run it as-is on Java SE 9 then the types in the JAR files will be defined in the unnamed module.


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

Every class loader, it turns out, has its own unique unnamed module, which is returned by the new ClassLoader::getUnnamedModule method. If a class loader loads a type that is not defined in a named module then that type is considered to be in that loader’s unnamed module, i.e., the getModule method of the type’s Class object will return its loader’s unnamed module. The module colloquially referred to as “the unnamed module” is, then, simply the unnamed module of the application class loader, which loads types from the classpath when they are in packages not defined by any known module.

ClassLoader 在 Java-9 中修订后指出:

The Java run-time has the following built-in class loaders:

  • Bootstrap class loader: The virtual machine's built-in class loader...

  • Platform class loader: ... To allow for upgrading/overriding of modules defined to the platform class loader, and where upgraded modules read modules defined to class loaders other than the platform class loader and its ancestors, then the platform class loader may have to delegate to other class loaders, the application class loader for example. In other words, classes in named modules defined to class loaders other than the platform class loader and its ancestors may be visible to the platform class loader.

  • System class loader: It is also known as application class loader and is distinct from the platform class loader. The system class loader is typically used to define classes on the application class path, module path, and JDK-specific tools. The platform class loader is a parent or an ancestor of the system class loader that all platform classes are visible to it.

Do I understand right that there is always only one unnamed module in JPMS?

简而言之

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

更详细

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

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

Does it mean that applications that were developed before Java9 and not updated for Java9 will be loaded as one unnamed module?

这与代码(应用程序、框架、库)是否以 Java9 为目标无关 - 它仅取决于您放置 JAR 的路径,在 class 路径或 module path.

如果它在 class 路径上,它将与其他 class 路径内容一起在未命名模块中结束。对于没有模块描述符的普通 JAR 和包含模块描述符的模块化 JAR 都是如此。

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