Export eines Java-Programms als MacOS Applicaion-Bundle, Disk-Image oder Installations-Package

Unter MacOS kann ein als *.jar gepacktes lauffähiges Java-Programm durch Doppelklick gestartet werden. In vielen Fällen ist es jedoch erwünscht oder sogar notwendig1, eine Java-Anwendung als MaOS-Application-Bundle (*.app), als Disk-Image (*.dmg) oder als Installations-Package (*.pkg) zu exportieren.
Ausgangspunkt des Exports ist immer ein lauffähiges JAR, das entweder selbst erstellt oder etwa aus der IDE Eclipse direkt exportiert werden kann. Hierzu werden im Package Explorer ein Rechtsklick auf das Projekt ausgeführt und dann Export... → Java → Runnable JAR file gewählt.

jpackage

Das Erstellen eines der erwähnten MacOS-Archive erfolgt auf der Kommandozeile mit Hilfe des Programms jpackage. Es befindet sich im JDK-Verzeichnis unter Contents/Home/bin/ und bietet zwar keine Man-Page, aber eine Hilfe, die mit jpackage --help aufgerufen werden kann. Sie enthält ausführliche Hinweise und Beispiele.
Die hier gezeigten Verfahren beziehen sich auf nichtmodulare Anwendungen, deren *.class-Dateien in einem einzelnen JAR gepackt sind. Für darüber hinaus gehende Anwendungen sei auf jpackage --help verwiesen.

Herstellen eines Application-Bundles

Wird ein Application-Bundle aus einem JAR erstellt, müssen die zu packenden Ressourcen in einem anderen Verzeichnis als dem Zielverzeichnis liegen, in dem das fertige Bundle abgelegt wird. Wird dies nicht beachtet, kann es sonst während des Packens zu Rekursionen kommen. Man erhält dann die Fehlermeldung 'File name too long'. Das Quellverzeichnis kann jedoch als Unterverzeichnis innerhalb des Zielverzeichnisses liegen. Wird kein gesondertes Zielverzeichnis spezifiziert, wird das aktuelle Arbeitsverzeichnis als solches verwendet. Das Quellverzeichnis muss in jedem Falle angegeben werden und das lauffähige JAR und bei Bedarf eine Icon-Datei enthalten.

Zur Erzeugung des Bundeles wechselt man am einfachsten in das Zielverzeichnis:

cd <zielverzeichnis>

Der folgende Aufruf erzeugt dann ein Bundle mit dem Bezeichner MyApp.app (In <> gesetzte Angaben sind entsprechend zu ersetzen):

/Library/Java/JavaVirtualMachines/jdk-17.0.1.jdk/Contents/Home/bin/jpackage \
--input <quellverzeichnis> \
--dest <zielverzeichnis> \
--name <MyApp> \
--app-version 1.0.0 \
--main-jar <MyJar.jar> \
--main-class <package.MyMainClass> \
--type app-image \
--icon <quellverzeichnis/MyIcon.icns> \
--vendor <Herausgeber> \
--verbose

Die Einträge sind wie folgt zu verstehen:

  1. Pfad zu jpackage, hier absolut angegeben
  2. Quellverzeichnis mit den Programmresourcen
  3. Zielverzeichnis, wenn nicht angegeben, wird das aktuelle Arbeitsverzeichnis verwendet
  4. Name des zu erstellenden Bundles ohne Extension
  5. Versionsnummer, darf nicht mit 0 beginnen
  6. JAR mit Extension, in der sich die Klasse mit main() befindet
  7. Name der Klasse mit main() ohne Extension
  8. Zieltyp, app-image, dmg oder pkg Wenn nicht spezifiziert wird ein OS-abhängiger Standardtyp erstellt.
  9. Pfad zur Icon-Datei. Sie muss vom Typ *.icns sein.
  10. Anbieter des Bundles
  11. Kommentierte Konsolen-Ausgabe

Herstellen eines Disk-Images oder Installations-Packages

Die Herstellung eines Disk-Images und eines Installations-Packages verläuft genau so wie diejenige des Application-Bundles. Allerdings müssen die --type-Angaben angepasst werden:

--type dmg    # Diskimage
--type pkg    # Installations-Package

Zudem können Quell- und Zielverzeichnis nach meinen Erfahrungen hierbei identisch sein.

1) Ein Dock-Icon kann z.B. nur bei Ausführen eines Application-Bundles eine Badge erhalten.

Wenn Ihnen javabeginners.de gefällt, freue ich mich über eine Spende an diese gemeinnützigen Organisationen.