Bundling the JRE with a Java application - java

I have created an exe with a launch4j Ant script and build.xml file. I want to bundle the JRE in my application and have to distribute it to clients. How do I do this?
Thanks,
Rajani

Well, just bundle everything under $JAVA_HOME/jre into your distribution (presumably a Zip/TAR file) and then have your scripts reference that (i.e. use the java executable under $JRE_HOME/bin to run your java program).
Remember that if you do this, you will have to deliver different distributions for different target platforms (Windows,OSX, linux etc) and architectures (or one bloated uber-distribution of course, but no one will thank you for that!).

This works great... if you want your program to run on just a single version of a specific OS.
Generally, though, bundling a JRE is a bad idea. Even on Windows, there are three versions of the JRE: one for x86, one for x86-64, and one for Itanium. Even if Sun does make it hard to find the 64-bit versions, they still exist.
The 64-bit versions of Java for Windows are actually on java.sun.com, but not java.com.

Related

How to run java program using Oracle JDK 17, if Oracle JDK 17 does not come with JRE [duplicate]

This question already has answers here:
How can I get Java 11 run-time environment working since there is no more JRE 11 for download?
(4 answers)
Closed 3 years ago.
We are planning to migrate our Java 8 project to use Java 11. But I noticed that Java 11 doesn't have a JRE folder.
In Java 9 and Java 10, folder structures are changed i.e. java\jdk1.x or java\jre1.x, where x is Java 9 or 10.
But in Java 11, I am getting only one folder, i.e. java\jdk-11. How will my client use my application without jre?
What I understood is that Java 11 is enforcing to modularize our application, and using jlink is needed to create our own jre to run the application in client.
Is my understanding correct?
For 20 years, the JDK shipped with a JRE which was just a subset of its functionality installed in a different directory on your system.
In fact, it shipped with TWO identical JREs, one installed inside the JDK installation directory and one outside it.
This has always puzzled me as it's a complete waste of effort on the part of the maintainers to make this so, and a complete waste of disk space on the computer you install it on, as that JRE just duplicates some of the things the JDK can do already.
Finally, with Java 11, Oracle and the OpenJDK team decided to end this silliness and just distribute a single thing, the JDK.
This JDK when installed is actually smaller on your hard disk than the old JRE alone used to be, removing even the somewhat valid argument that you'd want a separate JRE for devices with limited disk space, an argument that never explained why 2 JREs would be installed with a single JDK in the first place but was made to justify the need for a JRE as a stripped down runtime environment for the JDK.
Ergo, there is no need for a separate JRE, and there hasn't been one for a long time, let alone for including and forcibly installing it as part of the JDK installation.
And no, you don't need to create your own JRE. Just install the OpenJDK on the client machines and make sure you add the $JAVA_HOME/bin to the system path, just as you had to do with old JREs.
And oh, strip the Windows directory tree of any java*.exe files which some versions of the old JRE installer were wont to place there, as well as the system path which also had some weird entries added by some JRE installers.
tl;dr
How will my client use my application without jre?
➥ Bundle a Java implementation within your Java-based app.
Learn about:
Java Platform Module System
jlink (JEP 282)
jpackage (JEP 343)
Details
What I understood is that Java 11 is enforcing to modularize our application
No, modularization is not required, strictly speaking. Most existing apps can run as-is in Java 11. You can continue to develop in Java 11 without modularizing your code. But in your case, for a GUI desktop or mobile app, then you need to package a JVM within your app. Modularizing and using jlink tooling is probably the best way to go about that. In contrast a server-side Servlet-based app or Microservices server need not yet modularize, though likely a good idea to do so eventually.
I noticed that Java 11 doesn't have a JRE folder.
Oracle no longer intends for end-users to be installing a JRE or a JDK. Java Applets in a browser and Java Web Start app delivery are both being phased out, leaving the end-user with no need for a JRE. Java-based apps are expected to bundle their own Java implementation. The only folks consciously installing a JDK will be developers & server-side sysadmins.
Some folks are disappointed to see the passing of the Java Everywhere dream. And they may be annoyed to have to make a build of their app for every host OS (macOS, Linux, Windows, etc.). On the other hand, some developers are happy to be bundling a Java implementation (now smaller than ever) with their app, as that eliminates the hassle for the end-user to download-install-update a system-wide Java implementation. Also eliminates wrestling with corporate IT departments to install Java on users’ PCs. And bundling Java with app simplifies testing and support, as you know and control exactly what version and distribution of Java is involved. By the way, this bundling-Java-with-app is not exactly new: It has been supported by Apple for many years in the macOS & iOS app stores.
Important:
Understand clearly the nature of the OpenJDK project, as explained in Wikipedia
Read this white paper by Oracle of 2018-03, Java Client Roadmap Update
Read the white paper Java Is Still Free, authored by key members of the Java community.
Here is a flowchart diagram that may help you finding and deciding amongst the various vendors providing a Java 11 implementation.
Look at the AdoptOpenJDK project website to download the latest JRE and JDK.
I have used their nightly builds to work around the problem of missing JRE in JDK package. Just unpack JRE into JDK folder and this is going to be it.

