Search code examples
javaexecutable-jarjpackage

JPackage for only one application?


I have a java application that at runtime shall spawn another JVM. Yet I want to package my application using jpackage, which works quite well. But at runtime, when my application tries to invoke the next JVM using

File javaHome = new File(System.getProperty("java.home"));
File java = new File(javaHome, "bin/java"); // may need a tweak on Windows
new ProcessBuilder().start(java.getAbsolutePath(), "-jar", ...);

I have to learn that the application was launched using a custom built JVM, and there just is no command such as 'java'. So the error I am getting is that this java.getAbsolutePath() cannot be executed.

Without the java executable, how can my application run another jar in a separate process? Can I reuse the JVM bundled with my application, or do I still have to provide another one?


Solution

  • By default jpackage will pass the following flags when invoking jlink to create the runtime image:

    --strip-native-commands --strip-debug --no-man-pages --no-header-files
    

    It is this --strip-native-commands flag that removes the java launcher from the runtime image.

    You can use the --jlink-options flag when invoking jpackage to override the default commands, and drop the --strip-native-commands flag:

    --jlink-options "--strip-debug --no-man-pages --no-header-files"
    

    That should result in the java command (as well as others) being present in the created runtime image.


    If you want even more control over the custom JVM/runtime image used by jpackage, you could also manually run jlink to create a runtime image, and then pass that image to jpackage using the --runtime-image flag.