Embedding a JRE in a Swing application for Mac OS X
Asked Answered
G

3

6

I must ship a swing application with an embedded JRE. A zipped archive with application + JRE + .bat/.sh did the trick for Windows and Linux. Users download the zip, unzip it, and launch the application. Perfect.

But now, I must provide the same thing for Mac OS X. I have read / was told a lot of different things on that matter (forbidden to distribute a JRE on Mac, the contrary, there is always a JRE on Mac, etc...), so I'm really confused about what I can possibly do.

Does anybody already did such a thing? How did you solved the Mac application deployment? As a bonus, what is the best format to distribute my application in Mac (zip?)?

Gwendagwendolen answered 23/1, 2013 at 14:59 Comment(3)
Have you tried Excelsior JET ?Asthma
How about Launch4j? And check thisPro
@NikolayKuznetsov Launch4J is only for building Windows .exe launchers. The building of the launcher can be done on Mac/Linux but the resulting launcher will run on Windows only.Altitude
A
3

Have a look at the appbundler project on java.net. It provides an Ant task that will package your application up as a normal Mac .app bundle, and can optionally include an embedded JRE.

The whole Java landscape on Mac is a bit of a mess at the moment as we're still in the transitional period where Java 6 releases are supplied and maintained by Apple and Java 7 releases come direct from Oracle. The jarbundler project referred to by a_horse_with_no_name is for wrapping up a JAR as a .app bundle that will run on the Apple-supplied Java 6 that is included with Mac OS X 10.5/6/7, but not on Oracle Java 7, conversely appbundler targets Oracle Java 7 and its .app bundles won't run on Java 6.

If you want to target recent Macs running 10.7 or 10.8, and in particular if you want to distribute your app via the Mac App Store, then you should use appbundler and bundle a copy of the JRE. If you don't want to distribute via the store then the embedded JRE is optional. If your app can run on Java 6 then targetting Apple Java 6 with jarbundler will mean your app can run on older (<= 10.6) Macs. But then anyone with a more recent Mac that has only Java 7 will be prompted to download and install Java 6 when they try and run your app.

It's fine to distribute the .app in a .zip archive, as long as everything in the Contents/MacOS directory (and the appropriate files in the embedded JRE if applicable) inside the app is marked with execute permission in the zip file. If you're building with Ant you'll need to use <zipfileset>s with the right filemode.

Altitude answered 23/1, 2013 at 16:41 Comment(4)
Which Java version is targeted with jarbundler is only a matter which Stub is included if I'm not mistaken. So if one can get hold of the Stub for Java7 this can be used for jarbundler as well. I did this for the upgrade from Java5 to Java6 (apparently with the help of other Mac users). A ZIP file won't work because you cannot specify execute permissions within a ZIP file, only in tar file.Craunch
@a_horse_with_no_name there is no stub for Java 7 that is compatible with the Info.plist format used by Apple Javas, Oracle versions use a different API to launch the VM from the stub. And a ZIP file can hold permissions information (technically it's an infozip extension rather than part of the core spec but it's a de facto standard).Altitude
Ah, I didn't know that about the Stub. But I have never seen a ZIP file that contains file permissions (and I don't think Ant's zip task supports it at all). Can you give me a reference for that?Craunch
@a_horse_with_no_name "Starting with Ant 1.5.2, <zip> can store Unix permissions inside the archive (see description of the filemode and dirmode attributes for <zipfileset>). Unfortunately there is no portable way to store these permissions. Ant uses the algorithm used by Info-Zip's implementation of the zip and unzip commands - these are the default versions of zip and unzip for many Unix and Unix-like systems." (from the Ant manual for <zip>)Altitude
R
2

The easiest approach uses the same JAR as any other platform, deployed via Java Web Start. I've never tried using it to install a JRE.

The best approach to provide a more Mac friendly experience requires you to wrap your JAR(s) in an application bundle, discussed in the article's cited here. The preferred delivery format is a compressed disk image, .dmg.

The article Java Deployment Options for Mac OS X compares both options. This game is an example that can be launched either way.

Addendum: For the curious, the Mac OS X Finder treats .jnlp files as documents, opened with the JWS launcher by default. I keep a folder of some frequently used .jnlp files in a dock folder for quick access. The Java Preferences control panel permits managing cached applications. Choosing to install a shortcut creates a simple Mac Application bundle in the destination folder, and the included Info.plist can be edited just like any other. The decision to customize the .plist hinges on what features the application needs: screen menu bar, dock name and icon, JNI path, etc.

Rixdollar answered 23/1, 2013 at 17:42 Comment(2)
Is that comparison list fully correct for OS X Application Bundles? OTOH 1) a) Don't JWS desktop shortcuts work? b) Don't JWS apps. appear in the OS X equivalent of the Windows 'Add/Remove Programs' applet? 2) Isn't it possible? 3) Icons! Give me a break.. 4) No argument. 5) Document types are available by specifying an interest in the JNLP.. So a couple of questionable, and one or two really doubtful statements in that list. Further clarification would be appreciatedSpermogonium
@AndrewThompson: I've tried to elaborate on my (recently acquired) understanding of 1) a & b above. I'll have to look closer at 2) through 5).Rixdollar
C
1

I think you can safely assume the JRE is already present on a Mac.

The best format (so I'm told - I'm not a Mac user myself) is a tar.gz (to preserve file attributes) of an "App" bundle.

You can use the "jarbundler" ( http://sourceforge.net/projects/jarbundler/ ) to create a proper Mac "bundle" that can be extracted without further ado. Make sure the Stub that is included in the bundle is marked as "executable" from within the Ant tar task.

I think there are some problems if more than one JRE is installed. In that case the correct Stub must be used to start the JRE version that your application needs. If I recall correctly this Stub is located at /System/Library/Frameworks/JavaVM.framework/Resources/MacOS/JavaApplicationStub

There is a page that indicates that there might be problems with Java7 and the jarbundler: http://informagen.com/JarBundler/

Craunch answered 23/1, 2013 at 16:29 Comment(3)
"I must ship a swing application with an embedded jre" probably means any assumptions about what's already installed are worthless.Helvetii
@OrangeDog: but the OP also stated: "so I'm really confused about what I can possibly do"Craunch
@a_horse_with_no_name You can't safely assume a JRE is always present on the Mac. As you see now with recent Java updates from Apple on 10.8.2, they are completely fading out of the process of providing Java 6 System packages.Woodsman

© 2022 - 2024 — McMap. All rights reserved.