Today I want to share our project and show how it can be used with JavaFX.
Usually, a JavaFX application is started with all modules loaded int the boot layer. For example:
Boot layer: - myproject.app - javafx.base - javafx.controls - javafx.graphics
However, JPMS allows you to create an unlimited number of child layers and build a graph from them, which in turn lets us separate application management from the application itself.
For exactly this purpose, Weaverbird was created - it runs in the boot layer and is responsible for creating and managing the layers (at the same time its capabilities go much further). With this framework we can organize out application in the following way:
Boot layer: - myproject.boot - weaverbird.core Child layer: - myproject.app - javafx.base - javafx.controls - javafx.grapchis
And now lets' take a look at some code. In myproject.boot we create a component config (Java or XML) and start it:
var config = ComponentConfig.builder()
.title("MyApp").name(appName).version(appVer)
.repositories(r -> r.name(...).url(...))
.modules(
m -> m.groupId("my.company")
.artifactId("myproject.app")
.version(appVer)
.active(true),
m -> m.groupdId("org.openjfx")
.artifactId("javafx-base)
.version(fxVer)
.classifier("linux"),
// ... other JavaFX modules
)
.build();
var framework = FrameworkFactory.create(settings, path);
var componentManager = framework.getComponentManager();
componentManager.installComponent(config, null);
componentManager.startComponent(appName, appVer);
The only thing left is to actually launch the JavaFX app in the child layer. So, in myproject.app we have
public class ModuleActivatorProvider implements ModuleActivator {
@Override
public void activate(ModuleContext context) {
var thread = new Tread(() -> {
Application.launch(MyApp.class);
context.getFramework().shutdown();
});
thread.start();
}
@Override
public void deactivate(ModuleContext context) { }
} The same mechanism is used for plugins. That's it. Sorry for the long post :)