我似乎无法找到关于是否仍然可以在运行时扫描所有可用类(用于接口,注释等)的任何信息,就像Spring,Reflections和许多其他框架和库当前所做的那样,面对面Jigsaw的相关变化与类的加载方式有关。
修改 : 这个问题是关于扫描寻找类的真实物理文件路径。 The other question是关于动态加载类和资源。它有关但非常不重复。
更新 :Jetty项目为此标准化API提供了JEP proposal。如果你有办法帮助实现这个目标,请做。否则,等等和希望。
更新2 :找到了this相关的发声帖子。引用后代的代码片段:
如果您真的只是想了解模块的内容 启动层(启动时解析的模块)然后你就可以了 像这样的东西:
ModuleLayer.boot().configuration().modules().stream()
.map(ResolvedModule::reference)
.forEach(mref -> {
System.out.println(mref.descriptor().name());
try (ModuleReader reader = mref.open()) {
reader.list().forEach(System.out::println);
} catch (IOException ioe) {
throw new UncheckedIOException(ioe);
}
});
答案 0 :(得分:18)
以下代码在Java 9+(Jigsaw)中实现了模块路径扫描。它会在callstack上找到所有类,然后为每个类引用调用classRef.getModule().getLayer().getConfiguration().modules()
,它会返回一个List<ResolvedModule>
,而不仅仅是List<Module>
。 (ResolvedModule
使您可以访问模块资源,而Module
则不会。)给定每个模块的ResolvedModule
引用,您可以调用.reference()
方法来获取{ {1}}用于模块。 ModuleReference
为您提供ModuleReference#open()
,您可以使用ModuleReader
列出模块中的资源,也可以使用ModuleReader#list()
或Optional<InputStream> ModuleReader#open(resourcePath)
打开资源。然后,在完成模块后关闭Optional<ByteBuffer> ModuleReader#read(resourcePath)
。这在我见过的任何地方都没有记录。要弄清楚这一切是非常困难的。但这是代码,希望其他人能从中受益。
请注意,即使在JDK9 +中,您仍然可以使用传统的类路径元素以及模块路径元素,因此对于完整的模块路径+类路径扫描,您应该使用适当的类路径扫描解决方案,例如ClassGraph,它使用以下机制支持模块扫描(免责声明,我是作者)。
ModuleReader
答案 1 :(得分:2)
这里的实际问题是找到类路径上所有jar和文件夹的路径。一旦你拥有它们,你就可以扫描。
我所做的是以下内容:
requires
个模块MANIFEST.MF
MANIFEST.MF
路径
我对当前模块执行相同的操作,以获取当前代码的类路径。
这样我收集当前工作模块的类路径及其所有必需的模块(1步之外)。这对我有用 - 我的Java8扫描仪仍然可以完成这项工作。此方法不需要任何其他VM标志等。
我可以扩展这种方法以轻松获取所有所需模块(不仅仅是第一级),但就目前而言,我并不需要。