Creating a Windows Executable from a Jar using Maven
August 7th, 2012 by Micha KopsOften in the life of a developer there is the need to create a windows executable for a Java application that is build and packaged in a Jar file.
The following short example shows how to create an executable Jar first and a windows executable containing vendor information, a nice icon and other stuff afterwards by using a combination of the Maven Shade Plugin and the launch4j Plugin for Maven.
The Application
We’re building a simple swing application here and we’re just rendering a JColorChooser in a JDialog.
And that’s the code ..
package com.hascode.tutorial; import javax.swing.JColorChooser; import javax.swing.JDialog; public class Main extends JDialog { private static final long serialVersionUID = 1L; private final JColorChooser cc; public Main() { setSize(800, 600); setTitle("hasCode.com launch4j Maven Tutorial"); cc = new JColorChooser(); add(cc); setDefaultCloseOperation(DISPOSE_ON_CLOSE); setVisible(true); } public static void main(final String[] args) { new Main(); } }
Configuring Maven
We’re using a combination of the Maven shade plugin and a specific variant of the Launch4j Maven Plugin (there are different implementations available) here. Alternatively you could replace the maven shade plugin with the Maven Assembly Plugin but I’m using the first one here I somehow like this one.
The Shade plugin assembles all dependencies into a runnable jar – the transformer adds the Main-Class header to the MANIFEST.MF.
The configuration of the Launch4j maven plugin should be self-explanatory.
For the look I’ve added an application icon in src/main/resources.
My final pom.xml looks like this one:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.hascode.tutorial</groupId> <artifactId>launch4j-maven-sample</artifactId> <version>0.0.1</version> <name>hasCode Launch4j Maven Example</name> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>2.5.1</version> <configuration> <source>1.6</source> <target>1.6</target> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>1.7.1</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> </execution> </executions> <configuration> <shadedArtifactAttached>true</shadedArtifactAttached> <shadedClassifierName>shaded</shadedClassifierName> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>com.hascode.tutorial.Main</mainClass> </transformer> </transformers> </configuration> </plugin> <plugin> <groupId>com.akathist.maven.plugins.launch4j</groupId> <artifactId>launch4j-maven-plugin</artifactId> <version>1.5.1</version> <executions> <execution> <id>l4j-clui</id> <phase>package</phase> <goals> <goal>launch4j</goal> </goals> <configuration> <headerType>gui</headerType> <jar>${project.build.directory}/${artifactId}-${version}-shaded.jar</jar> <outfile>${project.build.directory}/hasCode.exe</outfile> <downloadUrl>http://java.com/download</downloadUrl> <classPath> <mainClass>com.hascode.tutorial.Main</mainClass> <preCp>anything</preCp> </classPath> <icon>src/main/resources/icon/application.ico</icon> <jre> <minVersion>1.6.0</minVersion> <jdkPreference>preferJre</jdkPreference> </jre> <versionInfo> <fileVersion>1.0.0.0</fileVersion> <txtFileVersion>${project.version}</txtFileVersion> <fileDescription>${project.name}</fileDescription> <copyright>2012 hasCode.com</copyright> <productVersion>1.0.0.0</productVersion> <txtProductVersion>1.0.0.0</txtProductVersion> <productName>${project.name}</productName> <companyName>hasCode.com</companyName> <internalName>hasCode</internalName> <originalFilename>hasCode.exe</originalFilename> </versionInfo> </configuration> </execution> </executions> </plugin> </plugins> </build> </project>
Building
Just run mvn package and you should get the desired hasCode.exe in your target directory. Trying to run the executable on a windows system could look like that:
Debugging Log4j
It is easy to debug your final application – just start it with the parameter “–l4j-debug” and in the same directory where the exe is located there should appear a file named launch4j.log containing some more or less useful information like this:
CmdLine: C:\Documents and Settings\User\Desktop\hasCode.exe --l4j-debug WOW64: no Check launcher: (n/a) 64-bit search: SOFTWARE\JavaSoft\Java Runtime Environment... 32-bit search: SOFTWARE\JavaSoft\Java Runtime Environment... Match: SOFTWARE\JavaSoft\Java Runtime Environment\1.6 Match: SOFTWARE\JavaSoft\Java Runtime Environment\1.6.0_33 64-bit search: SOFTWARE\JavaSoft\Java Development Kit... 32-bit search: SOFTWARE\JavaSoft\Java Development Kit... Check launcher: C:\Program Files\Java\jre6\bin\javaw.exe (OK) Heap -Xms: 128 MB / 0%, Free: 211 MB, Heap size: 128 MB Heap -Xmx: 1024 MB / 0%, Free: 211 MB, Heap size: 1024 MB
Tutorial Sources
Please feel free to to view and download the complete sources from this tutorial from my Bitbucket repository – or if you’ve got Mercurial installed just check it out with
hg clone https://bitbucket.org/hascode/launch4j-maven-example
Resources
xsi:schemaLocation=”http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd”>
<modelVersion>4.0.0</modelVersion>
<groupId>com.hascode.tutorial</groupId>
<artifactId>launch4j-maven-sample</artifactId>
<version>0.0.1</version>
<name>hasCode Launch4j Maven Example</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.7.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
<configuration>
<shadedArtifactAttached>true</shadedArtifactAttached>
<shadedClassifierName>shaded</shadedClassifierName>
<transformers>
<transformer
implementation=”org.apache.maven.plugins.shade.resource.ManifestResourceTransformer”>
<mainClass>com.hascode.tutorial.Main</mainClass>
</transformer>
</transformers>
</configuration>
</plugin>
<plugin>
<groupId>com.akathist.maven.plugins.launch4j</groupId>
<artifactId>launch4j-maven-plugin</artifactId>
<version>1.5.1</version>
<executions>
<execution>
<id>l4j-clui</id>
<phase>package</phase>
<goals>
<goal>launch4j</goal>
</goals>
<configuration>
<headerType>gui</headerType>
<jar>${project.build.directory}/${artifactId}-${version}-shaded.jar</jar>
<outfile>${project.build.directory}/hasCode.exe</outfile>
<downloadUrl>http://java.com/download</downloadUrl>
<classPath>
<mainClass>com.hascode.tutorial.Main</mainClass>
<preCp>anything</preCp>
</classPath>
<icon>src/main/resources/icon/application.ico</icon>
<jre>
<minVersion>1.6.0</minVersion>
<jdkPreference>preferJre</jdkPreference>
</jre>
<versionInfo>
<fileVersion>1.0.0.0</fileVersion>
<txtFileVersion>${project.version}</txtFileVersion>
<fileDescription>${project.name}</fileDescription>
<copyright>2012 hasCode.com</copyright>
<productVersion>1.0.0.0</productVersion>
<txtProductVersion>1.0.0.0</txtProductVersion>
<productName>${project.name}</productName>
<companyName>hasCode.com</companyName>
<internalName>hasCode</internalName>
<originalFilename>hasCode.exe</originalFilename>
</versionInfo>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Tags: assembly, Build, exe, Java, launch4j, maven, plugin, shade, swing, windows
December 12th, 2012 at 1:25 pm
Hey,
this is a good article. I would like to save it as a PDF or to print it out. But it’s not possible because your blog is not printerfriendly :-( . Could you provide the article as a pdf?
Regards,
Simon
December 12th, 2012 at 9:31 pm
You’re right .. the print layout is even uglier than the normal web layout.
I’ve added some basic print styles for a more or less slightly improved print layout ;)
December 17th, 2012 at 7:36 pm
Thanks man, that’s very useful!
April 19th, 2015 at 10:42 am
[...] EXE-Datei in den Build-Prozess zu integrieren. Das Vorgehen wird unter launch4j-maven-plugin und hasCode.com gut erläutert. Für die Applikation konzepte-admin sieht der Eintrag in der POM wie folgt [...]