moditect / layrry

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

Plug-ins should be single archive instead of directory #39

Closed gunnarmorling closed 3 years ago

gunnarmorling commented 3 years ago

When providing plug-ins as archives (zip, tar.gz), we'd avoid any issues around async file system events when copying something into a plug-ins folder.

gunnarmorling commented 3 years ago

@aalmiray, so I think we probably should get this done before the first release. I think this is causing the test instabilities: the FS watch event for the plug-in dir itself is fired while the contents still are copied. This would be avoided by copying a single file which extract ourselves because then the order of events would be deterministic:

aalmiray commented 3 years ago

hmm in which case we may need to support both .zip and .tar.gz. Given that .jar extends .zip we might as well cover it, isn't it?

gunnarmorling commented 3 years ago

Yes, ultimately, both zip and tar.gz should be supported, but for Alpha1 one would be good enough IMHO. As you say, zip support should come for free with the JDK, I'm not sure about tar.gz.

aalmiray commented 3 years ago

Well, .tar.gz is what we currently use for the vert.x and javafx examples, so ... 😏

gunnarmorling commented 3 years ago

Ah, good point, so the dependency plug-in can do it, and so it should be doable for us as well, right?

puce77 commented 3 years ago

I think Layrry should have it's own packaging type (similar to war, ear etc.).

Parents can then be simple dependecies to other Layrry packing artifacts and modules are regular JAR module dependencies which get added to the zip (local module path), eliminating the need to curate the Layrry configuration file by hand.

If the Layrry configuration file is still needed, the layer part could be generated by the plugin.

aalmiray commented 3 years ago

A custom Layrry packaging is something we've discussed before but in the context of a particular deployment option, not necessarily for organizing the build.

While the idea of reusing the POM information and structure (maven module layout) seems like a good idea to begin with, there are cases where the information found in POM files does not map to Layrry layers. For example, take the modular-tiles layers file (found in the Layrry readme) where there's a javafx base layer. There may be more than one POM file with JavaFX JPMS modules as dependencies, how would those modules be organized in layers that depend on a common javafx layer? Additional information in the POM needs t be provided, likely using a Layrry plugin.

OTOH the custom packaging option enables the following scenario given local artifact support (see https://github.com/moditect/layrry/pull/58): an executable JAR containing the Layrry launcher, the layers config file, all required dependencies: Such that

app-1.0.jar
  |- /META-INF/
  |- /META-INF/layrry/  
  |- /META-INF/layrry/layers.yml
  |- /META-INF/layrry/libs
  |- /META-INF/layrry/libs/app-1.0.jar
  |- /META-INF/layrry/libs/dep-1.0.jar
  |- <Layrry Launcher classes>

The Main-Class of this archive extracts the contents of /META-INF/layrry into a temporary directory and process to assemble layer using the configuration file, which points to the local repository. The containing JAR can be made executable so that you can double click on it to launch the application. Of course, an external Java runtime is still required. The custom Layrry launcher could check for a required Java version (this requires the launcher to be compiled with -release11) and stop the launch if the requirement is not met. An archive like this could keep .jaras suffix or use.lar`.

one final note, the layers config file is required by the launcher, not the build itself. in your suggested approach one would need to generate a custom Layrry launcher (generated source code) using the Layrry API to configure layers. An external configuration file is better in this case.