moditect / layrry

A Runner and API for Layered Java Applications
Apache License 2.0
337 stars 33 forks source link

Run Layrry on a custom runtime image #65

Open sormuras opened 3 years ago

sormuras commented 3 years ago

Idea Outline

Motivation: https://twitter.com/AlmasBaim/status/1336685347795857409

Applications: Game A | Game B | ...
-- Layrry --
Custom Runtime Image: java.base, ..., javafx.base, ..., com.almas.fxgl.all, ..., + natives

Let Layrry run and manage applications on a prepared custom runtime image that provides a set of shared modules as system modules.

aalmiray commented 3 years ago

Adding @AlmasB

For this to work the Layrry API would have to support defining module ids as inputs in its configuration. Right now only Maven coordinates are allowed, for example

[layers.javafx]
    modules = [
        "org.openjfx:javafx-base:jar:{{os.detected.jfxname}}:{{javafx_version}}",
        "org.openjfx:javafx-controls:jar:{{os.detected.jfxname}}:{{javafx_version}}",
        "org.openjfx:javafx-graphics:jar:{{os.detected.jfxname}}:{{javafx_version}}",
        "org.openjfx:javafx-web:jar:{{os.detected.jfxname}}:{{javafx_version}}",
        "org.openjfx:javafx-media:jar:{{os.detected.jfxname}}:{{javafx_version}}"]
[layers.core]
    modules = [
        "org.kordamp.tiles:modular-tiles-model:{{project_version}}",
        "org.kordamp.tiles:modular-tiles-core:{{project_version}}",
        "org.kordamp.tiles:modular-tiles-app:{{project_version}}",
        "org.moditect.layrry:layrry-platform:{{layrry_version}}",
        "eu.hansolo:tilesfx:{{tilesfx_version}}"]
    parents = ["javafx"]
[layers.plugins]
    parents = ["core"]
    directory = "plugins"
[main]
  module = "org.kordamp.tiles.app"
  class = "org.kordamp.tiles.app.Main"

Assuming there was a base jlink image with JavaFX modules then the previous example could be rewritten as

[layers.javafx]
    modules = [
        "javafx.base",
        "javafx.controls",
        "javafx.graphics",
        "javafx.web",
        "javafx.media"]
[layers.core]
    modules = [
        "org.kordamp.tiles:modular-tiles-model:{{project_version}}",
        "org.kordamp.tiles:modular-tiles-core:{{project_version}}",
        "org.kordamp.tiles:modular-tiles-app:{{project_version}}",
        "org.moditect.layrry:layrry-platform:{{layrry_version}}",
        "eu.hansolo:tilesfx:{{tilesfx_version}}"]
    parents = ["javafx"]
[layers.plugins]
    parents = ["core"]
    directory = "plugins"
[main]
  module = "org.kordamp.tiles.app"
  class = "org.kordamp.tiles.app.Main"
aalmiray commented 3 years ago

Probably related to #50

sormuras commented 3 years ago

Why do you need [layers.javafx] and parents = ["javafx"] to be configured and referenced? Or, why are system modules like java.base, java.desktop, etc. not configured?

My understanding of a custom runtime image is that all linked modules become system modules, siblings to java.base so to say. If that understanding is correct, your example could be rewritten as

[layers.core]
    modules = [
        "org.kordamp.tiles:modular-tiles-model:{{project_version}}",
        "org.kordamp.tiles:modular-tiles-core:{{project_version}}",
        "org.kordamp.tiles:modular-tiles-app:{{project_version}}",
        "org.moditect.layrry:layrry-platform:{{layrry_version}}",
        "eu.hansolo:tilesfx:{{tilesfx_version}}"]
[layers.plugins]
    parents = ["core"]
    directory = "plugins"
[main]
  module = "org.kordamp.tiles.app"
  class = "org.kordamp.tiles.app.Main"
aalmiray commented 3 years ago

Right, we'd have to test that theory, won't we? 😏

If all jlinked modules can't be put into separate ModuleLayers then the only benefit I can see for the time being when combining Layrry is related to external modules, so that

aalmiray commented 3 years ago

Alright, so I did some investigation and I found the following:

module app {
    exports app;
    requires javafx.base;
    requires javafx.graphics;
    requires javafx.controls;
    requires javafx.web;
    requires javafx.media;
    requires java.logging;
    requires jdk.jfr;
}

Then ran latest Layrry against modular-tiles with the following configuration

