Packaging a Java app for Mac with Maven
Recently I had the task to prepare a Java app for deployment on MacOS. The project setup was based on Maven and so the packaging step should be integrated in the Maven build process. There were only old and outdated tutorials with lots of manual work out there. Luckily I found a Maven plugin on GitHub, which simplifies this task a lot: https://github.com/federkasten/appbundle-maven-plugin. It supports a lot of configuration options for packaging a Java app and creates a DMG for you. But be careful, the creation of a DMG only works on a Mac.
Basic usage
Insert the following into your build plugins section, customize your main class name and you’re good to go.
<plugin>
<groupId>sh.tak.appbundler</groupId>
<artifactId>appbundle-maven-plugin</artifactId>
<version>1.2.0</version>
<configuration>
<mainClass>HelloWorld</mainClass>
<generateDiskImageFile>true</generateDiskImageFile>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>bundle</goal>
</goals>
</execution>
</executions>
</plugin>
Run clean package appbundle:bundle
and after the build finishes you find a DMG in the target
folder.
Set icon file and disk name
To set the icon file and the name of the DMG, add this to the <configuration>
section:
<bundleName>Hello World</bundleName>
<iconFile>HelloWorld.icns</iconFile>
The icon file requires the .icns format. I used https://iconverticons.com/online/ to generate my icon. You have to add it to src/main/resources
because the specified <iconFile>
is loaded from this path.
Hint: The <bundleName>
is the name of the disk and not the app name! To set an app name you must add <finalName>AppName</finalName>
to your <build>
section.
Deliver additional files
If you want to deliver additional files with your app which are not packaged into your JAR, add the following to the <configuration>
section:
<workingDirectory>$APP_ROOT/../</workingDirectory>
<additionalResources>
<fileSet>
<directory>${project.basedir}</directory>
<includes>
<include>*.txt</include>
</includes>
</fileSet>
</additionalResources>
This snippet selects all .txt files in ${project.basedir}
and adds them to the DMG. <workingDirectory>
adjusts the working directory of your Java app so you can access the delivered files from within your application as if your app would be a normal JAR without changing file paths in your Java code.
Deliver additional classpath resources
You can deliver classpath ressources for your app, too. These can be e. g. external libs, which are not included in your JAR. Simply add these resources to a folder in your project directory, e. g. dist/libs
and include the following:
<additionalClasspath>:$APP_ROOT/../libs/</additionalClasspath>
<additionalResources>
<fileSet>
<directory>${project.basedir}/dist</directory>
</fileSet>
</additionalResources>
Via <additionalClasspath>
you can add classpath resources for your app. Hint: Classpathes are separated by a :
at the beginning of each referenced directory or JAR file!
I hope you can use some of my code examples for delivering your next Java app for Mac!