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