TL;DR

Eine Anwendung über

java -jar

im Terminal zu starten funktioniert zwar, ist aber nicht besonders elegant. Wer wissen möchte wie man eine Spring Boot Anwendung für Windows als .exe paketiert, sollte weiterlesen.

Alternativ gibt es hier auch das passende Beispielprojekt: Bitbucket

Launch4j

In meinem letzten Artikel habe ich euch gezeigt, wie ihr mit Spring Boot sehr einfach eine Kommandozeilenanwendung erstellen könnt. Am Ende des Artikels konnten wir unsere Anwendung mit dem folgenden Befehl ausführen:

java -jar spring-boot-shell.jar

Um das Starten der Anwendung für die späteren Nutzer etwas komfortabler zu machen, wäre es natürlich besser wenn man diese einfach per Doppelklick starten könnte.

Um aus unserer ausführbaren JAR eine Windows Executable zu generieren, gibt es das Projekt Launch4j. Das Ziel dieses Projekts ist es, Java Anwendungen so zu verpacken, dass sie wie native Windows Anwendungen ausgeführt werden können. Natürlich muss die Java Runtime trotzdem installiert sein, damit die Anwendung funktioniert.

Die Einbindung in unser Projekt ist denkbar einfach, da es für Launch4j auch ein Maven Plugin gibt. Dieses müssen wir nur noch in unserem Projekt konfigurieren.

<plugin>
    <groupId>com.akathist.maven.plugins.launch4j</groupId>
    <artifactId>launch4j-maven-plugin</artifactId>
    <version>1.7.25</version>
    ...
</plugin>

Execution

Damit das Plugin während des Builds auch ausgeführt wird, müssen wir eine Execution definieren. Ich habe hierfür die Phase package des Builds gewählt, da das Spring Boot Plugin hier die JAR erzeugt, welche wir dann verpacken wollen. Als Goal muss immer launch4j verwendet werden.

<plugin>
    ...
    <executions>
        <execution>
            <id>build-windows-executable</id>
            <phase>package</phase>
            <goals>
                <goal>launch4j</goal>
            </goals>
        </execution>
    </executions>
    ...
</plugin>

Konfiguration

Launch4J bietet eine ganze Reihe an Einstellungsmöglichkeiten, welche direkt im Plugin konfiguriert werden können. Ich will hier nur kurz auf die Wichtigsten für unser Beispiel eingehen. Eine Dokumentation aller verfügbaren Optionen findet ihr hier: Launch4j Dokumentation

<plugin>
    ...
    <configuration>
        <headerType>console</headerType>
        <outfile>${project.build.directory}/${artifactId}.exe</outfile>
        <jar>${project.build.directory}/${artifactId}-${project.version}.jar</jar>
        <errTitle>${artifactId}</errTitle>
        <classPath>
            <mainClass>org.springframework.boot.loader.JarLauncher</mainClass>
            <addDependencies>false</addDependencies>
            <preCp>anything</preCp>
        </classPath>
        <jre>
            <minVersion>1.8.0</minVersion>
        </jre>
        <versionInfo>
            <fileVersion>${version}.0</fileVersion>
            <txtFileVersion>${version}.0</txtFileVersion>
            <fileDescription>a description</fileDescription>
            <copyright>Pragtics 2019</copyright>
            <productVersion>${version}.0</productVersion>
            <txtProductVersion>${version}.0</txtProductVersion>
            <productName>${artifactId}</productName>
            <internalName>${artifactId}</internalName>
            <originalFilename>${artifactId}.exe</originalFilename>
        </versionInfo>
    </configuration>
</plugin>

Mit der Option outfile geben wir den Pfad an, an dem unsere Executable erzeugt werden soll. Normalerweise sollte dieser sich auch im target Ordner unseres Projekts befinden.

Natürlich müssen wir Launch4j auch noch sagen welche Java Anwendung wir gerne verpacken möchten. Dafür müssen wir in der Eigenschaft jar den Pfad zu unserer JAR angeben. Im Normalfall sollte ${project.build.directory}/${artifactId}-${project.version}.jar hier funktionieren.

Wichtig, als

mainClass

dürfen wir nicht unsere eigene Main Klasse eintragen. Hier muss die Klasse

org.springframework.boot.loader.JarLauncher 

verwendet werden. Spring Boot sorgt dann dafür, dass unsere Main Klasse ausgeführt wird.

Unter versionInfo können wir noch ein paar Metainformationen angeben, welche nachher in der Executable wiederzufinden sind. Dabei müssen wir darauf achten, dass die Versionsnummer unter Windows immer vierstellig sein muss.

Damit ist die Konfiguration schon erledigt. Wenn wir jetzt mvn package ausführen, erhalten wir im Ausgabeverzeichnis eine .exe Datei, welche wir einfach mit einem Doppelklick ausführen können.

Ein funktionierendes Beispielprojekt, mit dem gezeigten Beispiel, findet ihr hier: Bitbucket