我想在作为模块的jar中加载和重新加载服务提供者。据我了解,可以通过将模块加载到新的ModuleLayer
中来实现。
按照this answer中的建议和docs中的示例,我已经在运行时成功加载了模块并使用了服务提供商。
var finder = ModuleFinder.of(Path.of("/path/to/module/"));
var bootLayer = ModuleLayer.boot();
var pluginLayer = bootLayer.defineModulesWithOneLoader(
bootLayer.configuration().resolve(finder, ModuleFinder.of(), Set.of("myapp")),
ClassLoader.getSystemClassLoader());
ServiceLoader.load(MyService.class, pluginLayer.findLoader("myapp"))
.findFirst()
.ifPresentOrElse(
__ -> System.out.println("Found provider."),
() -> System.out.println("Couldn't find provider."));
我唯一不确定的是最终应该如何卸载模块并重新加载新版本。链接的答案说,卸载ModuleLayer
时发生了GC。通过一些测试,我已经确认了这一点,尽管这感觉很棘手。显然,即使无法访问该层,我也无法精确控制何时对其进行垃圾收集。
允许快速重新加载模块的最佳方法是什么?