A better way how to make Eclipse resistant to Java updates

It is a know problem, when you update Java, JDK or JRE, on Windows Eclipse will likely to fail to start as it points to outdated JDK/JRE folder. Fix is relatively simple, it was discussed and solved on several threads like here or here.
But I found those solutions unsatisfyingly inflexible. This solutions suggest to manually fix path in eclipse.ini to something like:
-vm C:\Program Files\Java\<jdk-version-just-installed>\bin\javaw.exe
This means you have to do it after every update, again and again. If you update JDK frequently, and everyone should to have latest security patches, that makes it very annoying.
I expect that after a smart installation every Java program would just run out of box without any manual step involved; any solution less than that I would not consider satisfactory.
I can think of two ways:
using environmental (system) variable like JAVA_HOME. Can eclipse.ini reference environmental variables?
using symbolic link pointing to the latest JDK. And if you wonder, yes, Windows with NTFS support symlinks.
Both ways however need some cooperation from the installer, both JAVA_HOME or symlink as to be updated to the new value. Automatically of course, otherwise there would be no reason why to have them in the first place.
Please correct me if I am wrong, but JDK/JRE installation on linux does exactly that, provides and updates symlink to latest JDK/JRE. Why not Windows installer?
Is there a hidden parameter, option or a toggle in Java install tool doing that?
If not, is there a better, an alternative installation tool?
Can Eclipse launcher itself find a latest Java?
Is there a better eclipse.ini parameter for that?
The purpose of specifying the VM in either eclipse.ini or on the command line is to isolate it from system updates. For example, in the past it has been a big problem that some programs install their own JVM and include it on the system PATH (Oracle was particularly bad about this). So the entire idea is to isolate Eclipse from those kinds of changes; it should not care what other JVMs you have on your system, it refers to a "known" good one for running Eclipse.
Another alternative is to place a JVM directly under the Eclipse installation directory, in a directory named jre, as documented here. I don't personally ever do that, however; I find it to be unnecessary and cumbersome.
What I do that would probably help you is to not install JVM updates into separate directories with names that reflect the actual update version. Instead, I install JDKs into a consistent place based on the major java version. For example:
/Java/
/JDK/
/1.7/
/bin/
<etc...>
/1.8/
/bin/
<etc...>
That way, in eclipse.ini (or any other place a need to refer to a particular JVM) I just use /Java/JDK/1.8 and that will continue to work no matter how many updates I install into that location.
What we do to avoid this problem: We have custom dedicated JDK's for our development environment (for eclipse and for our products), which are not 'attached' to the system. We're using softlinks e.g. ../app/jdk which links to a specific jdk, for intellij we have a ../app/intellij-jdk softlink.
Not sure who to do it in windows, but in linux you download the gzip and extract it, withing messing up your system, like paths, I think for windows you can only download the installer, but it's possible to only extract the actual software from the executable.
Older Windows JDK installers used to copy java.exe and javaw.exe (and also javavm.dll I think) in c:\windows\system32 to make them available in the default path.
In recent installers, a symbolic link is created for java.exe, javaw.exe and javaws.exe in C:\ProgramData\Oracle\Java\javapath. This means that these executables will point always to the most recent JDK update.

Java exe launcher with support for Windows 7

The Problem
Currently I use exe4j 4.4.2 to wrap our client app in a Windows native executable, but the result does not integrate with Windows 7 so well.
For example: When I right click in the task bar it only offers a pop-up to close the application but no pinning. Eclipse' Equinox launcher on the other hand does that with bravado.
I'm looking for a java exe launcher which has the following features:
Wraps jars in Windows native executables (no Java Web Start or similar)
Doesn't extract the jar from the executable
Doesn't need write access in "Program Files"
Uses executable filename as process name (only one process)
Integrates well with Windows 7 (esp. pinning in the taskbar)
Allows setting of JVM arguments (esp. heap size)
Flexible customization for JRE search
Lightweight
Actively maintained
Integrates well in Ant build
Preferably free
I have checked the following:
exe4j
Windows 7 integration lacking
It's not expensive but ordering and
distribution of licenses to the build machines is a pain.
JRE search not flexible enough
Eclipse Equinox
Not lightweight
Seems to do everything I want, except that I have no idea how
to use it with a non-eclipse-based app.
Can I use it outside of OSGI, PDE-Build world?
WinRun4J
JRE search not well documented
Seems not widely used despite incredible feature set, what am I missing?
Launch4J
Doesn't support setting the process name in Windows 7 (Bug ID 3353972).
There is a patch (Bug ID 1670471) but it has been rejected with reference
to jliftoff which is dead.
JRE search not flexible enough.
JSmooth
Seems not to be actively maintained.
Latest release is from 2007, well before Windows 7.
Are there any other options?
Is there a chance to use the Eclipse launcher with a non Eclipse-base application?
Try Advanced Installer http://www.advancedinstaller.com/java.html (There is a free edition available in this).
I'm happy with WinRun4J. The JRE search works fine for me. It sometimes chokes especially on 64bit systems if multiple JREs and JDKs are installed and registered in the Windows registry, but this can usually be fixed by supplying the correct path in the corresponding .ini file.
I did not use Launch4J because it creates a new (temporary) .exe in the JRE installation folder which seems a bit strange to me. The advantage of that method is, that it can use a single .exe for both 32 and 64 bit JVMs though
It sounds to me like you just need to go with Launch4J. The process name matches the .exe name that you launch with. A great example of a program that is wrapped this way is "Keystore Explorer 4.01".
I would create a bat file. Wrap this bat file into a exe. You can create an exe with an icon and everything. Try this bat to exe converter:
http://download.cnet.com/Bat-To-Exe-Converter/3000-2069_4-10555897.html
In this way, you have better control. The size of the exe is very small.
Edit: Also, the creation of the exe is one time thing.

I make my executable jar in exe format,but i want to add jre with this

I make my executable jar in exe format, but I want to add JRE with this because if JRE is not present in their machine, they can use it with this included JRE.
But I do not want to install this JRE in their machine. This JRE is only used by this application only. It will just like game or other application. I use launch4j to make jar to exe but i did not find any option from where it can attach JRE and it has no option from where I can link my jar dynamically.
How do I achieve that?
If there is other free installer then mention it, and please give the procedure with example.
Since it has been established that your app. has a GUI, I will suggest Java Web Start as the answer.
But I do not want to install this JRE in their machine.
That is not a sensible requirement. The user might already have a usable JRE installed, if they don't they probably also don't want every Java based application to be installing its own 'private' JRE.
Oracle's deployJava.js can do the checking, and help guide the user through the steps of installing (which basically comes down to click 'OK' when prompted).
I make my executable jar in exe format,..
If you only intend to support Windows, what is the attraction of coding in Java? JWS supports any platform for which Java is available. That brings a lot more potential customers for the app.
I want to use free installer.
JWS is entirely free. Just like the JRE.
..please give the procedure with example.
Do you run an IDE? If not, do you otherwise have Ant installed? If that is a yes to either one, check out my small JNLP API examples. Each comes with complete source and a build file (an Ant build.xml).
Within a couple of keystrokes & a few moments, you can see the app. installed and launched on your desktop. For the end user, it is even simpler. Just click a link in a web page, and it all happens automatically (possibly with a security prompt - for the protection of the user).
I like JSmooth. You can give it a try here:
http://jsmooth.sourceforge.net/features.php
Flexible automatic Java VM detection
Detects the location of any Sun JVM installed. The wrappers use
several strategies to detect all the JVM available on a computer,
using windows registry, environment variables, windows path.
Detects
and uses Microsoft's JView (for 1.0 and 1.1 Java applications), if
available.
The JVM search sequence is fully customizable using the
GUI. You can force the executable to search in the path first, and in
the registry last, or in JAVA_HOME first. We have all the flavours!
Sometimes it's more convenient to bundle a JRE with your application.
JSmooth can deal with that too, you just need to define in which
folder the JRE is expected. It falls back nicely to a standard JVM
search if the JRE is not where it should be.
Specify which versions of
the JVM are compatible with your software. You can set a minimum
version, but also a maximum JVM version.
Documentation: http://jsmooth.sourceforge.net/docs/jsmooth-doc.html
Take a look at launch4j.
I had to use it, and it worked out very well.
You can set a minimum version of a needed JRE, bundle a JRE, or if a JRE is not found (and not bundled) the launcher may lead the user to a download location of an appropriate JRE.
There are various further features launch4j offers, and as opposed to another suggestion here, launch4j is activly developed
http://launch4j.sourceforge.net/

How do I properly repackage the JRE installer in my installer?

I've got a Java application that I'm writing an installer for. We're using the AdvancedInstaller program to create our installer (well, we're evaluating it currently, but will definitely purchase a license soon), and although it has special support for Java applications, it is geared more towards repackaging them as desktop-type apps, and our software is a series of Java services and other utilities which doesn't make sense to distribute in EXE-wrappers. The target audience for this software is very specific, and we know that our software will probably be automatically distributed on freshly-imaged Windows 2003 Server machines. So requiring Java as a prerequisite basically makes more work for some poor sysadmin, and I'd rather avoid that if at all possible by repackaging the JRE's installer inside of our own.
I discovered that if I tried to execute the JRE's installer as a pre-install step from my MSI, it complains that another installer is already running (mine, of course), so it bails out. When I try to add the JRE installer as a software prerequisite in the AdvancedInstaller project (as a bundled EXE, not a URL link), it never seems to actually get installed, despite me trying to force-install it.
What's the best way to repackage the JRE? I'm not really a Java guy, so I don't know too much about how other developers deal with this same problem, short of requiring their users to hunt out and install the JRE on their own. The ideal solution here would be for us to find a EXE installer which can be executed from inside of another MSI installer, or if it's possible, to just package all of the files inside of the JRE and then create the appropriate registry and environment variables. How should I go about doing this?
I have not idea if this is "the way" to do it, but confronted with a somewhat similar problem, we simply archive an installed JRE with the rest of our application files and make sure that all our start scripts don't use java ..., but rather ..\..\jre\bin\java ... or similar. The JRE is unpackaged as part of our installation process in a subdirectory of where we install and that's that.
I agree with bdumitriu's answer:
a simple zip of a jre is enough, unless you want to link that jre to:
default java (meaning you must add java.exe of the unzipped jre to the path, before any other java path references)
default java for some script (you could define JAVA_HOME as referencing your new unzipped jre, but that may have side effects on other script also using JAVA_HOME before that new JRE)
file associations like .jnlp or .jar files (this requires some registry modifications)
browser java plugin registration (which requires also registry modifications)
If the last two points do not interest you on the desktop concerned by this deplyment, a simple zip is enough.
http://www.syswow64.co.uk/2013/05/java-7-update-21-1721-enterprise.html
The issue on many blogs and articles is around creating the 'deployment.config' and 'deployment.properties' files for an enterprise deployment. In my case i wanted to set the security level to 'Medium', but everytime I open the Java control panel it was set to the default HIGH setting.

Categories

Resources