Windows exe z Launch4j

Tworząc aplikację desktopową za pomocą Javy chciałbyś mieć możliwość utworzenie pliku exe dla systemu Windows. Tak aby twoja aplikacja mogła być uruchamiana wprost bez żadnych magicznych plików batchowych. Fajnie aby wykrywała obecność JRE i kierowała do odpowiedniej witryny celem pobrania środowiska uruchomieniowego.

Takie możliwości stwarza projekt Launch4j, który opakowuje archiwum jar w plik wykonywalny exe. Dodatkowo za pomocą wtyczki dla Mavena można całą konfigurację umieścić w jednym pliku projektu - pom.xml.

W poniższym wpisie omówię krótko jak przygotować prosty projekt javowy z dodaną opcją opakowywania. Niestety oryginalny kod wtyczki zawierał pewne błędy, jednak dzięki licencji GPL mogłem zforkować (wydzielić, oddzielić, … ?) cały kod do swojego repozytorium na GitHubie. Druga sprawa, to artefakty Mavena są dostępne na Nexusie firmy SoftwareMill, aby nie trzeba ba było samemu ich budować lokalnie i instalować.

Do dzieła!

Potrzebne: linia komend, Maven 3.x, IDE wspierające Mavena

Projekt Mavena - to jest najprostsza rzecz, wystarcz użyć wtyczki Archetype do wygenerowania najprostszego projektu

mvn archetype:generate

zostanie wyświetlona bardzo długa lista dostępnych archetypów, jednak na moje potrzeby wystarczy domyślnie wybrana opcja 106 - maven-archetype-quickstart (An archetype which contains a sample Maven project.)

Choose a number: 106:
Choose version:
1: 1.0-alpha-1
2: 1.0-alpha-2
3: 1.0-alpha-3
4: 1.0-alpha-4
5: 1.0
6: 1.1
Choose a number: 6: 
Define value for property 'groupId': : pl.org.lenart.launch4j
Define value for property 'artifactId': : launch4j-demo
Define value for property 'version':  1.0-SNAPSHOT: : 
Define value for property 'package':  pl.org.lenart.launch4j: : 
Confirm properties configuration:
groupId: pl.org.lenart.launch4j
artifactId: launch4j-demo
version: 1.0-SNAPSHOT
package: pl.org.lenart.launch4j
 Y: :

I mam gotowy prosty projekt, który posłuży mi jako przykład. Otwieram pom.xml w IDE - w moim przypadku jest IntelliJ IDEA, która nie potrzebuje żadnych dodatkowych czynności, aby otworzyć projekt mavenowy - wybieram plik pom.xml i to wszystko. Np. w przypadku Eclipse IDE należy cześniej z linii komend wykonać

mvn eclipse:eclipse

aby wygenerować projekt Eclipse'a, który następnie można otworzyć za pomocą Eclipse IDE.

Otwarcie projektu

W raz z projektem tworzona jest przykładowa klasa App. Poniżej jest zmodyfikowany kod klasy, który wyświetla proste okno dialogowe, celem stwierdzenia, że wersja opakowana to jest ta sama aplikacja.

package pl.org.lenart.launch4j;
 
import javax.swing.*;
import java.awt.*;
 
public class App extends JFrame {
 
    public static void main(String[] args) {
        App app = new App();
        app.sayHello();
    }
 
    public App() throws HeadlessException {
        setVisible(false);
    }
 
    private void sayHello() {
        JOptionPane.showMessageDialog(this, "Hello world!", "Hello", JOptionPane.INFORMATION_MESSAGE);
        dispose();
    }
 
}

Uruchomienie powyższej aplikacji skutkje ładnym komunikatem

Komunikat

Następny krok to dodanie wtyczki Launch4j i repozytorium.

Wtyczkę i jej konfigurację umieszczę w profilu, bo do codziennej pracy nie jest mi potrzebne opakowywanie archiwum jar do pliku exe. A więc profil idealnie się do tego nadaje. Taka mała uwaga co do profili w Maven 3 - jeśli w trakcie wywołania mavena podamy profil, profil domyślny nie zostanie włączony do cyklu budowania. Jest to znacząca zmiana od wersji 2.

Umieszczenie repozytorium w profilu przyspieszy proces budowania aplikacji, gdyż jedynie przy aktywnym profilu, Maven będzie przeszukiwał podane repozytorium wtyczek.

    <profiles>
        <profile>
            <id>winexe</id>
            <build>
                <plugins>
                    <plugin>
                        <groupId>com.akathist.maven.plugins.launch4j</groupId>
                        <artifactId>launch4j-maven-plugin</artifactId>
                        <version>1.4</version>
                    </plugin>
                </plugins>
            </build>
            <pluginRepositories>
                <pluginRepository>
                    <id>softwaremill-public</id>
                    <name>SoftwareMill Public Reposityr</name>
                    <url>http://tools.softwaremill.pl/nexus/content/groups/public/</url>
                </pluginRepository>
            </pluginRepositories>
        </profile>
    </profiles>

Kolejny krok to podanie w jakiej fazie wtyczka ma zostać uruchomiona, w tym przypadku najlepsza jest faza pakowania całego projektu do pliku jar, a więc wystarczy dodać poniższy fragment, aby otrzymać porządane zachowanie

    <executions>
        <execution>
            <id>l4j-clui</id>
            <phase>package</phase>
            <goals>
                <goal>launch4j</goal>
            </goals>
        </execution>
    </executions>

