更新:我在这里回答了我自己的问题:
Scanning classpath/modulepath in runtime in Java 9
-
[旧问题 - 已废弃:]
在Java 9模块系统中,您可以使用
查找系统模块Set<ModuleReference> ms = ModuleFinder.ofSystem().findAll();
然后可以使用这些ModuleReference
对象列出每个模块的内容:
for (ModuleReference m : ms) {
System.out.println(m.descriptor().name());
System.out.println(" " + m.descriptor().toNameAndVersion());
System.out.println(" " + m.descriptor().packages());
System.out.println(" " + m.descriptor().exports());
Optional<URI> location = m.location();
if (location.isPresent()) {
System.out.println(" " + location.get()); // e.g. "jrt:/java.base"
}
m.open().list().forEach(s -> System.out.println(" " + s));
}
要获取当前类的模块,可以使用
Module m = getClass().getModule();
但我似乎无法从此ModuleReference
获得Module
(因此我无法列出模块的内容,而不是软件包)和非{ -Module
未列出系统ModuleFinder
。
两个问题:
java.class.path
系统属性吗? (类型AppClassLoader#ucp
的{{1}}字段不可见,并且在JRE 9中被锁定,因此您无法通过内省获得它。)答案 0 :(得分:4)
这个怎么样:
Set<String> systemModuleNames = ModuleFinder
.ofSystem()
.findAll()
.stream()
.map(moduleRef -> moduleRef.descriptor().name())
.collect(Collectors.toSet());
List<Module> nonSystemModules = ModuleLayer
.boot()
.modules()
.stream()
.filter(m -> !systemModuleNames.contains(m.getName()))
.collect(Collectors.toList());
System.out.println(nonSystemModules);
现在,当您拥有nonSystemModules
时,您可以使用此列表执行任何操作(例如,获取每个模块中的资源)。