[layers.core]
    modules = [
        "org.kordamp.tiles:modular-tiles-model:{{project_version}}",
        "org.kordamp.tiles:modular-tiles-core:{{project_version}}",
        "org.kordamp.tiles:modular-tiles-app:{{project_version}}",
        "org.moditect.layrry:layrry-platform:{{layrry_version}}",
        "eu.hansolo:tilesfx:{{tilesfx_version}}"]
[layers.plugins]
    parents = ["core"]
    directory = "plugins"
[main]
  module = "org.kordamp.tiles.app"
  class = "org.kordamp.tiles.app.Main"

And ... it works! Which means all modules found in the image can be used by any layer. This means it's possible to build a custom FXGL image and have it launch a layered application.

However, it has to be done by invoking the layrry-launcher JAR from the outside as this artifact is not yet modular, thus

/path/to/jlinked/image/bin/java -jar path/to/layrry-launcher-1.0-SNAPSHOT-all.jar \
  --layers-config staging/layers.toml \
  --properties staging/versions.properties

If Layrry were to be modularized (see #12) then the launcher could be embedded into the image and make it part of the main class, thus resulting in

/path/to/jlinked/image/bin/layrry-fxgl-base \
  --layers-config staging/layers.toml \
  --properties staging/versions.properties

This is great as once we have #37 ready we could launch apps from anywhere, such as

/path/to/jlinked/image/bin/layrry-fxgl-base \
  --layers-config https://server:port/path/to/layers.toml \
  --properties https://server:port/path/to/versions.properties

Or implementing the "capsule"* deployment approach (a capsule contains the layers config file plus all required external JARs, packaged using either flat or default repo format)

/path/to/jlinked/image/bin/layrry-fxgl-base --capsule https://server:port/path/to/app.lar

note: Assuming the capsule launcher is built of course, currently only a wild idea.

AlmasB commented 3 years ago

This is looking good!

On Thu, 10 Dec 2020, 6:12 pm Andres Almiray, notifications@github.com wrote:

Alright, so I did some investigation and I found the following:

  • built a custom jlink image with the following module descriptor (app is just a simple JavaFX app to test it works)

module app { exports app; requires javafx.base; requires javafx.graphics; requires javafx.controls; requires javafx.web; requires javafx.media; requires java.logging; requires jdk.jfr; }

  • javafx.base = required by modular-tiles
  • javafx.graphics = required by modular-tiles
  • javafx.controls = required by modular-tiles
  • javafx.web = required by modular-tiles
  • javafx.media = required by modular-tiles
  • java.logging = required by mustache (layrry-config)
  • jdk.jfr = required by layrry (layrry-core)

Then ran latest Layrry against modular-tiles with the following configuration

[layers.core] modules = [ "org.kordamp.tiles:modular-tiles-model:{{project_version}}", "org.kordamp.tiles:modular-tiles-core:{{project_version}}", "org.kordamp.tiles:modular-tiles-app:{{project_version}}", "org.moditect.layrry:layrry-platform:{{layrry_version}}", "eu.hansolo:tilesfx:{{tilesfx_version}}"] [layers.plugins] parents = ["core"] directory = "plugins" [main] module = "org.kordamp.tiles.app" class = "org.kordamp.tiles.app.Main"

And ... it works! Which means all modules found in the image can be used by any layer. This means it's possible to build a custom FXGL image and have it launch a layered application.

However, it has to be done by invoking the layrry-launcher JAR from the outside as this artifact is not yet modular, thus

/path/to/jlinked/image/bin/java -jar path/to/layrry-launcher-1.0-SNAPSHOT-all.jar \ --layers-config staging/layers.toml \ --properties staging/versions.properties

If Layrry were to be modularized (see #50 https://github.com/moditect/layrry/issues/50) then the launcher could be embedded into the image and make it part of the main class, thus resulting in

/path/to/jlinked/image/bin/layrry-fxgl-base \ --layers-config staging/layers.toml \ --properties staging/versions.properties

This is great as once we have #37 https://github.com/moditect/layrry/issues/37 ready we could launch apps from anywhere, such as

/path/to/jlinked/image/bin/layrry-fxgl-base \ --layers-config https://server:port/path/to/layers.toml \ --properties https://server:port/path/to/versions.properties

Or implementing the "capsule"* deployment approach (a capsule contains the layers config file plus all required external JARs, packaged using either flat or default repo format)

/path/to/jlinked/image/bin/layrry-fxgl-base --capsule https://server:port/path/to/app.lar

note: Assuming the capsule launcher is built of course, currently only a wild idea.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/moditect/layrry/issues/65#issuecomment-742699121, or unsubscribe https://github.com/notifications/unsubscribe-auth/AA3NT5QFAX74X7M4FAD5T5DSUEFPVANCNFSM4UTX2A3Q .