automatically downloading and enabling a jigsaw module
Alan Bateman
Alan.Bateman at oracle.com
Fri Jul 29 09:12:35 UTC 2016
On 29/07/2016 09:22, Jochen Theodorou wrote:
> :
>
> To start off I guess there would be a small gateway program, that
> handles the command line arguments and issues the download of the
> modules. What comes after that? Is it as easy as spawning a new class
> loader and load the modules in that loader as well as the reminder of
> the program? Is there an alternative way of doing this? How do I add
> the modules to the current layer? Or if a different layer... Will my
> program then still have access to the services?
Assuming you've downloaded the module that you will hand off too, plus
all the dependences, then the code fragment below might get you started.
The code fragment assumes the packaged modules are downloaded to some
directory on the file system. It invokes the
Configuration.resolveRequiresAndUses to resolve a module name "rabbit".
This will create a Configuration that is essentially a module graph that
includes "rabbit" and its dependences, the "AddUses" variant deals with
services as you mentioned those. It then instantiates that graph of
modules using Layer.defineModulesWithOneLoader which will create one
class loader for all the modules in the module layer. The rest isn't
anything module specific, it's just using core reflection to invoke
rabbit's entry point, I assume this is a hand off from your mini launcher.
Alex covers a lot of the background in the Under the Hood talk,
specifically part 3 on "Loaders and Layers".
-Alan
Path dir = // download directory
ModuleFinder finder = ModuleFinder.of(dir);
Layer bootLayer = Layer.boot();
Configuration cf = bootLayer.configuration()
.resolveRequiresAndUses(ModuleFinder.of(), finder,
Set.of("rabbit"));
System.out.println("Resolved");
cf.modules().stream()
.map(ResolvedModule::name)
.sorted()
.forEach(System.out::println);
ClassLoader scl = ClassLoader.getSystemClassLoader();
Layer layer = bootLayer.defineModulesWithOneLoader(cf, scl);
ClassLoader loader = layer.findLoader("rabbit");
Class<?> c = loader.loadClass("rabbit.Main");
Method mainMethod = c.getMethod("main", String[].class);
ClassLoader tccl = Thread.currentThread().getContextClassLoader();
try {
Thread.currentThread().setContextClassLoader(loader);
mainMethod.invoke(null, (Object)new String[0]);
} finally {
Thread.currentThread().setContextClassLoader(tccl);
}
More information about the jigsaw-dev
mailing list