Step-by-Step Guide: Building a Windows EXE with exe4jCreating a native Windows executable from a Java application improves user experience by providing familiar double-click launching, bundling the right Java runtime, and offering nicer icons, version info, and installer integration. exe4j is a mature commercial tool designed specifically for turning Java applications into Windows .exe launchers. This guide walks through the full process: preparing your Java app, configuring exe4j, testing, and packaging the final EXE.
What exe4j does and when to use it
exe4j does not compile Java bytecode to native machine code. Instead, it creates a thin Windows native launcher that starts your JVM with the right settings and can optionally bundle or locate a JRE. Use exe4j when you want:
- A native-looking Windows application launcher with icon, version info, and PID handling.
- Control over JVM arguments, classpath, and bundled JRE selection.
- Customizable wrapper behavior (GUI vs console, single instance, JVM search order).
- Better integration for installers and Windows shortcuts.
Pre-requisites
- A built Java application (JAR file) with a clear main class.
- Windows machine (or a compatible environment) to run exe4j.
- exe4j installer (trial or licensed) downloaded from ej-technologies.
- (Optional) A bundling tool or installer (e.g., Inno Setup, NSIS, or jpackage) if you want to include a JRE or create an installer.
1) Prepare your Java application
- Package your application into a runnable JAR. Ensure your JAR includes a manifest with the Main-Class entry or that you know the fully-qualified main class name.
- Verify the application runs with the desired JVM options:
- Example test: java -Xmx512m -jar myapp.jar
- Collect any dependent libraries (if not packaged into a fat JAR). Decide whether to use a single “fat” JAR (simpler) or a modular classpath.
Tip: Creating an executable JAR (using Maven Shade, Gradle shadow plugin, or similar) reduces classpath complexity for the launcher.
2) Install and open exe4j
- Run the exe4j installer and launch the application.
- You’ll be presented with a project wizard. Each exe4j project describes one EXE launcher.
3) Create a new exe4j project
- Choose a project type: typical choices are “GUI application” (no console window) or “Console application” (shows console).
- Set the EXE filename (e.g., myapp.exe) and the output folder.
- Choose the type of launcher: “Single EXE” vs “Wrapper EXE” options are presented depending on exe4j version — typically you’ll create a simple launcher EXE.
4) Configure application settings
Fill in the main settings screen:
- Main class: enter your app’s main class (e.g., com.example.Main) or point to your executable JAR.
- Classpath: add your application JAR and any library JARs (or a directory). If you use a fat JAR, add only that.
- VM options: add JVM options you want to pass by default (e.g., -Xmx512m, -Dfile.encoding=UTF-8).
- Program arguments: add any fixed program arguments if needed.
- Working directory: set a working directory policy (e.g., EXE directory, installation directory, or current working directory).
5) Configure JRE detection and bundling
One of exe4j’s strengths is flexible JRE handling.
Options typically include:
- Search for an installed JRE on the user’s system using configured search order (registry keys, PATH, JAVA_HOME).
- Specify minimum and maximum required Java versions (e.g., require Java 11+).
- Provide a bundled JRE by pointing to a JRE folder to ship with your app.
- Allow users to download a JRE if missing (you can configure a download URL or show an error).
Recommendations:
- For the best user experience, bundle a JRE matched to your app’s requirements (beware of increased package size).
- Alternatively, require a specific Java version and provide a helpful error message directing users to a download link.
6) Native integration (icons, version info, splash screens)
- Icon: add a .ico file so Windows shows your app icon in Explorer and the taskbar.
- Version information: set product name, company, file version, and product version. This shows in file properties.
- Splash screen: configure an optional splash image or use a lightweight launcher to display an initial splash.
7) Advanced options
- Single-instance: enable single-instance behavior so launching the EXE again focuses the existing instance instead of starting a new one.
- JVM selection: let users choose which JVM to run if multiple are installed.
- Proxy/HTTP settings: pass system properties or configure environment variables if required.
- Environment variables: set or modify env vars before launching the JVM.
- Exit codes: map Java exceptions or error codes to specific Windows exit codes if needed.
8) Build the EXE
- Review all settings in the exe4j project.
- Click “Build” (or equivalent) to generate the EXE. exe4j assembles the native launcher which references your JARs and runtime policy.
- Test the created EXE on the development machine first: double-click it and verify behavior (GUI, console output, JVM options applied).
9) Packaging and distribution
exe4j creates a launcher EXE but doesn’t create an installer unless you use its installer product (install4j) or a separate installer builder. Common distribution strategies:
- Zip the EXE together with a bundled JRE and libs, then provide an installer script.
- Use Inno Setup or NSIS to create a Windows installer that places files in Program Files, creates shortcuts, and registers file associations.
- Consider using jlink/jpackage (from JDK) to create a runtime image with a native installer if you prefer open-source tooling.
Example Inno Setup steps:
- Copy myapp.exe, myapp.jar, libs/, and the bundled JRE into the installer’s files section.
- Create Start Menu and Desktop shortcuts pointing to myapp.exe.
- Optionally set up uninstaller entries and registry keys.
10) Testing on target environments
- Test on clean Windows installs (different Windows versions you intend to support).
- Verify behavior when no JRE is installed and when multiple JREs are present.
- Test with limited permissions (standard user) to ensure installer and launcher work without admin rights, if that’s intended.
- Check for antivirus false positives; sign your EXE with a code-signing certificate to reduce warnings.
11) Troubleshooting common problems
- EXE exits immediately with no output: check JVM search configuration and ensure the correct main class/path is set.
- Wrong JVM version used: tighten the JRE version constraints or bundle a JRE.
- DLL or library load failures: ensure native libraries are placed where the app expects them (use PATH or working directory settings).
- Icon/version not showing: ensure the EXE was rebuilt after icon/version edits; check that icon is a valid .ico with required sizes.
12) Code signing
Code-signing your EXE is strongly recommended to avoid SmartScreen warnings and to build user trust. Use an EV or standard code-signing certificate and sign the EXE after building (and before packaging into an installer).
Example signing command (signtool, Windows SDK):
signtool sign /a /tr http://timestamp.digicert.com /td SHA256 /fd SHA256 myapp.exe
13) Alternatives and complementary tools
- install4j: from the same vendor, provides installers and more advanced launcher features.
- jpackage (JDK): can create platform installers and runtime images.
- Launch4j: open-source alternative to create Windows EXEs.
- jlink: to create minimized Java runtime images.
Comparison (high level)
Feature | exe4j | Launch4j | jpackage |
---|---|---|---|
Native launcher customization | Yes | Limited | Yes |
Bundled JRE support | Yes | Yes | Yes (via runtime image) |
Commercial support | Commercial | Open-source | Part of JDK |
Installer creation | No (use install4j) | No | Yes |
14) Checklist before release
- EXE tested on target Windows versions.
- Proper JRE handling (bundled or clear install instructions).
- Icons, version info, and splash as desired.
- Single-instance and JVM options set.
- EXE code-signed.
- Installer created and tested (if used).
- Antivirus and signing checks passed.
Building a native-looking Windows executable with exe4j is mainly configuration work: point at your JAR, set JVM behavior, decide how to manage the JRE, and build. The launcher gives you control over startup, appearance, and runtime selection without changing your Java bytecode.
Leave a Reply