根据 Jar 文件直接创建 Windows 的可执行程序(Creating a Windows Executable from a Jar using Maven)

桌面软件开发 William 309浏览 0评论

Often 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.

Simple Swing Application

Simple Swing Application

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();
 }
 
}

程序员经常被要求将一个 Java 应用程序打包成 Windows 下的可执行程序。下面这个简单的实例就是演示如何创建一个包含开发商信息的 Windows 可执行程序,并包含一个不错的图标。这里需要用到 Maven Shade 插件和 Maven 的 Launch4j 插件。

编写一个简单的 Java GUI 应用

我们创建了一个简单的 swing 应用,如下图所示:

Simple Swing Application

相应的代码如下:

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 theMANIFEST.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>

配置 Maven

这里我们需要使用 Maven 的两个插件:Maven shade plugin 和一个 Launch4j Maven Plugin 的变种,你也可以使用 Maven Assembly Plugin 来替代 Maven Shade plugin,但我喜欢后者。

Shade 插件将所有依赖的文件打包到一个单独可运行的 jar 文件,转换器会在 MANIFEST.MF 中增加 Main-Class 属性。

而 Launch4j Maven Plugin 插件的配置不言自明。

我们将应用图标放在 src/main/resources 目录下.

最终的 pom.xml 内容如下:

<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:

Running the executable on a windows system

Running the executable on a windows system

Debugging Log4j

It is easy to debug your final application – just start it with the parameter “–l4j-debug” and in the same directory where theexe 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

构建

现在只需要运行 mvn package 就可以在 target 目录中获得一个名为 hasCode.exe 的可执行文件,可直接双击运行,运行结果如下:

Running the executable on a windows system

调试 Log4j

应用的调试很简单,只需要启动时增加参数 “–l4j-debug” 然后在 exe 文件的相同目录就会生成一个名为 launch4j.log 的文件,该文件将包含一些有用的调试信息,形如:

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

我将这些源码都放在 Bitbucket repository 上,你可通过 Mercurial 来获取:

hg clone https://bitbucket.org/hascode/launch4j-maven-example

via:oschina

转载请注明:AspxHtml学习分享网 » 根据 Jar 文件直接创建 Windows 的可执行程序(Creating a Windows Executable from a Jar using Maven)

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址