Main /
MacJavaAppsHow to bundle your Java application on the Mac. SummaryIn the past, we have provided a Mac OS X The way this is done differs between Apple Java (version 1.6) and Oracle Java (1.7 and later). Ptolemy II now requires Java 1.7 (though it can be built under Java 1.6). Some portions of Ptolemy II require Java 1.8 (accessors use Nashorn). We will be shipping Java 1.8. So, we want to deploy a Mac .app file that uses Java 1.8. Unfortunately, Oracle has some fairly heavyweight and incomprehensible system to create the .app directory. So, we use universalJavaApplicationStub How we built apps in Ptolemy 10.0
When When When universalJavaApplicationStubFortunately, https://github.com/tofi86/universalJavaApplicationStub defines a shell script that can be used to invoke Java cd $PTII/vendors git clone https://github.com/tofi86/universalJavaApplicationStub.git creates Unfortunately, the syntax that it expects for JarbundleruniversalJavaApplicationStub suggests using https://github.com/tofi86/Jarbundler, which is a fork of Jarbundler. Installed with: cd $PTII/vendors git clone https://github.com/tofi86/Jarbundler.git cd Jarbundler/ ant sudo -i cp /Users/cxh/ptII/vendors/Jarbundler/build/jarbundler-2.4.0.jar /opt/local/share/java/apache-ant/lib/ PtplotAs a test, I used a Ptplot installation: cd $PTII/ptolemy/plot make dists mkdir tmp cd tmp tar -zxf ../ptplot5.11.devel.tar.gz cd ptplot5.11.devel export PTII=`pwd` ./configure ant Then, at the end of <taskdef name="jarbundler" classname="net.sourceforge.jarbundler.JarBundler" /> <target name="app"> <jarbundler dir="." mainclass="ptolemy.plot.plotml.EditablePlotMLApplication" name="Ptplot" shortname="Ptplot" stubfile="/Users/cxh/ptII/vendors/universalJavaApplicationStub/src/universalJavaApplicationStub" useJavaXKey="true" > <jarfileset dir="/Users/cxh/ptII/ptolemy/plot/tmp/ptplot5.11.devel"> <include name="**/*.jar" /> </jarfileset> </jarbundler> </target> Running
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <plist version="1.0"> <dict> <key>CFBundleName</key> <string>Ptplot</string> <key>CFBundleShortVersionString</key> <string>1.0</string> <key>CFBundleAllowMixedLocalizations</key> <string>false</string> <key>CFBundleInfoDictionaryVersion</key> <string>6.0</string> <key>CFBundleExecutable</key> <string>universalJavaApplicationStub</string> <key>CFBundleDevelopmentRegion</key> <string>English</string> <key>CFBundlePackageType</key> <string>APPL</string> <key>CFBundleSignature</key> <string>????</string> <key>JavaX</key> <dict> <key>MainClass</key> <string>ptolemy.plot.plotml.EditablePlotMLApplication</string> <key>JVMVersion</key> <string>1.3+</string> <key>ClassPath</key> <array> <string>$JAVAROOT/config/jarTest.jar</string> <string>$JAVAROOT/ptolemy/plot/compat/compat.jar</string> <string>$JAVAROOT/ptolemy/plot/demo/demo.jar</string> <string>$JAVAROOT/ptolemy/plot/img/img.jar</string> <string>$JAVAROOT/ptolemy/plot/plot.jar</string> <string>$JAVAROOT/ptolemy/plot/plotapplet.jar</string> <string>$JAVAROOT/ptolemy/plot/plotapplication.jar</string> <string>$JAVAROOT/ptolemy/plot/plotml/plotml.jar</string> <string>$JAVAROOT/ptolemy/plot/plotmlapplet.jar</string> <string>$JAVAROOT/ptolemy/plot/pxgraphapplet.jar</string> </array> <key>Properties</key> <dict> <key>com.apple.mrj.application.apple.menu.about.name</key> <string>Ptplot</string> </dict> </dict> </dict> </plist> Problem: Mac App fails with "LSOpenURLsWithRole() failed with error -10810"If the Mac App fails with LSOpenURLsWithRole() failed with error -10810, then try making universalJavaApplicationStub executable bash-3.2$ open Vergil.app/ LSOpenURLsWithRole() failed with error -10810 for the file /Applications/Ptolemy/ptII11.0.devel07Sep/bin/Vergil.app bash-3.2$ ls -l Vergil.app/Contents/MacOS/ total 168 -rw-r--r-- 1 cxh admin 18604 Aug 8 08:25 JavaAppLauncher -rwxr-xr-x 1 cxh admin 45920 Aug 8 08:25 JavaApplicationStub -rw-r--r-- 1 cxh admin 12397 Sep 7 00:55 universalJavaApplicationStub bash-3.2$ chmod a+x Vergil.app/Contents/MacOS/universalJavaApplicationStub bash-3.2$ open Vergil.app/ Problem: $JAVAROOT and $APP_ROOT are not expanded in the Properties element.I'm using the Apple format with JavaX instead of Java so as to avoid #9. However $JAVAROOT and $APP_ROOT were not being expanded. So, I forked universalJavaApplicationStub, see https://github.com/cxbrooks/universalJavaApplicationStub Use: git clone https://github.com/cxbrooks/universalJavaApplicationStub.git Below is the diff: --- a/src/universalJavaApplicationStub +++ b/src/universalJavaApplicationStub @@ -158,6 +158,8 @@ if [ $exitcode -eq 0 ]; then # read the JVM Options JVMOptions=`/usr/libexec/PlistBuddy -c "print ${JavaKey}:Properties" "${InfoPlistFile}" 2> /dev/null | grep " =" | sed 's/^ */-D/g' | tr '\n' ' ' | sed 's/ */ /g' | sed 's/ = /=/g' | xargs` + # replace occurances of $APP_ROOT with its content + JVMOptions=`eval "echo ${JVMOptions}"` # read StartOnMainThread JVMStartOnMainThread=`/usr/libexec/PlistBuddy -c "print ${JavaKey}:StartOnMainThread" "${InfoPlistFile}" 2> /dev/null` @@ -181,9 +183,11 @@ if [ $exitcode -eq 0 ]; then # read the JVM Arguments JVMArguments=`/usr/libexec/PlistBuddy -c "print ${JavaKey}:Arguments" "${InfoPlistFile}" 2> /dev/null | xargs` + # replace occurances of $APP_ROOT with its content + JVMArguments=`eval "echo ${JVMArguments}"` - # read the Java version we want to find - JVMVersion=`/usr/libexec/PlistBuddy -c "print ${JavaKey}:JVMVersion" "${InfoPlistFile}" 2> /dev/null | xargs` + # read the Java version we want to find + JVMVersion=`/usr/libexec/PlistBuddy -c "print ${JavaKey}:JVMVersion" "${InfoPlistFile}" 2> /dev/null | xargs` # read Info.plist in Oracle style else @@ -200,7 +204,7 @@ else # read the JVM Options JVMOptions=`/usr/libexec/PlistBuddy -c "print :JVMOptions" "${InfoPlistFile}" 2> /dev/null | grep " -" | tr -d '\n' | sed 's/ */ /g' | xargs` - # replace occurances of $APP_ROOT with it's content + # replace occurances of $APP_ROOT with its content JVMOptions=`eval "echo ${JVMOptions}"` JVMClassPath="${JavaFolder}/*" @@ -210,7 +214,7 @@ else # read the JVM Arguments JVMArguments=`/usr/libexec/PlistBuddy -c "print :JVMArguments" "${InfoPlistFile}" 2> /dev/null | tr -d '\n' | sed -E 's/Array \{ *(.*) *\}/\1/g' | sed 's/ */ /g' | xargs` - # replace occurances of $APP_ROOT with it's content + # replace occurances of $APP_ROOT with its content JVMArguments=`eval "echo ${JVMArguments}"` fi My patch was merged in to the trunk in October, 2015. Sharing a common JDKOne issue is that for each of the https://github.com/tofi86/universalJavaApplicationStub was updated to support "There is some foo happening to determine which Java versions are installed – here's the list in which order system properties are checked:"
"system variable $JAVA_HOME"
"can also be set to a relative path using the <LSEnvironment> Plist dictionary key which allows for bundling a custom version of Java inside your app!"
"LSEnvironment (Dictionary - macOS) defines environment variables to be set before launching this app. The names of the environment variables are the keys of the dictionary, with the values being the corresponding environment variable value. Both keys and values must be strings."
"These environment variables are set only for apps launched through Launch Services. If you run your executable directly from the command line, these environment variables are not set."
https://github.com/tofi86/universalJavaApplicationStub/pull/26 discusses how the feature was implemented. JDK ImplementationI edited <key>LSEnvironment</key> <dict> <key>JAVA_HOME</key> <string>../jdk</string> </dict> However, it seemed that the # first check system variable "$JAVA_HOME" echo "$0: JAVA_HOME: $JAVA_HOME" > /tmp/j.out if [ -n "$JAVA_HOME" ] ; then The /Users/cxh/ptII/bin/CapeCode.app/Contents/MacOS/universalJavaApplicationStub: JAVA_HOME: https://www.cpume.com/question/eizoseg-set-environment-variables-on-mac-os-x-lion.html suggested running /System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -v -f ~/ptII/bin/CapeCode.app |