"How do I make an .EXE file from my Java application?", "Need help converting jar to exe", "Is it possible to create a Windows executable using Java?" --- these and similar questions are among the most popular topics on Java developer forums. Should you start such a topic today, you are likely to encounter the following three types of replies:
- "You cannot"
- "You should not, because that would kill the very purpose of Java"
- "You can do that with third party software X and Y"
Simplify Java Application Deployment
Java compiles to platform-independent bytecode (.class files), which
is not directly supported by PC hardware. So a Java program needs
a Java Runtime Environment (JRE) to run, which would either interpret
the bytecode instructions or compile them to native code on the fly.
This in turn means that the author of that program has to ensure
somehow that the proper version of the JRE is installed on an end user
system.
In a general case you may not expect that your end users will know what a JRE is, how to check its version, and how to download and install it. This is especially true for consumer applications, such as games or multimedia. And those who already have a JRE installed may not like the idea about installing a different version, because it may break their existing Java applications and favorite applets.
Then, even if you can make sure the right version of the JRE is properly installed on enduser systems, which is quite possible in a classroom or enterprise environment, the command line required to launch your Java application can be quite long:
Yes, you may put that line into a batch file and call it
So it comes as no surprise that the primary motivation for seeking a way to convert a Java application into an EXE file is to make its deployment and use simpler and safer for an average user, that is, a Windows user. What surprises newbie Java developers is that the JDK does not offer such functionality. Before J2SE 1.4, all you could make with JDK tools were
In a general case you may not expect that your end users will know what a JRE is, how to check its version, and how to download and install it. This is especially true for consumer applications, such as games or multimedia. And those who already have a JRE installed may not like the idea about installing a different version, because it may break their existing Java applications and favorite applets.
Then, even if you can make sure the right version of the JRE is properly installed on enduser systems, which is quite possible in a classroom or enterprise environment, the command line required to launch your Java application can be quite long:
java -Xmx200m -cp whatever.jar -Dsome.property MyApp
Yes, you may put that line into a batch file and call it
runme.bat
,
but it looks so much easier to give your program to a friend, teacher or
colleague as a single file that can be run by a double-click. Or, even better,
enable it to be installed and uninstalled in a native manner without
affecting other applications.
So it comes as no surprise that the primary motivation for seeking a way to convert a Java application into an EXE file is to make its deployment and use simpler and safer for an average user, that is, a Windows user. What surprises newbie Java developers is that the JDK does not offer such functionality. Before J2SE 1.4, all you could make with JDK tools were
Executable Jars
Pros |
---|
No need to use any third-party tools Single distribution for all Java-enabled platforms |
Cons |
Application will not start on systems that do not have a JRE
(properly) installed Application will not work if it uses APIs absent in the default JRE Need to teach users that .JAR files are clickable |
Resources |
The Java Archive (JAR) File Format |
Tools |
One-JAR Autojar Fat Jar Java Launcher |
You can make your Java application runnable via a double-click by
packaging it into a so called executable jar. You do that by
specifying the main class of your application, any extra jar files
it may require and so on in the jar's manifest file
Note: As of J2SE 5.0, jar files are associated with the
If your application consists of more than one jar file, there is an open source tool called One-JAR that claims to correctly repackage multiple jars into one.
The major problem with executable jars is compatibility. The default JRE may be of an older version than is required by your application or may not have the necessary Java Optional Packages (previously known as Standard Extensions) installed. For instance, if your app uses the
Fortunately, Sun has created a Java application deployment technology that eliminates this compatibility problem and adds some nice features. It is part of the Java 2 platform since version 1.4 and is called
Main-Class: MyAppMain Class-Path: mylib.jarThen you use the
jar
utility from the Java SDK to package
your classes and resource files, specifying the m
option
and the name of your manifest file:
jar cvfm MyApp.jar MyApp.mf *.class *.gifThis will result in the creation of
MyApp.jar
. Now, if you type
java -jar MyApp.jarthe Java launcher will read the manifest from
MyApp.jar
and
invoke the main
method from the class MyAppMain
.
Moreover, if you double-click that jar file on a system that has JRE
installed, the java launcher will be invoked automatically.
Note: As of J2SE 5.0, jar files are associated with the
javaw
launcher on Windows, which does not open a console on
startup. If your application needs a console,
write a batch file which would start it using the
java
launcher.
If your application consists of more than one jar file, there is an open source tool called One-JAR that claims to correctly repackage multiple jars into one.
The major problem with executable jars is compatibility. The default JRE may be of an older version than is required by your application or may not have the necessary Java Optional Packages (previously known as Standard Extensions) installed. For instance, if your app uses the
java.nio
package introduced in Java 2 version 1.4,
it will not work on JRE 1.3.x. Similarly, if it uses JavaMail 1.3, and
the default JRE has JavaMail 1.2 or JavaMail is not present at all, the
double-clicked jar will not run.
Fortunately, Sun has created a Java application deployment technology that eliminates this compatibility problem and adds some nice features. It is part of the Java 2 platform since version 1.4 and is called
Java Web Start
Pros |
---|
Available for all major desktop platforms Single distribution for all JWS-enabled platforms Code-signing and sandboxing Versioning and incremental updates Automatic installation of JREs and optional packages Use of third-party tools is optional |
Cons |
Internet connectivity required if JWS, JRE, and/or an Optional
Package is not present on the system Support for jnlp MIME type required on both Web server and browser Limited desktop integration capabilities |
Resources |
JWS Technology Home
Deploying Software with JNLP and Java™ Web Start Java Web Start (Roedy Green's Java Glossary) Lopica - All Things Web Start |
Tools |
Xito Application Manager Automatic JNLP Generator |
Java Web Start (JWS)
and the underlying Java Network Launch Protocol (JNLP)
enable Java application delivery from a standard Web server.
The end user initiates application installation by clicking on an URL.
If the Java Web Start engine is not present on the system, the user
is prompted to download and install it. Once Java Web Start is in place,
clicking on the same URL will initiate the application download and
installation procedures. It may involve download and installation of the
required version of the JRE and Optional Packages.
Upon their successful completion, the application
is launched. The application will be cached on the user's system so next
time the user clicks on the same URL, the JWS engine will launch the
local copy of the application from the cache, if it detects that the
computer is offline or the application was not updated on the Web site.
Another important feature of JWS is its ability to run your application in a sandbox - a restricted container based on Java security architecture. But, unlike an applet, your application can gain access to local system resources like the filesystem, printer and system clipboard using the JNLP API even if it comes from an untrusted environment, after prompting the user for confirmation.
Java Web Start is available for Windows, Linux, and Solaris, and is part of MacOS X since v10.1. There are also third-party implementations of the JNLP protocol, some of them also include tools that assist you in the creation and maintenance of JNLP packages.
That was the bright side. Now, what is not so good about JNLP? First off, for seamless operation both the browser and the Web server that hosts the JNLP-enabled application must support
On the client side, a major browser would be configured to recognize the above MIME type during installation of the JWS engine, but users of less popular browsers, such as Opera, may have to do that manually.
JNLP-enabling an application may involve minor changes in its code and (re)packaging it into a set of jar files.
Before J2SE 5.0, JWS had very little to offer in terms of desktop integration - all it could do was create a desktop icon and/or a Start Menu entry for the application. On Windows, the application will not show up in Add/Remove Programs, so end users would have to run the Java Web Start application manager in order to remove your application.
Finally, JWS user interface needs much polishing. As of J2SE 5.0, users still complain about ugly windows with incomprehensible messages.
To sum it up, JWS can be a viable option in a controlled environment, such as corporate intranet, but it is not ready for the consumer market, where you may be better off using
Another important feature of JWS is its ability to run your application in a sandbox - a restricted container based on Java security architecture. But, unlike an applet, your application can gain access to local system resources like the filesystem, printer and system clipboard using the JNLP API even if it comes from an untrusted environment, after prompting the user for confirmation.
Java Web Start is available for Windows, Linux, and Solaris, and is part of MacOS X since v10.1. There are also third-party implementations of the JNLP protocol, some of them also include tools that assist you in the creation and maintenance of JNLP packages.
That was the bright side. Now, what is not so good about JNLP? First off, for seamless operation both the browser and the Web server that hosts the JNLP-enabled application must support
application/x-java-jnlp-file
MIME type. Some hosting providers
do not support it. Moreover, versioning and incremental updates require
additional support from the Web server, which has to be implemented
using servlets, cgi-bin scripts, etc.
On the client side, a major browser would be configured to recognize the above MIME type during installation of the JWS engine, but users of less popular browsers, such as Opera, may have to do that manually.
JNLP-enabling an application may involve minor changes in its code and (re)packaging it into a set of jar files.
Before J2SE 5.0, JWS had very little to offer in terms of desktop integration - all it could do was create a desktop icon and/or a Start Menu entry for the application. On Windows, the application will not show up in Add/Remove Programs, so end users would have to run the Java Web Start application manager in order to remove your application.
Finally, JWS user interface needs much polishing. As of J2SE 5.0, users still complain about ugly windows with incomprehensible messages.
To sum it up, JWS can be a viable option in a controlled environment, such as corporate intranet, but it is not ready for the consumer market, where you may be better off using
Custom Java Launchers And Wrappers
Pros |
---|
JRE version check JRE download or bundling Unique process name and icon No end-user training |
Cons |
Platform specific Desktop integration capabilities absent or very limited |
Resources |
JNI 6.0 Specification, FAQ, & Downloads Java Native Interface: Programmer's Guide and Specification (book, HTML, and PDF) |
Tools |
Commercial: Free:
JSmooth
Launch4j jstart32 exeJ Java Launcher Janel |
When a Java program is invoked using one of the methods discussed above
(batch file, executable jar, or Java Web Start/JNLP), the operating system
runs a Java launcher from the JRE. The Windows version of the JRE has
separate launchers for command-line and GUI apps, called
As a result, all running Java applications have the same Taskbar/Alt-Tab icons and appear in the Windows Task Manager as either
In fact, those launchers are just small native programs that load the Java Virtual Machine from a DLL/shared library and then feed your program to that JVM using the Invocation API. That API is part of the Java Native Interface (JNI), so it is standardized, and it is also very simple. This makes it relatively easy to write your own launcher with a unique name and icon. What it has to do is find a suitable JRE on the end user's system (unless you bundle the JRE with your application), load and initialize the JVM, and run your application on it.
If you do not have the right tools, skills, or time to develop a custom launcher for your Java application, there are quite a few third-party Java launcher generators listed in the Tools section of the frame. Some of them provide additional features such as instant splash screen, stdout and stderr redirection, and so on, the most notable being wrapping.
A Java wrapper is essentially a custom Java launcher that is also a self-extracting archive containing all the application's classes, jars and auxiliary files. The wrapper unpacks those files on startup and removes on termination. This way, your application is distributed as a single executable.
A wrapper normally looks up the JRE upon startup. If the JRE is not present or its version does not match the application's compatibility requirements, some wrappers may install the JRE (if you have included it when wrapping your application) and/or download and install the required version of the JRE.
The most sophisticated wrappers may also setup file associations and create shortcuts on first run. But if you need something more complex, such as support for automatic updates or uniform cross-platform deployment, have a look at
java.exe
and javaw.exe
respectively.
As a result, all running Java applications have the same Taskbar/Alt-Tab icons and appear in the Windows Task Manager as either
java.exe
or
javaw.exe
. If you have two or more Java apps running, you
have no means to distinguish between multiple instances of the standard
Java launcher in the Task Manager.
In fact, those launchers are just small native programs that load the Java Virtual Machine from a DLL/shared library and then feed your program to that JVM using the Invocation API. That API is part of the Java Native Interface (JNI), so it is standardized, and it is also very simple. This makes it relatively easy to write your own launcher with a unique name and icon. What it has to do is find a suitable JRE on the end user's system (unless you bundle the JRE with your application), load and initialize the JVM, and run your application on it.
If you do not have the right tools, skills, or time to develop a custom launcher for your Java application, there are quite a few third-party Java launcher generators listed in the Tools section of the frame. Some of them provide additional features such as instant splash screen, stdout and stderr redirection, and so on, the most notable being wrapping.
A Java wrapper is essentially a custom Java launcher that is also a self-extracting archive containing all the application's classes, jars and auxiliary files. The wrapper unpacks those files on startup and removes on termination. This way, your application is distributed as a single executable.
A wrapper normally looks up the JRE upon startup. If the JRE is not present or its version does not match the application's compatibility requirements, some wrappers may install the JRE (if you have included it when wrapping your application) and/or download and install the required version of the JRE.
The most sophisticated wrappers may also setup file associations and create shortcuts on first run. But if you need something more complex, such as support for automatic updates or uniform cross-platform deployment, have a look at
Java-Aware Setup Authoring Tools
Pros |
---|
Complete desktop integration Can be platform-specific or cross-platform Localization support Flexibility |
Cons |
Requires third-party tools which may be too pricey and/or complex |
Resources |
AppDeploy.com |
Tools |
Commercial: Free: |
If all you need is install a private copy of the JRE alongside your
application and create shortcuts that run your application on that JRE,
you may use any setup generator. However, using a Java-aware tool may give you the
following benefits:
Windows-centric tools, such as Advanced Installer for Java enable you to build MSI (Windows Installer) packages.
Multi-platform tools can generate native installers for multiple platforms - Windows, Linux, Mac OS X, as well as RPMs and tarballs. install4j is one such tool.
There exist also Java-based setup authoring tools enabling you to create cross-platform installations, Those installations are essentially executable jars with platform-specific logic selected at run time. InstallAnywhere is perhaps the most well known tool of this type, but if its pricing is beyond your budget, consider the open source IzPack.
Finally, there is One Tool to Rule Them All - InstallShield, which can create both Windows desktop (MSI) and cross-platform installations, plus server and mobile ones, for any type of application and for a multitude of platforms. And yes, it does support JRE lookup and bundling, native launchers, and so on.
For straightforward installations, however, InstallShield is an overkill. Also note that InstallAnywhere and InstallShield are aimed at the enterprise developer and are priced accordingly.
All the above solutions do not change the fundamental principle mentioned in the first section of this article. Whether you make an executable jar or create a sophisticated installer, your Java program is still deployed as platform-independent bytecode. In the early days of Java, the only way to execute a Java program on a common PC hardware was to interpret that bytecode. Today, any decent J2SE implementation contains a Just-In-Time (JIT) compiler that compiles frequently executed methods to native code. So it sounds quite natural to take one step further and compile the entire application down to native code before it is deployed. Such tools exist and they are called
- Install-time JRE detection and download
- Generation of native launchers
- User-editable JVM parameter files
- Redirection of stderr and stdout for saving logs and exception stack traces.
- Registration of Java applications as Windows services and Unix daemons
Windows-centric tools, such as Advanced Installer for Java enable you to build MSI (Windows Installer) packages.
Multi-platform tools can generate native installers for multiple platforms - Windows, Linux, Mac OS X, as well as RPMs and tarballs. install4j is one such tool.
There exist also Java-based setup authoring tools enabling you to create cross-platform installations, Those installations are essentially executable jars with platform-specific logic selected at run time. InstallAnywhere is perhaps the most well known tool of this type, but if its pricing is beyond your budget, consider the open source IzPack.
Finally, there is One Tool to Rule Them All - InstallShield, which can create both Windows desktop (MSI) and cross-platform installations, plus server and mobile ones, for any type of application and for a multitude of platforms. And yes, it does support JRE lookup and bundling, native launchers, and so on.
For straightforward installations, however, InstallShield is an overkill. Also note that InstallAnywhere and InstallShield are aimed at the enterprise developer and are priced accordingly.
All the above solutions do not change the fundamental principle mentioned in the first section of this article. Whether you make an executable jar or create a sophisticated installer, your Java program is still deployed as platform-independent bytecode. In the early days of Java, the only way to execute a Java program on a common PC hardware was to interpret that bytecode. Today, any decent J2SE implementation contains a Just-In-Time (JIT) compiler that compiles frequently executed methods to native code. So it sounds quite natural to take one step further and compile the entire application down to native code before it is deployed. Such tools exist and they are called
No comments:
Post a Comment