什么是自动模块? [英] What is an automatic module?

查看:136
本文介绍了什么是自动模块?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在stackoverflow上多次提到自动模块,但我找不到自动模块的完整,简洁和自给自足的定义。

Automatic modules are mentioned many times on stackoverflow but I couldn't find a complete, succinct and self-sufficient definition of an automatic module.

那么,什么是一个自动模块?它是否导出所有包裹?它打开所有包裹吗?它是否读取了所有其他模块?

So, what is an automatic module? Does it export all packages? Does it open all packages? Does it read all other modules?

推荐答案

我首先回答你的实际问题(什么是自动模块?),但是我还解释了 。很难理解为什么自动模块的行为方式与没有这些信息的情况一样。

I first answer your actual question ("What is an automatic module?"), but I also explain what they are there for. It is hard to understand why automatic modules behave the way they do without that information.

模块系统从模块路径上找到的每个JAR创建一个模块。对于模块化JAR(即那些带有模块描述符的JAR),它们很容易定义模块的属性(名称,要求,导出)。对于普通JAR(没有模块描述符),这种方法不起作用,那么模块系统应该做什么呢?它会自动创建一个模块 - 自动模块,可以这么说 - 并对三个属性进行最安全的猜测。

The module system creates a module from every JAR it finds on the module path. For modular JARs (i.e. those with module descriptors) that is straightforward as they define the module's properties (name, requires, exports). For plain JARs (no module descriptor) this approach doesn't work, so what should the module system do instead? It automatically creates a module - an automatic module, so to speak - and takes the most safe guesses for the three properties.

派生名称分为两步:


  • 如果JAR定义自动模块-Name 其清单中的标题,它定义模块的名称

  • 否则,JAR文件名用于确定名称

  • if the JAR defines the Automatic-Module-Name header in its manifest, it defines the module's name
  • otherwise, the JAR file name is used to determine the name

第二种方法本质上是不稳定的,因此不应发布依赖于这种自动模块的模块。 Maven对此发出警告。

The second approach is intrinsically unstable, so no modules with a dependency on such an automatic module should be published. Maven warns about that.

由于普通JAR表示没有require子句,因此模块系统允许自动模块读取所有其他模块,使其成为可读性图(又名模块图)。与显式模块不同,自动模块也读取未命名的模块,该模块包含从类路径加载的所有内容。这个看似微不足道的细节变得非常重要(见下文)。

Since a plain JAR expresses no requires clauses, the module system lets automatic modules read all other modules that make it into the readability graph (aka module graph). Unlike explicit modules, automatic ones also read the unnamed module, which contains everything that was loaded from the class path. This seemingly minor detail turns out to be very important (see below).

自动模块有一些进一步的可读性怪癖,但是:

Automatic modules have some further readability quirks, though:


  • 第一个自动模块解决后,所有其他模块也一样。这意味着一旦模块路径上的单个普通JAR被另一个模块引用,所有普通JAR都将作为自动模块加载。

  • 自动模块暗示可读性,这意味着读取其中一个模块的模块会读取所有这些模块。

  • As soon as the first automatic module is resolved, so are all others. That means once a single plain JAR on the module path is referenced by another module, all plain JARs are loaded as automatic modules.
  • Automatic modules imply readability on all other automatic modules, which means a module reading one of them, reads all of them.

这可能会产生令人遗憾的影响,即依赖于几个普通JAR的显式模块(即非自动模块)只需要一个其中(只要其他人也在模块路径上结束)。

Taken together this can have the unfortunate effect that an explicit module (i.e. a non-automatic one) that depends on several plain JARs can get away with only requiring one of them (as long as the others end up on the module path as well).

由于JAR不包含哪些包被视为公共API而哪些包不是公共API的信息,因此模块系统会导出所有包并打开它们以进行深度反射。

Since the JAR contains no information which packages are considered public APIs and which aren't, the module system exports all packages and also opens them for deep reflection.

模块系统还扫描 META-INF / services 并自动生成m模块提供其中指定的服务。假设允许自动模块使用所有服务。

The module system also scans META-INF/services and makes the automatic module provide the services named therein. An automatic module is assumed allowed to use all services.

最后, Main-Class 清单条目被处理为好吧,所以定义一个的普通JAR可以像自动模块一样启动,其中主类使用 jar 工具设置(即 java - -module-path my-app.jar --module my.app )。

Finally, the Main-Class manifest entry is processed as well, so a plain JAR that defines one can be launched just like an automatic module where the main class was set with the jar tool (i.e. java --module-path my-app.jar --module my.app).

创建自动模块后,它将被视为任何其他模块。这明确包括模块系统将其检查为任何其他模块,例如对于拆分包。

Once the automatic module was created, it is treated as any other module. This explicitly includes that the module system checks it a any other module, for example for split packages.

引入模块的原因之一是使编译和启动应用程序更可靠,并尽快发现类路径可能出现的错误。其中一个关键方面是需要子句。

One of the reasons for introducing modules was to make compiling and launching applications more reliable and find errors sooner that was possible with the class path. A critical aspect of that are requires clauses.

为了保证它们的可靠性,模块声明无法实现要求除命名模块之外的任何东西,它排除从类路径加载的所有内容。如果故事在这里结束,模块化JAR只能依赖于其他模块化JAR,这会迫使生态系统自下而上进行模块化。

To keep them reliable, there is no way for a module declaration to require anything other than a named module, which excludes everything loaded from the class path. If the story ended here, a modular JAR could only depend on other modular JARs, which would force the ecosystem to modularize from the bottom up.

这是不可接受的,但是,因此,引入自动模块作为模块化JAR依赖于非模块化JAR的手段,您需要做的就是将普通JAR放在模块路径上,并通过模块系统给出的名称来要求它。

That is unacceptable, though, so automatic modules were introduced as a means for modular JARs to depend on non-modular ones and all you need to do for that is place the plain JAR on the module path and require it by the name the module system gives it.

有趣的是,因为自动模块读取未命名的模块,所以可行(我通常建议这样做)将其依赖关系保留在类路径上。这样,自动模块充当从模块到类路径的桥梁。

The interesting bit is that because automatic modules read the unnamed module, it is feasible (and I generally recommend doing that) to leave its dependencies on the class path. This way automatic modules act as a bridge from the module to the class path.

您的模块可以位于一侧,需要它们作为自动模块的直接依赖关系,以及间接依赖关系可以留在另一边。
每当你的一个依赖项变成一个显式模块时,它就会在模块化的一侧留下桥接器,并将其直接依赖关系作为自动模块绘制到桥上。

Your modules can sit on one side, require their direct dependencies as automatic modules, and indirect dependencies can remain on the other side. Every time one of your dependencies turns into an explicit module, it leaves the bridge on the modular side and draws its direct dependencies as automatic modules onto the bridge.

这篇关于什么是自动模块?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