我使用 Java 17,并且尝试加载所有 Java SE 模块(不是 JDK)。
我尝试的代码:
AtomicInteger y = new AtomicInteger();
ModuleLayer.boot().modules().stream()
.map(Module::getName)
.sorted()
.filter(x -> x.startsWith("ja") && !x.equals("java.smartcardio"))
.forEach(x -> System.out.println("#" + y.incrementAndGet() + " | " + x));
过滤器内的谓词帮助我仅保留 Java SE 模块(其中 java.se
属于我们在这里看到的:https://docs.oracle.com/en/java/javase/17/docs/api/index.html )。但即使我删除它们,模块也不会返回。
我在文件系统中看到了 java.se
模块(在 lib/src.zip/...
和 legal/java.se
中>)。它甚至存在于我的 IDE (Intellij) 的ExternalLibraries 中:
代码的输出:
最佳答案
我假设您将代码作为非模块化(类路径)应用程序的一部分运行,否则模块的 requires
指令将控制存在哪些模块。
此类应用程序的政策已随 Java 11 发生变化。在以前的版本中,java.se
模块被用作非模块化应用程序的根模块(如果存在)。
java.lang.module
documentation of Java 10 :
The set of root modules at compile-time is usually the set of modules being compiled. At run-time, the set of root modules is usually the application module specified to the 'java' launcher. When compiling code in the unnamed module, or at run-time when the main application class is loaded from the class path, then the default set of root modules is implementation specific (In the JDK implementation it is the module "java.se", if observable, and every observable module that exports an API).
java.lang.module
documentation of Java 11 :
The set of root modules at compile-time is usually the set of modules being compiled. At run-time, the set of root modules is usually the application module specified to the 'java' launcher. When compiling code in the unnamed module, or at run-time when the main application class is loaded from the class path, then the default set of root modules is implementation specific. In the JDK the default set of root modules contains every module that is observable on the upgrade module path or among the system modules, and that exports at least one package without qualification.
(强调是我在引文中添加的)
这项新政策排除了 java.se
本身,因为它不“导出至少一个包”。
与 JDK-8205169 比较:
This [old] policy is problematic when creating a run-time image that contains
java.se
and also contains a java.* module that is not in Java SE but exports an API, e.g.java.json
. When compiling or running non-modular code, a developer needs to specify--add-modules
to ensure that the non-Java SE java.* modules in the run-time image are resolved.A second point is that the original policy was created to ensure that the
java.corba
and Java EE modules (that existed in Java SE 9 and 10) were not resolved by default. These modules are proposed to be dropped from Java SE 11 so this aspect of the policy is no longer relevant.
Change the policy so that the default set of root modules is simply all observable modules on the upgrade module path or among the system modules that exports at least one package, without qualification.
关于java - 为什么java.se模块没有加载?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77360378/