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.

Dependency Graph

Module Dependency

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.



Back to top

Version: 0.1.0. Last Published: 2018-10-08.

Earcam Maven Skin.