Page 1 of 1

Creating a Mac bundle that uses Java 7

PostPosted: 02 Oct 2013, 13:53
by melvin
I'd like to share some experiences on creating a Mac bundle for Java 7. I'd also like to thank the Forge team for pushing through with the upgrade to Java 7, it was a lot easier to do the same for Magarena after seeing what Forge has done.

I've tried Oracle's appbundler as well but ran into problems, I didn't manage to debug it as I don't have access to a Mac. After more research I came across http://mjhutchinson.com/journal/2010/01 ... or_gtk_app. The idea of using shell script (instead of using a Mac binary like what the bundlers do) appeals to me.

I've modified the launcher script from the site for Magarena 1.42, see https://code.google.com/p/magarena/sour ... auncher.sh and changed the Info.plist file to refer to MagarenaLauncher.sh as the CFBundleExecutable property.

Finally the app bundle is a zip of a directory with a special structure, in Magarena's case it looks like the following
Code: Select all
Magarena-<version>.app
 - Contents
   - Info.plist
   - PkgInfo
   - MacOS
     - MagarenaLauncher.sh
   - Java
     - <contents of the Win/Linux release zip>

Re: Creating a Mac bundle that uses Java 7

PostPosted: 14 Nov 2013, 20:05
by jendave
Hi all,

I have made a little progress on the Mac bundle for Java 7. Before, the Forge.app simply crashed immediately. Now I can get the splash screen but it hangs with this error.

Code: Select all
main > java.lang.ExceptionInInitializerError
   at java.nio.file.FileSystems.getDefault(FileSystems.java:176)
   at sun.util.calendar.ZoneInfoFile$1.run(ZoneInfoFile.java:483)
   at sun.util.calendar.ZoneInfoFile$1.run(ZoneInfoFile.java:478)
   at java.security.AccessController.doPrivileged(Native Method)
   at sun.util.calendar.ZoneInfoFile.<clinit>(ZoneInfoFile.java:477)
   at sun.util.calendar.ZoneInfo.getTimeZone(ZoneInfo.java:663)
   at java.util.TimeZone.getTimeZone(TimeZone.java:571)
   at java.util.TimeZone.setDefaultZone(TimeZone.java:668)
   at java.util.TimeZone.getDefaultRef(TimeZone.java:635)
   at java.util.TimeZone.getDefault(TimeZone.java:622)
   at java.text.SimpleDateFormat.initializeCalendar(SimpleDateFormat.java:682)
   at java.text.SimpleDateFormat.<init>(SimpleDateFormat.java:581)
   at java.text.SimpleDateFormat.<init>(SimpleDateFormat.java:560)
   at forge.card.CardEdition.<clinit>(CardEdition.java:89)
   at forge.card.CardEdition$EditionReader.<init>(CardEdition.java:277)
   at forge.card.EditionCollection.<init>(EditionCollection.java:38)
   at forge.model.FModel.<init>(FModel.java:152)
   at forge.model.FModel.getInstance(FModel.java:96)
   at forge.view.Main.main(Main.java:42)
Caused by: java.lang.RuntimeException: default directory must be absolute
   at sun.nio.fs.UnixFileSystem.<init>(UnixFileSystem.java:54)
   at sun.nio.fs.BsdFileSystem.<init>(BsdFileSystem.java:41)
   at sun.nio.fs.BsdFileSystemProvider.newFileSystem(BsdFileSystemProvider.java:43)
   at sun.nio.fs.BsdFileSystemProvider.newFileSystem(BsdFileSystemProvider.java:36)
   at sun.nio.fs.UnixFileSystemProvider.<init>(UnixFileSystemProvider.java:55)
   at sun.nio.fs.BsdFileSystemProvider.<init>(BsdFileSystemProvider.java:38)
   at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
   at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
   at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
   at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
   at java.lang.Class.newInstance(Class.java:374)
   at sun.nio.fs.DefaultFileSystemProvider$1.run(DefaultFileSystemProvider.java:52)
   at sun.nio.fs.DefaultFileSystemProvider$1.run(DefaultFileSystemProvider.java:43)
   at java.security.AccessController.doPrivileged(Native Method)
   at sun.nio.fs.DefaultFileSystemProvider.createProvider(DefaultFileSystemProvider.java:42)
   at sun.nio.fs.DefaultFileSystemProvider.create(DefaultFileSystemProvider.java:72)
   at java.nio.file.FileSystems$DefaultFileSystemHolder.getDefaultProvider(FileSystems.java:108)
   at java.nio.file.FileSystems$DefaultFileSystemHolder.access$000(FileSystems.java:89)
   at java.nio.file.FileSystems$DefaultFileSystemHolder$1.run(FileSystems.java:98)
   at java.nio.file.FileSystems$DefaultFileSystemHolder$1.run(FileSystems.java:96)
   at java.security.AccessController.doPrivileged(Native Method)
   at java.nio.file.FileSystems$DefaultFileSystemHolder.defaultFileSystem(FileSystems.java:95)
   at java.nio.file.FileSystems$DefaultFileSystemHolder.<clinit>(FileSystems.java:90)
   ... 19 more
 
The "Caused by: java.lang.RuntimeException: default directory must be absolute" line is the important one. I know the app is looking for the "res" folder. The Java 7 bundler directory structure and the way it handles paths are considerably different from the Java 6 way.

I'll dig into the code but if someone already recognizes the issue feel free to comment.

Thanks
Dave

Re: Creating a Mac bundle that uses Java 7

PostPosted: 19 Nov 2013, 09:47
by Max mtg
There is a familiar portion of calls in this trace
Code: Select all
   at java.text.SimpleDateFormat.<init>(SimpleDateFormat.java:581)
   at java.text.SimpleDateFormat.<init>(SimpleDateFormat.java:560)
   at forge.card.CardEdition.<clinit>(CardEdition.java:89)
   at forge.card.CardEdition$EditionReader.<init>(CardEdition.java:277)
that points to
Code: Select all
    private final static SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");