Ostatni krok to dodanie konfiguracji samej wtyczki

	<configuration>
		<headerType>gui</headerType>
		<jar>${project.build.directory}/${project.artifactId}-${project.version}.jar</jar>
		<outfile>${project.build.directory}/app.exe</outfile>
		<downloadUrl>http://java.com/download</downloadUrl>
		<classPath>
			<mainClass>pl.org.lenart.launch4j.App</mainClass>
			<preCp>anything</preCp>
		</classPath>
		<jre>
			<minVersion>1.6.0</minVersion>
			<jdkPreference>preferJre</jdkPreference>
		</jre>
		<versionInfo>
			<fileVersion>1.0.0.0</fileVersion>
			<txtFileVersion>${project.version}</txtFileVersion>
			<fileDescription>Launch4j Demo App</fileDescription>
			<copyright>Lukasz Lenart</copyright>
			<productVersion>1.0.0.0</productVersion>
			<txtProductVersion>1.0.0.0</txtProductVersion>
			<productName>App</productName>
			<companyName>Lukasz Lenart</companyName>
			<internalName>app</internalName>
			<originalFilename>app.exe</originalFilename>
		</versionInfo>
	</configuration>

To jest tylko część parametrów jakie można podać, opis pozostałych znajduje się na stronie projektu Launch4j. Najważniejsze jest podanie głównej klasy, która ma zostać uruchomiona przez launch4j

<mainClass>pl.org.lenart.launch4j.App</mainClass>

I w sumie gotowe, pozostaje przetestować wszystko, a więc wyołuję komendę

mvn clean install

i czekam na wynik ….

[INFO] 
[INFO] --- maven-jar-plugin:2.3.1:jar (default-jar) @ launch4j-demo ---
[INFO] Building jar: /Users/lukaszlenart/Projects/launch4j-demo/target/launch4j-demo-1.0-SNAPSHOT.jar
[INFO] 
[INFO] --- maven-install-plugin:2.3.1:install (default-install) @ launch4j-demo ---
[INFO] Installing /Users/lukaszlenart/Projects/launch4j-demo/target/launch4j-demo-1.0-SNAPSHOT.jar to /Users/lukaszlenart/.m2/repository/pl/org/lenart/launch4j/launch4j-demo/1.0-SNAPSHOT/launch4j-demo-1.0-SNAPSHOT.jar
[INFO] Installing /Users/lukaszlenart/Projects/launch4j-demo/pom.xml to /Users/lukaszlenart/.m2/repository/pl/org/lenart/launch4j/launch4j-demo/1.0-SNAPSHOT/launch4j-demo-1.0-SNAPSHOT.pom
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4.900s
[INFO] Finished at: Mon May 02 09:26:12 CEST 2011
[INFO] Final Memory: 9M/81M
[INFO] ------------------------------------------------------------------------

Jak widać, sam projekt buduje się bez problemów, jednak było to uruchomienie bez opakowywania do pliku exe - pasuje sprawdzić i ten element. Dodaję nazwę profilu do wywołania i czekam na wynik.

mvn clean install -Pwinexe

Tym razem można zauważyć, że została aktywowana wtyczka launch4j

[INFO] 
[INFO] --- maven-jar-plugin:2.3.1:jar (default-jar) @ launch4j-demo ---
[INFO] Building jar: /Users/lukaszlenart/Projects/launch4j-demo/target/launch4j-demo-1.0-SNAPSHOT.jar
[INFO] 
[INFO] --- launch4j-maven-plugin:1.4:launch4j (l4j-clui) @ launch4j-demo ---
[INFO] Platform-specific work directory already exists: /Users/lukaszlenart/.m2/repository/com/akathist/maven/plugins/launch4j/launch4j-maven-plugin/1.4
[INFO] launch4j: Compiling resources
[INFO] launch4j: Linking
[INFO] launch4j: Wrapping
[INFO] launch4j: Successfully created /Users/lukaszlenart/Projects/launch4j-demo/target/app.exe
[INFO] 
[INFO] --- maven-install-plugin:2.3.1:install (default-install) @ launch4j-demo ---
[INFO] Installing /Users/lukaszlenart/Projects/launch4j-demo/target/launch4j-demo-1.0-SNAPSHOT.jar to /Users/lukaszlenart/.m2/repository/pl/org/lenart/launch4j/launch4j-demo/1.0-SNAPSHOT/launch4j-demo-1.0-SNAPSHOT.jar
[INFO] Installing /Users/lukaszlenart/Projects/launch4j-demo/pom.xml to /Users/lukaszlenart/.m2/repository/pl/org/lenart/launch4j/launch4j-demo/1.0-SNAPSHOT/launch4j-demo-1.0-SNAPSHOT.pom
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 16.539s
[INFO] Finished at: Mon May 02 09:31:43 CEST 2011
[INFO] Final Memory: 10M/81M
[INFO] ------------------------------------------------------------------------

Najlepsze w tym rozwiązamu jest to, że cały proces budowania i opakowywania przeprowadziłem na swoim MacBook Pro - pozostaje przetestować gotowy pliki exe na systemie Windows. A do tego wykorzystam VirtualBox.

Uruchomienie na Windows

Jak widać wszystko ładnie działa, pasuje dodać jeszcze ikonkę i inne ozdobniki. Nawet właściwości zostały dodane, tak jak były podane w konfiguracji wtyczki.

Właściwości pliku exe

Cały projekt jest dostępny w repozytorium na GitHubie.

article/windows-exe-z-launch4j.txt · Last modified: 2011-05-02 10:04 by Lukasz Lenart
 
Except where otherwise noted, content on this wiki is licensed under the following license: CC Attribution-Noncommercial-Share Alike 3.0 Unported
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki