1
\$\begingroup\$

Edit: Clarification:

I want to create a named module during runtime and put dynamically loaded classes into the created module.

I am attempting to build a framework that allows for code generation that is compatible with Java 9's module system. I require the ability to load some generated byte code into a "virtual" module.

From what I can tell after looking though the Java code there are no exported and public methods that allow me to do anything like this, but I am sure I am missing something.

For an example, let's say this class is generated for the module "handler".

package handler;

public class ModHandler{
    public static String fireEvent(){
        return "This is a string from the generated module!";
    }
}

How do I make the "handler" module and load the bytecode into it? How would you add exports and requires into the module? I do not want to write anything to the disk to implement this.

\$\endgroup\$
1
\$\begingroup\$

You have to create a ModuleLayer from a Configuration. This requires a Set of Paths to pass to a ModuleFinder instance that can be created with ModuleFinder.of.

This example lists the jars in plugins and loads the modules.

// List all jar files in ./plugins
File[] pluginFiles = new File("plugins").listFiles((f,n)->n.endsWith(".jar"));
// Convert to Paths
Arrays.stream(pluginFiles).map(File::toPath).collect(Collectors.toSet());
// Create a module finder from those jars
ModuleFinder finder = ModuleFinder.of(Set.of(pluginFiles));
// Get the boot config
Configuration parentConfig = ModuleLayer.boot().configuration();
// Create a new configuration
Configuration configuration = parentConfig.resolve(
    finder,
    ModuleFinder.of(),
    // This gets the names of all the modules and tells the Config to load them
    finder.findAll().stream().map(mr->mr.descriptor().name()).collect(Collectors.toList())
);
// Create the ModuleLayer, you can now interact with the modules
ModuleLayer layer = ModuleLayer.boot().defineModulesWithOneLoader(configuration, ClassLoader.getSystemClassLoader());

This was so much harder to find than one might think, with this you can create a custom ModuleFinder and do weird and wonderful things.

\$\endgroup\$
  • \$\begingroup\$ Glad to hear that you found a solution! Don't forget to mark it as accepted - it helps others who may run into the same or similar problems. \$\endgroup\$ – Pikalek May 30 '18 at 17:48
  • 1
    \$\begingroup\$ I did not even try to because I am used to a 24 hour delay before I can do that. :-P \$\endgroup\$ – gudenau May 30 '18 at 22:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.