Plug-in Architectures for Java with Layrry & Java Module System
=>From Gunnar Morling & Andres Almiray (Java Champions) talk
What is JPMS?
JPMS
Java Platfrom Module System (AKA Jigsaw)
Introduced in Java 9
Designed to break down the JVM monolith
Applicable to user space as well
The promise is to give developers better code encapsulation and design foundations
But JPMS encountered some detractors.
Some user statements
"JPMS only allows for one version of a module"
"JPMS doesn't allow to add modules at runtime"
"I have to modularize ALL my dependencies in order to benefit from JPMS"
"It's so hard to map dependency coordinates to module dependencies"
"Help, non-exported packages of different modules collide!"
What no one ever said: "Let's use JPMS layers to tackle (some of) these issues"
Class ModuleLayer
It is like a function which allows you to define which class is used and loaded with your module.
It is like a class-loading toolkit
Using the Layers API
What can ease the use of module layers: Layrry is the answer
Hello, Layrry!
=>An API and Launcher for Modularized Java Applications
Layrry configuration by Java class
Layrry has a ready-Made launcher
which does the work of the previous Java class thanks to a yaml or toml file
layers.yml:
Layrry has a built-in template support
javafx.toml:
versions.properties
You can launch layrry with JBang
How to handle the dependencies? => the repositories
Local repositories with Layrry
=>Artifacts can be organized in a local repository that does not require remote resolution
=>Two layouts currently supported: flat and default
layers.yml:
Flat Repository:
Default repository:
That's not all: you can access remote repositories with Layrry
Layrry can deal with remote Layers
Layer configuration (and properties) files hosted at remote locations.
Mixing remote and local repositories is allowed.
Supports dynamic plugins, plugin directories can only be local.
Now we have Layrry to facilitate our task, let's see how it plugins and plugouts the classes
Plug-in architectures
Layrry can dynamically add (and remove) layers at runtime
pluginAdded:
Conclusion
The Java Module System doesn’t define any means of mapping between modules (e.g. com.acme.crm) and JARs providing such module (e.g. acme-crm-1.0.0.Final.jar) or retrieving modules from remote repositories using unique identifiers (e.g. com.acme:acme-crm:1.0.0.Final). Instead, it’s the responsibility of the user to obtain all required JARs of a modularized application and provide them via --module-path.
Furthermore, the module system doesn’t define any means of module versioning; i.e. it’s the responsibility of the user to obtain all modules in the right version. Using the --module-path option, it’s not possible, though, to assemble an application that uses multiple versions of one and the same module. This may be desirable for transitive dependencies of an application, which might be required in different versions by two separate direct dependencies.
This is where Layrry comes in: utilizing the notion of module layers, it provides a declarative approach as well as an API for assembling modularized applications, organized in module layers. The JARs to be included are described using Maven GAV (group id, artifact id, version) coordinates, solving the issue of retrieving all required JARs in the right version.
Module layers allow to use different versions of one and the same module in different layers of an application (as long as they are not exposed in a conflicting way on module API boundaries).
Module layers and thus Layrry also allow application extensions to be added and removed dynamically at runtime.