How to build a macOS application from a Java Jar file

UPDATE: The solution below worked for Java 8, and here’s a solution that works with Java 14 and newer on macOS systems.

In this article I’ll show how to build a macOS application from a Java Jar file. I tested this with Java 1.8 on macOS 10.12.5 (Sierra) on June 29, 2017.

Three assumptions in this process are:

  • You have a single Jar file you can already run with the java -jar command
  • You aren’t concerned about implementing macOS-specific features, like enabling the Preferences and Quit menu items, or implementing Mac-specific keystrokes in your app
  • I assume your application is a Java Swing or JavaFX GUI app

(I understand that those first two items can be big assumptions. More on those later.)

As those assumptions infer, you won’t have a “perfect” app whose menu items work exactly like a native Mac application, but you will at least have a Mac application that you can start by double-clicking an application icon.

Background

If you don’t already know it, a macOS application is actually a directory that contains a series of files in a specific, well-defined layout. The directory must end with the extension, “.app”.

Many years ago, Sun (now Oracle) created a process by which you could create a Mac application from a Java Jar file (or even a series of Jar files). They created an “AppBundler” Jar file that can be used with Ant to build a Mac application, and that’s what I use in this process.

Update: While you can still use the AppBundler described in this article — and in some ways it’s a more obvious approach to building a Mac/Java application — Oracle now recommends building Mac/Java applications with their javapackager tool. I write about it in my How to use javapackager to build a macOS application bundle tutorial.

Requirements

The requirements for building a macOS/Java application with this specific build process are:

  1. You’ll need the Java SDK installed. I tested this with Java 1.8 on macOS 10.12.5.
  2. You’ll need Ant. I tested this with Ant 1.10.1, which I installed with Homebrew.
  3. Make sure JAVA_HOME is set. (You may get an error if it isn’t set.)
  4. Your Java application needs to be in one Jar file. This distribution includes a hello.jar file to show how things work.
  5. The application probably needs a META-INF/MANIFEST.MF file in that Jar file. (I didn’t test it without one.)

As mentioned earlier, the biggest assumption is that your application completely exists in one Jar file such that you can run it with the java -jar command. If you have that, this build process should work; if you don’t have that, you’ll need a more-complicated build process.

Building your application

To build your application:

  1. Clone my Github project.
  2. cd into that directory.
  3. Copy your Jar file into the current directory.
  4. Change the variables at the top of the build.xml file to match your application.
  5. Eventually you’ll want to create your own icon file as a macOS icns file, but you can start with my world.icns file until you create your own.
  6. In the macOS Terminal (or similar app), type ant to build the application.
  7. Assuming you named your application “HelloWorld”, type open release/HelloWorld.app to run your application.

If all goes well, your application will be shown in a few moments. (I assume your application is a Java Swing or JavaFX GUI app.) You can then type type open release to open the folder that contains your app, and then you can use the Mac Finder to copy your app to your desktop (or anywhere else).

Note 1: Font smoothing

Java applications built like this seem to have non-smooth fonts on macOS. This is usually immediately apparent in the title bar of your application. To get a smooth font with your application, follow this build process:

  • Edit the _addHiResKeyToPlistFile.sh file
  • Set the APP_NAME variable in that file to the same app_name you use in the build.xml file
  • Run the script named _build.sh to build your application. If you look at that script you’ll see that it (a) runs ant, then (b) runs the _addHiResKeyToPlistFile.sh script. That script adds the NSHighResolutionCapable key to the application’s Info.plist file.

Note 2: Setting the “application category”

If you’re going to build an application that you want to distribute to other users — such as through the Apple/Mac store — you’ll want to be sure to set the app_category variable in the build.xml file properly. This variable is used to set the LSApplicationCategoryType key in the Info.plist file in your application.

See this apple.com url for more information on the possible values. In case that URL ever goes away, I also included those value names in the file in this project named LSApplicationCategoryType.txt.

The Mac/Java AppBundler

This build process uses the Sun/Oracle AppBundler Jar file, which is documented here.

More information

If you want to build a Mac application that uses several Jar files, you’ll need a slightly more-complicated process. I use Proguard for this purpose, and you can search this website for something like “Mac Java Proguard” to find those examples.

If you want to build a Mac/Java application whose menu items work like native macOS applications, you’ll have to code that into your application. Search this website for something like “Mac Java quit preferences” to find examples of how that works.

Summary

In summary, if you wanted a simple way to convert a Java Jar file into a macOS application, I hope this process is helpful.