Producing a launcher jar
You never assemble a launcher jar by hand. The Jenesis build tool produces it from one switch in
packaging.properties: it resolves the launcher, copies its classes into the jar, lays out your dependencies
for it, and writes the descriptor and manifest that make java -jar app.jar start the launcher. This chapter
shows that switch, what the build writes, and where the result lands.
Turning it on
The launcher jar is one of the build tool's packaging options. Enable it with
launcher=true in a packaging.properties file in the configuration folder:
# build.jenesis/packaging.properties
launcher=true
java build/jenesis/Project.java
Like every packaging feature, it only runs for a module that declares a main class - the same @jenesis.main
tag (or <mainClass> POM property) the other packaging steps key off. A module without one is skipped, so a
library is left alone and an application needs no launcher-specific configuration.
What the build writes
The build resolves the published launcher artifact and produces the jar in four moves. Everything the launcher needs at run time - the layout described in How it works - is put in place here:
- The launcher's classes go into the jar root. Only its
build/jenesis/launcher/*.classfiles are copied; the launcher's ownmodule-infoand manifest are left out, so at run time those classes are the unnamed module that hosts your application. - Each dependency is exploded into its own subfolder. The resolved jar file name becomes the folder name:
modulepath/org.slf4j%2Fslf4j-api%2F2.0.16.jar/for a modular or automatic dependency,classpath/…/for a plain one, andclasses.jar/for the application's own module. The split follows the same rule as the build'sExecutelauncher and itsbundle.zip: a jar is placed on the module path only when the application is modular and the jar describes a module. Apom.xmlapplication without a module therefore gets everything underclasspath/. application.propertiesis written withmainClass,mainModule(modular applications only), andclasspath- the class-path subfolders, listed in file-name order.- The manifest gets one attribute,
Main-Class: build.jenesis.launcher.Launcher, sojava -jarstarts the launcher.
That is the complete set. The other descriptor keys and manifest attributes the launcher understands - bundled agents, module-access grants, signer reconstruction - are for a jar you assemble yourself; the Reference chapter lists them.
bundle=true) makes the same module-path / class-path
split, but keeps each jar whole under modulepath/ and classpath/ for you to drop
onto a JRE. The launcher jar explodes those same jars into subfolders and adds the launcher, so it needs no
launch script.
Where the jar lands
The jar is named after the module's artifact id - demo.modular.executable.jar for the modular demo - or
application.jar when the build knows no artifact id. It is written into the module's build output, under
the launcher module's bundle step:
target/build/…/launcher/bundle/output/launcher/<name>.jar
It is not collected into the stage tree. A build of your own can locate it as the jar under a launcher/
folder of the build output - build/DemoLauncher.java in the two executable demos does exactly that, then
runs the jar.
The launcher is pinned like any dependency
The build resolves the launcher as a normal dependency, in its own launcher group, kept apart from your
application's dependencies. Until you pin it, it floats to the latest release. Run pin and the build records
the exact version and checksum next to your other pins - in a modular project:
/**
* @jenesis.main sample.Sample
* @jenesis.pin launcher/maven/build.jenesis/build.jenesis.launcher 0.3.1 SHA-256/720f9c17…
*/
module demo.modular.executable {
requires org.slf4j;
exports sample;
}
A pom.xml project carries the same line in its <!--jenesis.pin … --> block, outside
<dependencyManagement>, since the launcher is not an application dependency. Either way the launcher bytes
shaded into your jar are verified on every build, and the produced jar is reproducible:
the same sources yield the same bytes.
pom.xml application) and
demo-06 (a
modular one) each ship a build/DemoLauncher.java that switches the launcher on through a
profile, builds the jar, and runs it: java build/DemoLauncher.java Ada Lovelace. Their pinned
module-info.java and pom.xml show the pin line in both forms.
With the jar produced, the next chapter turns to running it: the start-up flow, what the single loader means for your code, and the pitfalls to watch for.