/ macOS

Packaging a .jar as .app file for macOS

When you write a Java application, you'll get a .jar file in the end. If you launch this file on a mac, you'll end up having the default java icon in the Dock (depending on the application) and you are unable to save the application in the Dock. It just doesn't feel right.

To solve this, you can either try to read oracle's documentation and end up using broken search fields, navigating dead links and outdated stuff until you lay crying in the corner. Or you can just use a Maven plugin which does the work for you.

Possible limitations

I read somewhere that you can't use the com.apple.eawt package with this type of app, but it looks fine to me.
For anyone interested, the com.apple.eawt package is a set of Java extensions for macOS specific applications like handlers for the "Preferences" shortcut and the menubar. Apple dropped support for this in Java 1.6 (as they stopped developing thier own Java version due to security concerns) but there exists a community maintained package which can be used for builds on non-Apple OSes (Java for Mac still contains this package).

The Maven Plugin

You can use the Maven plugin like this:

 <plugin>
    <groupId>sh.tak.appbundler</groupId>
    <artifactId>appbundle-maven-plugin</artifactId>
    <version>1.2.0</version>
    <configuration>
        <mainClass>com.example.myapp.Main</mainClass>
        <jrePath>/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk</jrePath>
        <bundleName>My cool App</bundleName>
        <iconFile>icons.icns</iconFile>
    </configuration>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>bundle</goal>
            </goals>
        </execution>
    </executions>
</plugin>

Here's a quick overview of the config options I think are important:

  • mainClass
    • this option let's you specify the entrypoint of your application. It should point to the class containing your psvm.
  • jrePath
    • you might not really need this, but if you specify the path to your JRE here, the plugin will bundle it into your .app file. Note that this blows up the application by ~170MB so consider if you really need it.
  • bundleName
    • this will be the name of your .app file. This will also appear in the Info.plist.
  • iconFile
    • this option should point to a .icns file that will be used for the app. The path is relative to the location of the pom.xml so in the above example, icons.icns would be in the project root.
  • generateDiskImageFile
    • this option is not in the example because I don't need it. It still might be useful to some to have a .dmg file generated with your app. Possible values are: true or false (default)

So let's build our macOS app by running:

$ mvn package appbundle:bundle

For more information to this plugin, go to it's GitHub repo.

Lerk

Lerk

vegan, programmer, musician, critical of everything & worst nightmare of every sysop.

Read More