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);
        }

Reply via email to