lade.jpms
Create and run dynamic JPMS module layers from an in-memory classloader
Provides a ModuleFinder for InMemoryClassLoader, allowing dynamic JPMS from in-memory resources.
Uses JPMS API, so JDK >= 9 required.
Examples
The following example, creates ×3 in-memory JPMS JARs, creates a ModuleLayer and executes the application.
Create JARs
An API, Imp and App:
Archive api = archive() .configured( asJpmsModule() .named("api") .exporting(s -> true) .autoRequiring() ) .with(AcmeApi.class) .toObjectModel(); Archive app = archive() .configured( asJpmsModule() .named("app") .autoRequiring() .autoRequiring(fromArchives(api)) .exporting(s -> true) .using(AcmeApi.class) .launching(AcmeApp.class) ) .toObjectModel(); Archive imp = archive() .configured( asJpmsModule() .named("imp") .autoRequiring() .autoRequiring(fromArchives(api)) .providing(AcmeApi.class, AcmeImp.class) ).toObjectModel();
Create InMemoryClassLoader
Remembering to register the URLStreamHandler
Handler.addProtocolHandlerSystemProperty(); InMemoryClassLoader loader = inMemoryClassLoader() .jar(api.toByteArray()) .jar(imp.toByteArray()) .jar(app.toByteArray());
Create ModuleFinder and ModuleLayer
The ModuleLayer has in-memory modules resolved by the finder, and service dependencies are bound
ModuleFinder finder = new InMemoryModuleFinder(loader); ModuleLayer parent = ModuleLayer.boot(); Configuration configuration = parent.configuration().resolveAndBind( ModuleFinder.of(), finder, Set.of("app")); ModuleLayer layer = parent.defineModulesWithOneLoader(configuration, loader);
Execute the App
Launch the application
Class<?> mainClass = layer.findLoader("app").loadClass(AcmeApp.class.getCanonicalName()); Method main = Methods.getMethod(mainClass, "main", String[].class) .orElseThrow(NoSuchMethodError::new); String you = "Dynamic & In-Mem"; String stdout = captureStdout(() -> main.invoke(null, new Object[] {new String[] {you}})); String expectedResponse = "module app: Acme Corp would like to say \"Hello\" to \"" + you + "\" (Terms and conditions apply)\n"; assertThat(stdout, is(equalTo(expectedResponse)));
View full source of associated test.