为什么模块路径上的模块必须使用--Add-Models?

Why is --add-modules necessary for modules which are on the module path?(为什么模块路径上的模块必须使用--Add-Models?)

本文介绍了为什么模块路径上的模块必须使用--Add-Models?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一个例子:自从从JDK中删除了JavaFX,现在JavaFX SDK以一组模块化JAR的形式分发。要编译一个JavaFX应用程序,当然必须将它们放在模块路径上:

javac -p /path/to/jars/ App.java
然而,这还不够。尝试编译将导致许多类似的错误
sample/App.java:3: error: package javafx.application is not visible
import javafx.application.Application;
             ^
  (package javafx.application is declared in module javafx.graphics, which is not in the module graph)

要解决此问题,我们可以使用--Add-MODULES:

添加
javac -p /path/to/jars/ --add-modules javafx.graphics App.java

如果我们向项目中添加了一个-info.Java模块(仅包含module ui {}),则不会有任何问题。

为什么模块路径上的模块对命名模块可见,但对未命名模块不可见?

推荐答案

+1回答一个非常好的问题。这里的问题是,当您编译命名模块和未命名模块时,它们的默认根模块集的计算方式非常不同。

这是JEP 261中的一句话,它解释了这种差异:

当编译器编译未命名模块中的代码或Java 调用Launcher并加载应用程序的主类 从类路径到应用程序类的未命名模块 加载器,则未命名模块的缺省根模块集为 计算方法如下

如果存在,则java.se模块是根。如果它不存在,那么 升级模块路径上或系统之间的每个Java.*模块 不加限定地导出至少一个包的模块是 超级用户。

升级模块路径上或系统间的每个非Java.*模块 不加限定地导出至少一个包的模块是 也是根。

这看起来可能有点复杂,所以我用粗体显示了文本中最重要的部分。另外,让我们一步一步来:

  • 您没有module-info.java,所以您的模块是一个未命名的模块。
  • java.se存在,因此它已进入根集。
  • 您的升级模块路径为空(因为您只指定了-p,而没有指定--upgrade-module-path)。
  • 至少导出一个包的系统模块也进入集合。

因此,根集仅为java.se和一些系统模块。没有JavaFX模块进入集合!

现在,当您使用module-info.java编译时会发生什么?使用不同的规则计算根集:

否则,默认的根模块集取决于阶段:

在编译时,通常是正在编译的模块集

因为根模块是需要JavaFX模块的模块,所以它们进入了模块图。

那么,如何解决这个问题呢?您可以通过将JavaFX模块放在升级模块路径上来完成此操作:

javac --upgrade-module-path /path/to/jars/ App.java

或使用--add-modules

javac -p /path/to/jars/ --add-modules ...

或使用普通老类路径:

javac -cp /path/to/jars/ App.java

这三个选项都应该有效。让我知道第一个选项是否真的有效,因为我没有尝试它。

这篇关于为什么模块路径上的模块必须使用--Add-Models?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本文标题为:为什么模块路径上的模块必须使用--Add-Models?

基础教程推荐