Search code examples
javaexelaunch4jjava-19

Java - Deployment of an exe bundled with JRE using Launch4J


this afternoon I've finally completed my project in Java. So I decided to make it available for windows using launch4j to build the exe file.

Seemed something simple, but actually for me is not. My situation right now is the following:

  1. I've installed only the Java SE Development Kit (JDK) 19
  2. My jar file doesn't run with the double click (I've read it could be because with double click you're opening it with javaw instead of java) but works fine with the CMD using java -jar "jar file path"
  3. If I double click on my exe it shows the CMD windows only for a split second and then disappears without writing anything. If I try to run it through the CMD it tells me that this exe need JRE to run (how's that possible if I have a JDK installed?)
  4. I can't find my JRE inside the JDK: I'm quite sure that JDK should contain JRE, but I can't find it in my installation folder of JDK 19

After describing you in the most detailed way my state, I want now to explicitly declare what I am aiming to:

  1. I would like to bundle my exe with a copy of the needed JRE, in order to make it run on other PC without an explicit installation of JRE
  2. I know this is possible since with Launch4J you can specify the path of the JRE to run your program. It is sufficient to put the JRE and the exe in a folder together and specify the relative path in the config file of launch4J (something like "./jrefolder" since they're in the same folder)
  3. What will happen with the newly correct exe in the other machines? Will it open using the javaw like the jar file in my PC?

Hope someone can give me support, cause this thing is driving my crazy since I've finished my project but still i can't deploy it officially


Solution

  • JDK 19

    I am install it from OpenJDK19U-jdk_x64_windows_hotspot_19.0.2_7.msi.

    Find your app dep JDK modules

    jdeps -cp "lib\*" --module-path "lib\*"  --multi-release 19 --print-module-deps --ignore-missing-deps you-app.jar
    
    • -cp "lib\*" (your project dependency jar files)
    • --module-path "lib\*"
    • --multi-release 19
    • --print-module-deps
    • --ignore-missing-deps
    • you-app.jar (your app jar file)

    OR No dependency jar files:

    jdeps --multi-release 19 --print-module-deps --ignore-missing-deps  you-app.jar
    

    Example Result:

    java.base,java.desktop
    

    Build Smaller JRE

    jlink --add-modules java.base,java.desktop --output jdk-19-mini-jre --strip-debug --no-man-pages --no-header-files --compress=2
    
    • --add-modules java.base,java.desktop (jdeps output result)
    • --output jre (your jre directory name)
    • --strip-debug
    • --no-man-pages
    • --no-header-files
    • --compress=2

    launch4j-3.14-win32

    DemoApp
    ├── DemoApp.jar (your app jar)
    ├── demoapp.xml (Launch4j Config files)
    └── jre (jlink command create JDK 19 jre)
    

    Open Launch4j

    Basic Tab

    • Output file: C:\Users\IEUser\Downloads\DemoSwingApp\Output\DemoApp\demoapp.exe
    • Jar: C:\Users\IEUser\Downloads\DemoSwingApp\DemoApp\DemoApp.jar

    Header Tab

    • Header type: GUI

    JRE Tab

    • Bundled JRE paths: jre
    • Only use private JDK runtimes
    • First 64-bit,then 32 bit

    demoapp.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <launch4jConfig>
      <dontWrapJar>false</dontWrapJar>
      <headerType>gui</headerType>
      <jar>C:\Users\IEUser\Downloads\DemoSwingApp\DemoApp\DemoApp.jar</jar>
      <outfile>C:\Users\IEUser\Downloads\DemoSwingApp\Output\DemoApp\demoapp.exe</outfile>
      <errTitle></errTitle>
      <cmdLine></cmdLine>
      <chdir>.</chdir>
      <priority>normal</priority>
      <downloadUrl>http://java.com/download</downloadUrl>
      <supportUrl></supportUrl>
      <stayAlive>false</stayAlive>
      <restartOnCrash>false</restartOnCrash>
      <manifest></manifest>
      <icon></icon>
      <jre>
        <path>jre</path>
        <bundledJre64Bit>true</bundledJre64Bit>
        <bundledJreAsFallback>true</bundledJreAsFallback>
        <minVersion></minVersion>
        <maxVersion></maxVersion>
        <jdkPreference>jdkOnly</jdkPreference>
        <runtimeBits>64/32</runtimeBits>
      </jre>
    </launch4jConfig>
    

    Click Launch4j Build exe

    Copy jre to Output\DemoApp\jre

    Output Directory

    DemoSwingApp/Output
    └── DemoApp
        ├── demoapp.exe
        └── jre
    

    Now, you can click demoapp.exe

    You need pack DemoApp (include demoapp.exe + jre directory) to a zip.

    Note: My example does not use a third-party jar. Only the App itself is packaged into a jar, and only Swing using the JDK.