Windows-EXE-Starter erzeugen
Beim Paketieren können Sie für die geschützte Anwendung einen nativen Windows-Starter erzeugen lassen. Es handelt sich um eine reine Win32-Programmdatei, die sich per Doppelklick starten lässt — Ihre Anwender müssen weder Java installieren noch jemals run.bat zu Gesicht bekommen.
Die EXE ist optional und wird nur auf Anforderung gebaut. Ist sie aktiviert, enthält das Paket weiterhin run.sh, run.command und run.bat. Beide Startwege verwenden exakt dasselbe Archivlayout, denselben Klassenpfad, dieselbe Hauptklasse und dieselben JVM-Startoptionen.
1. Anwendungsbereich
| Anwendungstypen | Java-Anwendung, Spring Boot (alle drei Layouts), Tomcat |
| Zielplattformen | windows-x64, windows-x86, windows-aarch64 |
| Nicht unterstützt | Bibliotheksverschlüsselung — ein einzelnes .p4jx-Archiv ist kein lauffähiges Anwendungsverzeichnis |
Sie müssen mindestens eine Windows-Zielplattform auswählen. Linux- und macOS-Ziele dürfen zusätzlich dabei sein: Diese Pakete entstehen wie gewohnt, nur ohne EXE, und starten über das übliche Skript. Wählen Sie überhaupt kein Windows-Ziel, schlägt die Aufgabe sofort fehl.
2. Vorgehen in der GUI
- Aktivieren Sie auf der Seite mit Eingabedatei und Zielplattformen die Option Windows-Anwendungs-EXE erzeugen (x64/x86/ARM64) und wählen Sie mindestens eine Windows-Zielplattform.
- Das Kontrollkästchen liegt vor der Verzweigung zwischen einfachem und erweitertem Modus, sodass beide Modi eine EXE erzeugen können.
- Nach dem Aktivieren erscheint eine Seite Windows-EXE-Starter, auf der Sie Dateiname, Startermodus, Symbol und Windows-Versionsinformationen eintragen. Ohne Aktivierung geht es direkt zur Abschlussseite.
- Ist die EXE aktiviert, erscheint das Feld JVM-Startoptionen nur noch auf dieser Starterseite, damit dieselbe Option nicht an zwei Stellen eingegeben werden kann. Die Eingaben gelangen sowohl in die EXE als auch in die Startskripte.
- Die Abschlussseite listet die Plattformen auf, die tatsächlich eine EXE erhalten, zusammen mit den ausgefüllten Starterfeldern.
3. CLI-Beispiele
Die kürzeste Form benötigt nur --windows-exe:
p4j --target-platform windows-x64 javaapp app.jar dist --windows-exe
Dateiname und Fenstermodus setzen:
p4j --target-platform windows-x64 javaapp app.jar dist \
--windows-exe \
--exe-name MyApp.exe \
--exe-mode gui \
--exe-icon assets/app.ico
Alle drei Windows-Architekturen auf einmal mit vollständigen Versionsressourcen:
p4j --target-platform windows-x64,windows-x86,windows-aarch64 \
springboot app.jar dist \
--windows-exe \
--exe-name MyService \
--exe-file-version 1.4.2.0 \
--exe-product-version 1.4.2.0 \
--exe-company 'Example Inc.' \
--exe-product 'Example Service' \
--exe-description 'Example background service' \
--exe-copyright 'Copyright (C) 2026 Example Inc.'
Tomcat-Pakete funktionieren ebenfalls; die erzeugte EXE startet den eingebetteten Tomcat im Vordergrund:
p4j --target-platform windows-x64 tomcat app.war dist --context /demo --windows-exe
4. Optionen
| Option | Beschreibung |
|---|---|
--windows-exe | Erzeugt eine Windows-Anwendungs-EXE |
--exe-name <name> | Dateiname der EXE; standardmäßig der Name der Eingabedatei, bei Tomcat-Paketen tomcat |
--exe-mode <mode> | console (Standard) oder gui |
--exe-icon <ico> | Optionales Windows-Symbol im .ico-Format |
--exe-file-version <a.b.c.d> | PE-Dateiversion: ein bis vier Zahlen, jede zwischen 0 und 65535. Leer bedeutet 0.0.0.0 |
--exe-product-version <a.b.c.d> | PE-Produktversion, gleiche Regeln |
--exe-company <text> | Firmenname |
--exe-product <text> | Produktname |
--exe-description <text> | Dateibeschreibung, sichtbar im Task-Manager und in den Dateieigenschaften |
--exe-copyright <text> | Copyright-Hinweis |
Jede --exe-*-Option aktiviert die EXE-Erzeugung von selbst; --windows-exe müssen Sie dann nicht zusätzlich angeben.
Der Name muss ein reiner Dateiname sein, ohne /, \ oder Verzeichnisanteil. Fehlt die Endung .exe, wird sie ergänzt.
Für beide Versionsfelder gilt dieselbe Regel: ein bis vier durch Punkte getrennte Zahlen zwischen 0 und 65535, etwa 1.0.0.1. Windows speichert jeden Teil als vorzeichenlose 16-Bit-Zahl, daher werden Werte mit Buchstaben oder Leerzeichen wie v1.0 oder 1.0-beta abgelehnt. Ein leeres Feld bedeutet 0.0.0.0. Beide Felder werden vor Beginn der Paketierung geprüft, sodass Fehler sofort auffallen und nicht erst mittendrin.
5. Aufbau der Ausgabe
Am Beispiel einer Java-Anwendung liegt die EXE neben den Startskripten im Wurzelverzeichnis des Pakets:
dist/
├── MyApp.exe # der neue Windows-Starter
├── app.p4jx
├── vlxjre/
├── lib/
├── run.sh
├── run.command
├── run.bat
└── README.md
Die README.md im Paket nennt die erzeugten EXE-Dateien und enthält Hinweise zur Codesignatur.
6. Verhalten des Starters
Das Verzeichnis der EXE ist die Wurzel der Anwendung. Der Starter akzeptiert ausschließlich Pfade für Runtime, Archiv, Klassenpfad und Arbeitsverzeichnis innerhalb dieser Wurzel; alles außerhalb des Pakets sowie alles, was über eine symbolische Verknüpfung oder Junction umgeleitet wurde, wird abgelehnt und der Prozess startet nicht. Sie können das gesamte Paket also frei verschieben oder umbenennen, die EXE aber nicht einzeln herauskopieren.
| Aspekt | Verhalten |
|---|---|
| Runtime | Verwendet immer vlxjre\bin\java.exe aus dem Paket. Nie das System-Java, und JAVA_HOME wird nicht gelesen. |
| Kommandozeilenargumente | An die EXE übergebene Argumente werden hinter die eigenen Argumente der Anwendung gehängt. |
| Konsolenmodus | Übernimmt Standardein- und -ausgabe der aktuellen Konsole, wartet auf das Ende der Anwendung und gibt deren Exit-Code zurück. |
| GUI-Modus | Erzeugt kein Konsolenfenster, passend für Desktop-Anwendungen. |
| Umgebungsvariablen | Löscht vor dem Start JAVA_TOOL_OPTIONS, _JAVA_OPTIONS, JDK_JAVA_OPTIONS und CLASSPATH, damit von außen keine Startoptionen eingeschleust werden können. |
Die JVM-Optionen der EXE werden beim Paketieren festgeschrieben, gemeinsam mit dem Parameterblock signiert und zur Laufzeit geprüft; nach der Auslieferung lassen sie sich nicht mehr ändern. APP_JAVA_OPTS wirkt nur auf run.bat — die EXE liest es nicht. Um die JVM-Optionen der EXE zu ändern, paketieren Sie erneut.
Aus demselben Grund lassen sich -javaagent, -agentlib, -agentpath, -Xbootclasspath und --patch-module nicht in die Startoptionen der EXE schreiben. Werden sie über --jvm-option übergeben, schlägt der Paketierungslauf sofort fehl.
7. Codesignatur
Protector4J signiert die erzeugte EXE nicht und greift auf keinerlei Authenticode-Anmeldedaten zu. Alle PE-Änderungen — Symbol, Versionsressourcen und Startoptionen — geschehen während der Paketierung, deshalb muss die Signatur zuletzt erfolgen.
- Schließen Sie die Paketierung ab und stellen Sie sicher, dass die EXE die Anwendung korrekt startet.
- Signieren Sie mit Ihrem eigenen Zertifikat per Authenticode, inklusive RFC3161-Zeitstempel.
- Prüfen Sie die Signatur unter der Windows-Richtlinie
/pa.
Ändern Sie die PE-Datei nach dem Signieren nicht mehr — jede Änderung macht die Signatur ungültig. Für ein neues Symbol oder eine neue Versionsnummer paketieren und signieren Sie erneut.
8. Felder der Aufgabendatei
Die exportierte p4j-task.yml verwendet Formatversion 2 und speichert bei aktivierter EXE die folgenden Felder. Aufgabendateien der Version 1 lassen sich weiterhin lesen.
windowsExe: true
exeName: MyApp.exe
exeMode: console
exeIcon: assets/app.ico
exeFileVersion: 1.4.2.0
exeProductVersion: 1.4.2.0
exeCompany: Example Inc.
exeProduct: Example Service
exeDescription: Example background service
exeCopyright: Copyright (C) 2026 Example Inc.
9. Fehlerbehebung
| Symptom | Ursache und Abhilfe |
|---|---|
| Meldung, dass eine Windows-Zielplattform nötig ist | Die EXE ist aktiviert, aber weder windows-x64 noch windows-x86 oder windows-aarch64 wurde gewählt. |
| Meldung über ein ungültiges Versionsformat | Ein Versionsfeld enthält Buchstaben oder Leerzeichen, hat mehr als vier Teile, oder ein Teil liegt außerhalb von 0–65535. |
| Meldung, dass der EXE-Name nur ein Dateiname sein darf | Der Name enthält ein Pfadtrennzeichen. Verwenden Sie einen Namen ohne Verzeichnis. |
| Meldung, dass die Symboldatei fehlt | --exe-icon verweist auf eine nicht vorhandene .ico. Prüfen Sie den Pfad. |
| Nach dem Doppelklick erscheint kein Fenster, die Anwendung endet sofort | Die Anwendung scheitert im GUI-Modus beim Start. Paketieren Sie im Konsolenmodus neu, um die Fehlerausgabe zu sehen. |
| Eine einzeln kopierte EXE läuft nicht | Der Starter benötigt Runtime und Archiv im selben Paketverzeichnis. Kopieren Sie das gesamte Ausgabeverzeichnis. |
Die vollständige Optionsliste finden Sie in der CLI-Referenz; den GUI-Assistenten beschreibt der GUI-Leitfaden.