Article ID: 000035
Last Revised On: 08-Apr-2012
PDF Version: 000035.pdf
The information in this article applies to:
You may download the latest version of Excelsior JET here.
This document explains how to reduce your Java application to a single EXE file after you have natively compiled it with Excelsior JET. A step-by-step guide utilizing free third-party tools is provided.
Disclaimer: This article references third-party software products, namely 7-Zip and ResEdit. These specific products are only used here for illustrative purposes and are not endorsed by Excelsior in any way. Excelsior has no control over the third parties providing those software products and therefore may not be held responsible for their availability and quality. Your use of those products, or any other third party products providing similar functionality will be subject to the terms and conditions of the respective license agreements and other applicable legal instruments.
Even though Excelsior JET compiles your jars and class files into a binary executable, that executable still requires a number of runtime files (JetPackII places them into the $(Root)/rt folder by default.) You must distribute those files alongside the executable. If you do not want to create an installer, you have to export your application as a self-contained directory, and then copy that directory in its entirety.
A workaround exists for those who absolutely must distribute their applications as single executables: use third-party tools to package the exported application as a self-extracting archive that would unpack its contents into a temporary directory, run the application from that directory, wait for its termination, and clean up after itself.
The tradeoff: The startup time of a natively compiled Java app is I/O bound, so the penalty imposed by this workaround may be substantial, especially on warm starts. At the same time, cold start from a slow-seek device such as an optical disk drive will actually be much faster. You will also be unable to fully enjoy the application download size reduction capabilities of Excelsior JET.
The rest of the article explains how to implement the above workaround using the excellent free 7-Zip archiver by Igor Pavlov, and how to “personalize” the resulting executable with ResEdit. You may of course use tools of your choice instead.
To reduce your natively compiled Java application into a single executable using 7-Zip, do the following:
For instance, if your compiled application that you want to launch is called MyApp.exe, the configuration file may have name MyApp.cfg and look like this:
;!@Install@!UTF-8! Progress="No" RunProgram="MyApp.exe" ;!@InstallEnd@!
The line “Progress="No"” is optional. It suppresses the extraction progress dialog.
copy /b 7zS.sfx + MyApp.cfg + MyApp.7z MyApp-standalone.exe
Notice the use of the /b switch to force binary concatenation!
Now, if you run MyApp-standalone.exe on another system, the SFX module will silently extract MyApp.7z into a temporary directory, run MyApp.exe from that directory, wait for its termination and remove the temporary directory and all its contents.
Note: A UAC prompt may display upon application startup on Windows Vista and Windows 7:
(As you may see, signing the executable does not help).
To learn what causes this problem and how to solve it, refer to the “Getting Rid of UAC Prompt” in the ADVANCED section below.
Starting from Windows Vista, a program author may indicate the required privilege level to the operating system by embedding an application manifest within the program. However, the original 7-Zip SFX modules do not have manifests at all, thus triggering a UAC prompt upon launch.
Fortunately, it is very easy to fix this — just add a manifest requesting asInvoker execution level to the SFX module. Refer to the next section for an easy way to do that.
Whatever your application is, the icon and version information of the SFX module will display in Windows Explorer and elsewhere /The admin shield on the icon is an indicator of the above UAC prompt issue/ :
|
|
You will likely wish to replace these with icon and data specific to the packaged application. To avoid rebuilding the SFX module from source, use a resource editor that can edit binary resources in-place. The below instructions assume usage of a freeware resource editor called ResEdit.
To begin:
To add an application manifest:
The default manifest should eliminate the UAC prompt just fine. If you want to double-check, make sure that it includes the following:
<security> <requestedPrivileges> <requestedExecutionLevel level="asInvoker" uiAccess="false"/> </requestedPrivileges> </security>
To replace the SFX icon with your application icon:
To edit version information:
Save the project and exit ResEdit. MyApp-sfx.exe is now “personalized” with your app’s icon and version information. Just make sure to change your build scripts to use the customized SFX module instead of the original 7zS.sfx.
Here is the result:
|
|
Notice that there is no more admin shield on the icon, thanks to embedding the application manifest into the SFX module. Now the application will start without a UAC prompt.
For some reason, our copy of ResEdit does not save changes to File Version and Product Version fields in the General Information section, As you may see, they stayed at 4.65.0.0. If this is important to you, you may wish to try some other resource editor.
Under certain circumstances, e.g. if the packaged application was run from a CD, Windows Program Compatiblity Assitant (PCA) may come into play upon application termination, claiming that it might not have been installed correctly. Basically, PCA wrongfully detects the packaged app as a setup, and raises an alert after it leaves no trace in Add/Remove Programs.
The precense of an UAC manifest disables PCA on Windows Vista, but not on Windows 7. Windows 7 added support for the <compatibility> section in application manifests (Windows Server 2008 R2 is also supposed to recognize it.) If you add the following section to the SFX module manifest, the PCA warning shall not appear:
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!--The ID below indicates application support for Windows Vista -->
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
<!--The ID below indicates application support for Windows 7 -->
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
<!--The ID below indicates application support for Windows 8 -->
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
</application>
</compatibility>
Note: As of version 1.5.4, you may not edit the manifest file in ResEdit. Suggested workaround:
If you are making a portable application, as in “designed to run on any computer from a USB stick”, it may need to know where the original self-extracting executable resides, as any files it would have stored into the temporary directory will be removed upon its termination.
You may not supply this information with the self-extraction module that comes with 7-Zip. Fortunately, Oleg Scherbakov has created the modified module that supports a number of additional parameters and features.
Specifically, the “%%S” configuration file variable points to the location of the SFX archive. You may pass it to your application via an environment variable (use System.getenv() to retrieve the value):
;!@Install@!UTF-8! Progress="No" SetEnvironment="MYAPP_HOME=%%S" RunProgram="MyApp.exe" ;!@InstallEnd@!
or via a system property (use System.getProperty() for retrieval):
;!@Install@!UTF-8! Progress="No" RunProgram="\"MyApp.exe\" \"-Dmyapp.home=%%S\" myapp.Main" ;!@InstallEnd@!
Notes for the last sample:
7-Zip and the modified SFX modules are open sourced under GNU LGPL, so changing the SFX modules and using them in proprietary applications is certainly legal. Seek lawyer’s help in otherwise maintaining compliance with LGPL.
Excelsior Installer uses the LZMA SDK on which 7-Zip is based.
|
Home | Company | Products | Services | Resources | Blog | Contact Store | Downloads | Support | Forum | Blog | Sitemap © 1999-2012 Excelsior LLC. All Rights Reserved. |