9

When using jlink, a bin/java file is generated. This executable will accept VM options by specifying options on the command line in the usual way (such as -Dsystem.property=value or -Xmx1G).

jlink also provides a --launcher option to create an executable that can be run directly, instead of having to invoke the bin/java executable with a module name.

How do I make the launcher executable pre-configured to use my choice of JVM options?

knaccc
  • 232
  • 2
  • 11

2 Answers2

3

You can use the add-options jlink plugin.

For example, if you want to set Xmx:

jlink --add-options="-Xmx100m" ...

To see a list of jlink plugins, run jlink --list-plugins.

The add-options plugin is currently documented (JDK14) as follows:

Plugin Name: add-options
Option: --add-options=<options>
Description: Prepend the specified <options> string, which may include
whitespace, before any other options when invoking the virtual machine
in the resulting image.

Beware that some of the plugins are, apparently, unstable (including add-options): https://docs.oracle.com/en/java/javase/12/tools/jlink.html

Renato
  • 12,940
  • 3
  • 54
  • 85
1

There are one or two ways of going about this,but mostly I'm going to concentrate on the default java ways.

Actual answer - Use JPackage. JLink is just the image of a runtime. JPackage is your distributable

Support for native packaging formats to give the end user a more natural installation experience. Specifically, the tool will support the following formats:

    Windows: msi, exe
    macOS: pkg, app in a dmg (drag the app into the Applications directory)
    Linux: deb, rpm

The application will be installed in the typical default directory for each platform unless the end-user specifies an alternate directory during the installation process (for example, on Linux the default directory will be /opt).

The ability to specify JDK and application arguments at packaging time that will be used when launching the application

The ability to package applications in ways that integrate into the native platform, for example:

    Setting file associations to allow launching an application when a file with an associated suffix is opened
    Launching from a platform-specific menu group, such as Start menu items on Windows
    Option to specify update rules for installable packages (such as in rpm/deb)


1) - Specify an @Args file

You can make an @args file that you can deploy (bundled) with your jlink app, and reference it when starting the application

java @args -m module/main

2) Use the new environment variable

JDK_JAVA_OPTIONS=--add-opens java.base/java.lang=...... -Xmx1G -Djdk.logging.provider=

https://docs.oracle.com/javase/9/tools/java.htm#JSWOR624

3) Use the JLink/JMod to specify main class in module

https://maven.apache.org/plugins/maven-jmod-plugin/plugin-info.html

      <plugin>
        <artifactId>maven-jmod-plugin</artifactId>
        <version>3.0.0-alpha-1</version>
        <extensions>true</extensions>
        <configuration>
          <module>
          <mainClass>mainClass</mainClass>
        </configuration>
      </plugin>

4) Use JLink to create a custom launcher/Edit JDK_VM_OPTIONS

<plugin>
                        <artifactId>maven-jlink-plugin</artifactId>
                        <version>3.0.0-alpha-2-SNAPSHOT</version>
                        <extensions>true</extensions>
                        <configuration>
                            <noHeaderFiles>true</noHeaderFiles>
                            <noManPages>true</noManPages>
                            <stripDebug>true</stripDebug>
                            <verbose>true</verbose>
                            <compress>2</compress>
                            <launcher>customjrelauncher=module/mainClass</launcher>
                        </configuration>
                        <dependencies>
                            <dependency>
                                <groupId>org.ow2.asm</groupId>
                                <artifactId>asm</artifactId>
                                <version>${maven.asm.version}</version>
                            </dependency>
                        </dependencies>
                    </plugin>

In the generated .sh/.bat there is a variable to specify any custom addon's

You can also specify the main class descriptor in your module-info using moditect if you are using it:

<plugin>
                <groupId>org.moditect</groupId>
                <artifactId>moditect-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <id>add-module-infos</id>
                        <phase>package</phase>
                        <goals>
                            <goal>add-module-info</goal>
                        </goals>
                        <configuration>
                            <overwriteExistingFiles>true</overwriteExistingFiles>
                            <module>
                                <mainClass>mainClassLocation</mainClass>
                            </module>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
Marc Magon
  • 713
  • 7
  • 11
  • Thanks, I appreciate you taking the time to answer. However, jpackage does not allow for cross-compilation, which means every time I produce binaries for Mac/Linux/Win I'd need to have a Mac (because you can't use MacOS in a VM on something other than a Mac) and I'd have to use 2 additional virtual machines (for Linux+Win from inside MacOS). Also, I'd have to generate installers, and I don't want installers, only executables. That's why I'm specifically looking for a way to make the executables generated by jlink to specify VM options. – knaccc Nov 07 '19 at 17:55
  • If you look at solution number 2, You will see the VM Argument | JDK_JAVA_OPTIONS=--add-opens java.base/java.lang=...... -Xmx1G -Djdk.logging.provider=. Please remember to mark as answer – Marc Magon Nov 08 '19 at 18:57
  • 1
    No. 2 is unfortunately not a good answer, because it means someone can't just double click the executable and run it with the developer's preferred JVM options. This is what I meant in the question by "pre-configured", sorry if this wasn't clear. – knaccc Nov 08 '19 at 19:17
  • I promise, please try it - If you set the environment variable in your O.S. - You will get exactly what you are looking for – Marc Magon Nov 10 '19 at 13:37
  • 1
    I'm not disagreeing that setting an environment variable is a way to pass in JVM arguments. I'm saying that it's not a useful answer for the purposes of giving someone an executable they can just double click on, without needing to know what an environment variable is or how to set it. – knaccc Nov 11 '19 at 04:13
  • 1
    I agree with @knaccc this is not an answer at all. The question is very simple: how do you make the java executable ALWAYS run with certain options. This does not answer that. Having to set an environment variable is definitely not a good option for an end user. – Renato Apr 03 '20 at 20:17
  • To ALWAYS make it run, use the Java Environment Variable. It exists for that exact purpose. Thanks for taking the time to try it out. – Marc Magon Apr 04 '20 at 21:27