42

I am new to programming in Java but am generally familiar with how everything works. I would like to be able to put both a jar file and a jre into a windows executable(exe) so that when I distribute it, the client needn't have a JRE installed. What program should I use?

I have launch4j and it seems to do exactly what I want but when I try to run the app, I get "This application was configured to use a bundled Java Runtime Environment but the runtime is missing or corrupted."

I want my app to just be a runnable exe, not an installer. At the very least, can anyone show me how to correctly bundle a JRE with launch4j?

MagicGuy52
  • 571
  • 1
  • 6
  • 11
  • What doesn't work when you use launch4j? – Code-Apprentice Dec 21 '12 at 20:10
  • I get error message: "This application was configured to use a bundled Java Runtime Environment but the runtime is missing or corrupted". – MagicGuy52 Dec 21 '12 at 20:19
  • Please edit your question to describe exactly what you tried with L4J and what happens. – Code-Apprentice Dec 21 '12 at 20:21
  • @DaveJarvis did you check [launch4j](http://launch4j.sourceforge.net/)? According to its websit it "is a cross-platform tool for wrapping Java applications [...] in lightweight Windows native executables [which] can be configured to [....] use a bundled [jre]" Looks like it meets OP's needs – Miserable Variable Dec 21 '12 at 20:35
  • 1
    It does but it is an installer. I do not see a way to create an exe that's not an installer. – MagicGuy52 Dec 21 '12 at 20:57
  • You can't use launch4j to embed a JRE inside your exe (see also http://stackoverflow.com/a/41263145). Launch4j only allows you to bundle a JRE together with your exe, so alongside it. – THelper Dec 21 '16 at 13:02
  • i have created executable file for my java software using launch4j but the file can not open in other machine. so that is the problem with launch4j. so for that, don't use launch4j if you want to supply that software to client. – Pranjal Dec 02 '16 at 06:31

9 Answers9

43

The only way I could bundle a JRE was to use Launch4J and Inno Setup Compiler.

First, create a jre6 folder (for example) in the same directory as your output file (.exe).

Then copy the JRE from your system into your jre6 folder.

Then you open Launch4J and set the Bundled JRE path - just type in jre6. Then click the Build button (obviously, after you've entered all the other parameters - but the only value you need to enter on the JRE tab itself is the Bundled JRE path value.)

I would have expected that to work, but if you then move the .exe to a new location (so it is no longer co-located with your jre6 folder) you get the This application was configured to use a bundled Java Runtime Environment but the runtime is missing or corrupted error when you try to run the application...

I've been playing around with this all day and there was no way I could get Launch4J to include the JRE in the .exe file. Really poor in my opinion, as their documentation does not seem to allude to this issue at all.

So what I did to solve was to use Inno Setup Compiler (ISC). This app is used to wrap your .exe as a Windows Installer file. So I added a setting to the ISC script that copies the JRE into the installer package. The line I added to the script (in the [Files] section) was:

Source: "M:\Netbeans\MyApp\jre6\*"; DestDir: "{app}\jre6\"; Flags: recursesubdirs createallsubdirs

...a bit of workaround, but it did the trick.

Repeat all the above steps, and you should be sorted.

ban-geoengineering
  • 18,324
  • 27
  • 171
  • 253
  • Is there any way to do all this with maven? – Marcus Jan 27 '17 at 11:10
  • Sorry, but I don't know Maven. You may be better off posting a new SO question. – ban-geoengineering Jan 27 '17 at 12:22
  • 1
    I don't understand your workaround. My NetBeans project folder has no jre6. There is a jre6 in C:\Program Files\Java. Also, if NetBeans project is used to create a Native exe it (NetBeans) uses Inno setup internally to create an installer, and if that installer is executed it puts a jre folder in User AppData\Local, e.g. C:\Users\Ed Sowell\AppData\Local\TryNativePackaging\runtime\jre. – Ed S Mar 14 '17 at 13:48
  • @EdS You will need to create the jre6 folder and copy your jre files into there (I think, likely from `C:\Program Files\Java`). My answer is from four years ago, so NetBeans may have changed a lot from then and I haven't created a desktop application since then. I'll help more if I can, but you may need to post a new question on SO if you're still stuck. – ban-geoengineering Mar 14 '17 at 15:11
  • Sorry to be so dense, but still don't understand how this all works. What concerns me now is the Source statement: M:\Netbeans\MyApp\jre6\*"; DestDir: "{app}\jre6\"; Flags: recursesubdirs createallsubdirs – Ed S Mar 18 '17 at 17:46
  • No worries - I've been there plenty of times! :-) So "M:\Netbeans\MyApp\" is your particular Netbeans project directory - obviously, you will need to change this. Then, within that directory, create a "jre6" folder which you then need to dump all your JRE files into. The "Flags" part you should probably leave unchanged. – ban-geoengineering Mar 18 '17 at 17:52
  • Perhaps I've got it all wrong, but isn't the Inno setup script creating an installer that is to be distributed and ultimately run on the end users machine? If so, it would seem that the jre would have to be made available online and then downloaded in the [code] section into {tmp} then referenced from {tmp} from there in the Source statement? – Ed S Mar 18 '17 at 18:03
  • Yes, ISC is for creating an installer that you can distribute, but the whole point of bundling the JRE is so user won't have to manually download it later. It's a tidy solution as everything is contained within the installer. (It also gives you full control over which JRE version is used with your app - in my example, it's JRE6.) – ban-geoengineering Mar 20 '17 at 09:08
  • If you're still getting the "runtime is missing or corrupted" message despite following the above steps, make sure you are using the correct JVM for your machine. I cloned my own project that was created on 32-bit Windows but I got the "runtime is missing or **corrupted**" error. This time, the solution was to download the latest JVM for my machine from http://www.oracle.com/technetwork/java/javase/downloads/index.html and include that instead. :-) – ban-geoengineering Jan 15 '18 at 17:42
  • Also, *Inno Setup Compiler* is now just called *Inno Setup* and can be downloaded via http://www.jrsoftware.org/ . – ban-geoengineering Jan 15 '18 at 17:44
  • If you specify a _relative path_ to the `jre6` folder in the Bundled JRE Path field, would it work? – Ko Ga Oct 27 '19 at 08:01
  • @KobbiGal Yes, I think that's what I suggested in my answer - typing in just `jre6` does make it relative. If you meant *absolute*, I'm not sure so you'd have to give that a try. – ban-geoengineering Oct 28 '19 at 12:17
  • @ban-geoengineering - I meant relative as in `./jre6`, not just `jre6`. – Ko Ga Oct 28 '19 at 18:45
  • @KobbiGal I'm not sure. I'm using Windows, so `jre6` is relative for me. If `./jre6` doesn't work for you, check out the documentation that comes bundled with Launch4j, or check out the support page: https://sourceforge.net/projects/launch4j/support . – ban-geoengineering Oct 28 '19 at 18:57
  • 2
    For those like me wanting to integrate launch4j + inno setup into a gradle task this might come in handy: https://blog.heckel.io/2014/05/29/gradle-create-windows-installers-debian-packages-manage-a-ppa-and-optional-sub-projects/ https://github.com/syncany/syncany/blob/develop/gradle/innosetup/INNOSETUP.md – Alex Rodriguez Lopez Jan 30 '20 at 07:50
8

the easy method to package jre to exe that lanch4j packaged is use wrap.

warp-packer --arch windows-x64 --input_dir mycrt --exec run.bat --output single.exe

and then stop cmd windows when launch exe.

editbin /subsystem:windows

warp: https://github.com/dgiagio/warp

editbin: installed by VS

Demo:

enter image description here

enter image description here

jamlee
  • 1,234
  • 1
  • 13
  • 26
  • This worked well for me. Based on the info here, I wrote instructions to use jlink+warp+maven+javafx to create an executable JavaFX windows application file (.exe) in my answer to [How to create a standalone .exe in Java (that runs without an installer and a JRE)](https://stackoverflow.com/questions/69811401/how-to-create-a-standalone-exe-in-java-that-runs-without-an-installer-and-a-jr). – jewelsea Nov 03 '21 at 21:05
3

Bundled JRE Solution for Inno Setup

In order to implement a bundled JRE solution with an application jar, I created an Inno Setup script that:

1) copies the JRE into the install exe

2) executes the equivalent of terminal command: java -jar myjar.jar using the bundled JRE

Firstly I copy the JRE:

#define MyJREPath "C:\Program Files\Java\jre1.8.0_191"

[Files]
Source: "{#MyJREPath}\*"; DestDir: "{app}\runtime\jre\";  \
        Flags: ignoreversion recursesubdirs createallsubdirs;  

I follow the directory structure convention shown here: https://docs.oracle.com/javase/8/docs/technotes/guides/deploy/self-contained-packaging.html

To run the equivalent of java -jar myjar.jar:

[Run]
Filename: "{app}\runtime\jre\bin\javaw.exe"; Parameters: " -jar myjar.jar"; \
          WorkingDir: "{app}\app\"; \
          Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; \
          Flags: postinstall skipifsilent   

(n.b. java.exe runs with a terminal and javaw.exe runs without a terminal)

Desktop shortcut needs to have the right filename, parameters and working directory:

[Icons]
Name: "{commondesktop}\{#MyAppName}"; \
      IconFilename: "{app}\app\{#MyAppIcoName}"; \
      Filename: "{app}\runtime\jre\bin\javaw.exe"; \
      Parameters: " -jar myjar.jar"; \
      WorkingDir: "{app}\app\"; \
      Tasks: desktopicon

[Tasks]
Name: "desktopicon"; \
    Description: "{cm:CreateDesktopIcon}"; \
    GroupDescription: "{cm:AdditionalIcons}"; \
    Flags: unchecked

For the icing on the cake, in order make my script handle both bundled JRE and none bundled options I use the Preprocessor IF statement (duplicated in each script section) to test whether the script has an empty MyJREPath or not. If MyJREPath is not empty and so a bundled JRE solution is required I use the coding above; alternatively if a bundled solution is not required then I use more "normal" coding shown the Inno Setup examples or generated by their wizard. Here's the IF statement:

#if MyJREPath != ""
    ; bundled JRE required

#else
    ; bundled JRE not required
#endif

Here's most of my script put together:

        ; Script generated by the Inno Setup Script Wizard.
        ; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!


        ; some more #defines here

        #define MyAppExeName "javaw.exe"
        #define MyJREPath "C:\Program Files\Java\jre1.8.0_191" 
        ;#define MyJREPath ""




        [Setup]
        ; NOTE: The value of AppId uniquely identifies this application.
        ; Do not use the same AppId value in installers for other applications.
        ; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
        AppId=XXXXXXXXXX
        AppName={#MyAppName}
        AppVersion={#MyAppVersion}
        ;AppVerName={#MyAppName} {#MyAppVersion}
        AppPublisher={#MyAppPublisher}
        DefaultGroupName={#MyAppPublisher}
        AppPublisherURL={#MyAppURL}
        AppSupportURL={#MyAppURL}
        AppUpdatesURL={#MyAppURL}   
        DefaultDirName={pf}\{#MyDefaultDirName}
        DisableProgramGroupPage=yes
        LicenseFile={#MyInnoSetupDir}\system\{#MyLicenseFile}
        OutputDir={#MyInnoSetupDir}

        #if MyJREPath != "" 
          ; run app with bundled JRE
          OutputBaseFilename={#MyAppName}-{#MyAppVersion}-bundledJRE-setup
        #else
          ; run app without bundled JRE
          OutputBaseFilename={#MyAppName}-{#MyAppVersion}-setup          
        #endif 

        SetupIconFile={#MyInnoSetupDir}\{#MyAppIcoName}
        Compression=lzma
        SolidCompression=yes  
        AppComments={#MyAppName}
        AppCopyright={#MyAppCopyright}  
        UninstallDisplayIcon={#MyInnoSetupDir}\{#MyAppIcoName}
        UninstallDisplayName={#MyAppName}
        WizardImageStretch=No
        WizardSmallImageFile={#MyInnoSetupDir}\{#MyAppBmpName}



        [Languages]
        Name: "english"; MessagesFile: "compiler:Default.isl"
        ;Name: "german"; MessagesFile: "compiler:Languages\German.isl"

        [Tasks]
        Name: "desktopicon"; \
                Description: "{cm:CreateDesktopIcon}"; \
                GroupDescription: "{cm:AdditionalIcons}"; \
                Flags: unchecked
        Name: "quicklaunchicon"; \
                Description: "{cm:CreateQuickLaunchIcon}"; \
                GroupDescription: "{cm:AdditionalIcons}"; \
                Flags: unchecked; OnlyBelowVersion: 0,6.1

        [Files]
        ; bundle JRE if required
        #if MyJREPath != "" 
            Source: "{#MyJREPath}\*"; DestDir: "{app}\runtime\jre\";  \
                Flags: ignoreversion recursesubdirs createallsubdirs;       
        #endif      

        ; copy jar and all files  
        Source: "{#MyInnoSetupDir}\*"; DestDir: "{app}\app\"; \        
                Flags: ignoreversion recursesubdirs createallsubdirs


        [Icons]
        #if MyJREPath != ""
          ; set up icons with bundled JRE
          Name: "{commonprograms}\{#MyAppName}"; \
                  IconFilename: "{app}\app\{#MyAppIcoName}"; \
                  Filename: "{app}\runtime\jre\bin\{#MyAppExeName}"; \
                  Parameters: " -jar {#MyJarName}"; \
                  WorkingDir: "{app}\app\"
          Name: "{commondesktop}\{#MyAppName}"; \
                  IconFilename: "{app}\app\{#MyAppIcoName}"; \
                  Filename: "{app}\runtime\jre\bin\{#MyAppExeName}"; \
                  Parameters: " -jar {#MyJarName}"; \
                  WorkingDir: "{app}\app\"; \
                  Tasks: desktopicon            
          Name: "{userappdata}\Microsoft\Internet Explorer\Quick Launch\{#MyAppName}"; \
                  IconFilename: "{app}\app\{#MyAppIcoName}"; \
                  Filename: "{app}\runtime\jre\bin\{#MyAppExeName}"; \
                  Parameters: " -jar {#MyJarName}"; \
                  WorkingDir: "{app}\app\"; \
                  Tasks: quicklaunchicon
        #else
          ; set up icons without bundled JRE
          Name: "{commonprograms}\{#MyAppName}"; \
                  IconFilename: "{app}\app\{#MyAppIcoName}"; \
                  Filename: "{app}\app\{#MyJarName}"; \
                  WorkingDir: "{app}\app\"
          Name: "{commondesktop}\{#MyAppName}"; \
                  IconFilename: "{app}\app\{#MyAppIcoName}"; \
                  Filename: "{app}\app\{#MyJarName}"; \
                  WorkingDir: "{app}\app\"; \
                  Tasks: desktopicon            
          Name: "{userappdata}\Microsoft\Internet Explorer\Quick Launch\{#MyAppName}"; \
                  IconFilename: "{app}\app\{#MyAppIcoName}"; \
                  Filename: "{app}\app\{#MyJarName}"; \
                  WorkingDir: "{app}\app\"; \
                  Tasks: quicklaunchicon 
        #endif

        [Run]
        #if MyJREPath != ""
          ; run app with bundled JRE
          Filename: "{app}\runtime\jre\bin\{#MyAppExeName}"; Parameters: " -jar {#MyJarName}"; \
                  WorkingDir: "{app}\app\"; \
                  Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; \
                  Flags: postinstall skipifsilent          
        #else
          ; run app without bundled JRE
          Filename: "{app}\app\{#MyJarName}"; \
                  WorkingDir: "{app}\app\"; \
                  Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; \
                  Flags: shellexec postinstall skipifsilent          
        #endif 

Hope this helps.

David Miller
  • 694
  • 6
  • 7
3

The Java Packager included with JDKs from JDK 7 Update 6, is the official way to embed JRE along with your code in a native executable file. Some maven plugin seems to package the task of packaging and generating native executable for major plateforms.

From JDK11 java packager would need to be downloaded according to java-packager-with-jdk11 witch demonstrates packaging using gradle

Another approach may be to build a GraalVM Native image with the contstraint to find alternatives to libraries using reflexion which is not supported.

user1767316
  • 3,276
  • 3
  • 37
  • 46
  • not suggesting the graalvm as the current situation is not fully supported the swing & awt frames, etc.... still many works to do. – gumuruh Apr 09 '22 at 02:24
2

I've never used the Launch4J product, good luck in getting it configured correctly.

Looks like you might be able to go to the Discussion Forum on Sourceforge for other hints here

Other Suggestions:

Most of the products I've seen from IBM (Websphere) and Oracle just extract a JRE under the installation directory and configure the startup batch command to use the installed JRE. Essentially the JRE and your jar file would be installed in one shot.

The installation exe usually checks to see if it's already installed and skips that step if it finds it already there. This is useful for upgrades of just the jar file.

Having the local installation also solves the issue of the customer installing their own JRE which may be incompatible or contain bugs. This way your dealing with a known JRE version.

The excelsior route is OK if you don't have a graphical component to your application (It's been a while, that restriction may have changed). There are other restrictions as well, but you probably just better off just distributing a JRE with your code in a single executable installer.

Mike
  • 3,186
  • 3
  • 26
  • 32
  • You seem to know our product since its infancy! In fact, Excelsior JET was first certified Java Compatible back in 2005, so it's been fully supporting Swing/AWT since then. It also handles Eclipse RCP just fine, JavaFX 2 is a bit tricky but works. You can download natively compiled Eclipse 4.2 Classic and JavaFX 2 Ensmeble demo from the gallery: http://www.excelsior-usa.com/jetgallery.html Disclaimer: I work for Excelsior. – Dmitry Leskov Dec 29 '12 at 09:19
1

Its easy to bundle jre into launch4j..

just copy the jre into the same output folder

In the bundle jre environment text box, just give the jre folder itself

In the environment variable text box (present in the same page below), give until bin

Then create exe.. It works as expected without jre in machine.

Thanks

Nivedha
  • 29
  • 1
  • 1
    This assumes you are using some other method to install the JRE on the target machine, next to the .exe file that Launch4j builds. – simpleuser Mar 22 '19 at 21:15
0

It seems you need native code compiler. These compilers produce native code which doesn't require JRE.

Check this article - http://web.archive.org/web/20190128082712/https://www.excelsior-usa.com/articles/java-to-exe.html#aot.

tcb
  • 2,745
  • 21
  • 20
-3

What you're asking for isn't going to be easy to do (if it's doable at all.) If I were you I would look into creating an executable JAR file:

java eclipse create executable jar

Another option would be to use Java Web Start. This was assuming you're using a modern browser the JNLP will automatically prompt the user to install the correct version of Java.

http://docs.oracle.com/javase/tutorial/deployment/webstart/index.html

Community
  • 1
  • 1
Matt Klooster
  • 717
  • 1
  • 5
  • 13
  • Is there any way that an executable jar could be run without jre? I had believed it impossible. Also, with a web start, does the app have to be online for it to work? – MagicGuy52 Dec 21 '12 at 20:23
  • No, executable JAR needs a JRE. Webstart doesn't have to be online, you can point it at local location. The only limitation is you need to open it with a browser, and include the node in the JNLP file. Here's a good question about doing that: [local-alternative-to-jnlp-file](http://stackoverflow.com/questions/2032491/local-alternative-to-jnlp-file) – Matt Klooster Dec 21 '12 at 20:54
-3

There are several reason why launch4j wont run smoothly. some of the reason is:

1) user do not run the application as Administrator

2) User do not setup icon image properly. must strictly .ico

Ridzuan Adris
  • 1,192
  • 2
  • 13
  • 32