Good news everyone!
Jun 04, 2016 I'll continue to update this post as I find more tweaks to make Java/Swing applications look and feel more like native Mac applications. FWIW, there's more to do to make a Swing application look and feel like a native Mac OS X application. At the very least you need to handle the 'Preferences' and 'Quit' menu items properly through callbacks. Cross-play with Java Edition: Windows, Mac, and Linux Allows you to play with other Java edition players. Split screen multiplayer (online multiplayer requires subscription sold separately) Playing split screen allows up to four players to play on the screen at the same time.
You can now put your Java 8 applications onto the mac app store. How do I know? Because I put a little hackathon app I wrote on the Mac App Store. The better news is that Oracle is working on making this very simple with the JavaFX packager. You can get some of the early bits in the open source repo for OpenJFX here (building and using open source code is left as an exercise for the reader).
If you don’t want to wait for the code to get an official release and you are comfortable doing stuff by hand then here are the steps you will need to follow.
- Cross-play with Java Edition: Windows, Mac, and Linux Allows you to play with other Java edition players. Split screen multiplayer (online multiplayer requires subscription sold separately) Playing split screen allows up to four players to play on the screen at the same time.
- Apple Java 2017-001 - For OS X 10.7 through macOS 10.13. Download the latest versions of the best Mac apps at safe and trusted MacUpdate.
Prepare your Environment
First you will need to be signed up as part of the Mac Develoer program at [developer.apple.com]. For this tutorial I will presume your name is
Alice Duke
, that your Team ID is JJJJJJJJJJ
and that the app you are shipping is titled AwesomeJavaApp
. You will of course need to change these to real values.Download your signing keys if you haven’t done so already (here’s how). You will need both the Mac App Distribution and Mac Installer Distribution, and they should automatically be placed in your keychain under the names
3rd Party Mac Developer Application: Alice Duke (JJJJJJJJJJ)
and 3rd Party Mac Developer Installer: Alice Duke (JJJJJJJJJJ)
.You will also need an entitlements file. Read all about them at the Mac Developer Library. You will have to turn on the app-sandbox entitlement as well as any of the other entitlements you will be using. Be sure to keep track of what entitlements you grand and why they are needed. Apple will be asking you to justify every one of them.
Next, create your Mac
.app
bundle the normal way you are doing with the javafxpackager, Ant, Maven, or Gradle build. Make sure this app works as it is what we will be bundling up.Next, you will need to copy the info.plist from the existing JDK or JRE into the embedded JRE in your app. It should be either at
/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Info.plist
or /Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Info.plist
, but it is likely to be the first one. Copy this file to AwesomeJavaApp.app/Contents/PlugIns/jdk1.8.0.jdk/Contents/Info.plist
.Now we need to strip a library. The Mac App Store doesn’t accept apps that even mention the deprecated Quicktime API, so we will need to remove the media capabilities tom JavaFX. If your app uses the JavaFX media apis you are out of luck for the time being. There is a bug to fix this in a future release.
The good news is that the Java 8 license lets us fix the problem, at least when it comes to JavaFX. Remove the file
libjfxmedia.dylib
.Signing the app (in may different places) is next. Apple loves their cryptographic hashes.
First, you may need to make the JDK in the app bundle writeable. The
codesign
program won’t sign read-only binaries. chmod -R +w AwesomeJavaApp.app/Contents/PlugIns/jdk1.8.0.jdk
should do the trick.You need to sign all jars, dylibs, and executable files in the bundle (with one exception). Enumerating them is left as an exercise to the reader. Any decent build tool can do it for you. You will need to sign it with both the identity you have and the entitlements you want
There is one caveat. Don’t sign the main excitable of the app bundle. It is in
Contents/MacOS
and has the name of your application, for example it would be AwesomeJavaApp.app/Contents/MacOS/AwesomeJavaApp
. We will get that signed another way.Another quirk is that you can give different entitlements to each file. In the javafxpackger we sign with an entitlements file that contains only the
app-sandbox
andinherit
entitlements, so they inherit all the entitlements from the main application.Next, you will want to sign the Java directory itself. Actually you need to sign all plugins and frameworks in your app, but the overwhelming majority of java apps will only have one plugin: Java.
Finally, we can sign the application itself. Yes, we can actually shave the yak at this point.
You may or may not need all of the flags I’ve show with
codesign
, as I have not exhaustively tested them in all the possibly combinations. You may not need the --deep
flag, but adding it will not get you out of signing all the interior jars and libraries. You may not need the -f
flag but it insures that your signature will be the only one. Finally, you may want to add a --verbose=4
flag to see all the gory details. Or not.Change app category macos. I bet you thought you were done? Now we need to create an installer package to send to the app store. Use the
productbuld
too to generate the need fileNote that you are signing this with the second key you downloaded: the one for installers.
If you feel the need you can test the install:
Now you can load it into the Mac App store using the Application Loader tool. You will first need to go to iTunes Connect and set things up. But we have now left the Java specific part of the assembly so there are many other blog posts out there by more qualified and experienced Mac App Store developers.
There are many other potholes that you could run into. Two I hit were not having a 512x512@2x icon, and another was a dispute about copyright on an icon. I changed the icon rather than wade through the appeals process to prove that the icon was in the public domain.
I plan on keeping this post up to date with any changes or corrections, so feel free to bookmark this page.
It’s no secret that there have been some issues within the last few years between the folks at Apple, and the folks at Oracle, who now own the rights to the Java language and software engines. Due to several security concerns, Apple, along with several other developers, have adjusted their approach to running Java apps and applets in order to protect consumers from potentially-dangerous code being run on their machines. On paper, this sounds like a good strategy to ensure the safety of user information.
But what if you legitimately have a need to run a Java app? There are so many different versions of Java Runtime Engines (also known as JRE, or the environment in which Java code is executed on an operating system) that finding the right combination can be tricky. Once you *do* find the correct version (or versions), security concerns such as the ones previously mentioned may still keep these apps from performing properly.
One way Java apps are distributed is called Java Web Start (see here for more information on this technology). These are small files that are downloaded and executed, as opposed to embedded code within a webpage. By default on several operating systems, including Apple’s OS X, these files are not executed automatically, which means they act as a regular download that must be double-clicked (or Command-O, for the keyboard fanatics out there like me) in order to run. While this isn’t a complete roadblock, it does diminish the convenience factor. Thankfully, there’s a way to get these programs to run automatically as they are downloaded, using Apples wonderful Automater tool. Here’s how:
Note: The screenshots in this document are tailored towards Apples most-recent version of OS X, Yosemite. If you are on an older version of OS X, the pictures and steps may not match up perfectly.
- From your Macintosh system, launch the Automater tool. This can be done by selecting it from the Launchpad, typing “Automater” into the Spotlight search field, or simply locating the icon in your Applications Folder.
- When Automater opens up, you can click “New Document” to create a blank document. This will open up the New Document wizard.
- We will be creating what is called a Folder Action workflow, so click to highlight the “Folder Action” icon, and then click the Choose button. A folder action workflow will perform a task any time the folder being monitored receives new files or folders within it.
- First, we need to specify the folder we want to perform this action on. Normally, this will be the “Downloads” folder, since this is where the downloaded Java Web Start files will be placed by default. From the drop-down in the upper right, select “Other…” and browse to the Downloads folder. Once that folder is opened, click the Choose button, and the drop-down should now read “Downloads”.
- Now we need to tell the workflow what action to perform. In the left-hand column, listed under “Library” are all the categories of actions we can choose from. Select “Utilities”, and all the utilities will come up in the next column. From that middle column, drag-and-drop “Run Shell Script” to the workflow column on the right, and it will add it as a step.
- Next, we need to configure the Shell Script action a little. Next to the “Shell:” dropdown, make sure the value is set to “/bin/bash” so that the BASH shell is used to execute the script. Then, on the right-hand side next to “Pass input:”, make sure it reads “as arguments”.
- Lastly, we need to input the shell script in question, as the default value of “cat” will not do what we need to do. Copy and paste the contents of the text box below into the shell script window. This script will search for any Java Web Start files (*.jnlp), and if it finds any, it will run the Java Web Start engine on them, and then delete them (so your downloads folder doesn’t get cluttered up).
- Once this is done, you can now save your Automater workflow from the File menu, or hit Command-S. I have titled mine “Java WebStart Downloads.workflow” so that i can easily find it in the coming steps.
- One last step is to activate the workflow for the downloads folder. Open up a Finder window, and go to your home folder by either selecting it from the Go menu in the menu bar, or hitting Command-Shift-H on your keyboard. This will allow you to see the Downloads folder in the Finder window itself, instead of just on the sidebar.
- Perform a secondary click (also known as a right-click) on the Downloads folder and select “Services”, and then “Folder Action Setup”. This brings up the Folder Actions Setup window.
- From the list of available actions, select your workflow, “Java WebStart Downloads.workflow” in my case, and click Attach. You will now see your Downloads folder in the lefthand column (with checkmark checked), and your workflow in the righthand column (also with checkmark checked). That’s it. Your Java Web Start documents will now automatically open, and then be removed.
Java Apps In Mac High Sierra
Now, whenever a .jnlp file is downloaded or otherwise placed in your Downloads folder, Automater will run (you will see a spinning gear in the top right of the menu bar). Once the Jawa Web Start file is finished, the gear will go away.
Java Apps In Mac Os
Note: The script used in this example is specifically designed for opening .jnlp files, however it can be easily adjusted to perform roughly any task on any type of file. This, however, is outside of the scope of this post. https://treeaccount963.weebly.com/blog/filehub-plus-mac-app.
While you’re at it, check out some of these sites for more Automator workflow ideas.
Java Apps In Mac Os
- (Please note, the following sites are not affiliated with Byteworks)