Java AppBundler application pointing to JRE defined by JAVA_HOME
Asked Answered
A

2

5

I have been using Java Application Bundler to pack a Java application as .app. I have managed to run the application if I pack the JRE7 inside of the .app bundle. Is it possible to configure .app (in Info.plist) to point to the JRE defined by JAVA_HOME environment variable? If I do that, I am getting "Unable to load Java Runtime Environment"! I have tried to configure the JAVA_HOME in different ways, but with no success!

Can anyone provide any help or suggestion?

Acronym answered 9/7, 2013 at 10:50 Comment(0)
V
12

appbundler applications can use either an embedded Java 7 JRE inside the app bundle, or the Java 7 JRE installed in /Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home (the same one used by the web browser plugin). They can't use a JDK installed under /Library/Java/JavaVirtualMachines (or anywhere else, for that matter) and they definitely can't use Java 6.

What you can do, however, is not use appbundler and instead build the bundle by hand, with the main executable being a shell script that runs the java command line tool from JAVA_HOME (maybe falling back to the /Library/Internet Plug-Ins JRE if JAVA_HOME is not set). Such a script will be able to support both Java 6 and 7.

You would use something like this as YourApp.app/Contents/MacOS/YourApp:

#!/bin/sh

PRG=$0

while [ -h "$PRG" ]; do
    ls=`ls -ld "$PRG"`
    link=`expr "$ls" : '^.*-> \(.*\)$' 2>/dev/null`
    if expr "$link" : '^/' 2> /dev/null >/dev/null; then
        PRG="$link"
    else
        PRG="`dirname "$PRG"`/$link"
    fi
done

progdir=`dirname "$PRG"`

if [ -n "$JAVA_HOME" ]; then
  JAVACMD="$JAVA_HOME/bin/java"
elif [ -x /usr/libexec/java_home ]; then
  JAVACMD="`/usr/libexec/java_home`/bin/java"
else
  JAVACMD="/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/bin/java"
fi

exec "$JAVACMD" -classpath "$progdir/../Resources/Jars/*" \
       -Dapple.laf.useScreenMenuBar=true \
       my.pkg.MainClass

Then put your application's JAR files in YourApp.app/Contents/Resources/Jars, the icon in YourApp.app/Contents/Resources/icon.icns, and the following in YourApp.app/Contents/Info.plist:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>CFBundleDevelopmentRegion</key>
        <string>English</string>
        <key>CFBundleExecutable</key>
        <string>YourApp</string><!-- relative to Contents/MacOS -->
        <key>CFBundleGetInfoString</key>
        <string>My clever application</string>
        <key>CFBundleIconFile</key>
        <string>icon.icns</string><!-- relative to Contents/Resources -->
        <key>CFBundleInfoDictionaryVersion</key>
        <string>8.0</string>
        <key>CFBundleName</key>
        <string>YourApp</string>
        <key>CFBundlePackageType</key>
        <string>APPL</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
        <string>8.0</string>
</dict>
</plist>

See the GATE Developer launcher for full details, though note that this is a slightly more convoluted case as the .app script delegates to another script, which in turn loads the JAR files from a location that is outside the .app bundle. The principle remains the same however.

Videlicet answered 9/7, 2013 at 10:59 Comment(5)
I have also a shell script to run the app, but that is not an option due to knowledge of users about running scripts. It should be a clickable app. What am I supposed to put in Info.plist of my app under JVMRuntime parameter? How to point it to JAVA_HOME?Acronym
Succeeded to run it with Java installed in /Library/Internet Plug-Ins/JavaAppletPlugin.plugin/. Just removed JVMRuntime parameter from Info.plist, instead of setting values pointing to JAVA_HOME!Acronym
@JuricaKrizanic I've put in a bit more detail, including the necessary contents for Info.plist to make it work with JAVA_HOMEVidelicet
Thanks @IanRoberts for this good explanation. I extended the basic shell script and released it on GitHub as "universalJavaApplicationStub" ( github.com/tofi86/universalJavaApplicationStub ). It now supports both Apple Java 6 and Oracle Java 7 and also both Info.plist styles for Java properties in the application bundle (Oracle introduced new property keys). Feel free to use it!Wellrounded
Note that with macOS 10.15 (Catalina) and higher, you might encounter problems during file access if you launch your App from a script (particularly when using JFileChooser). As already discussed on this universalJavaApplicationStub project the script has to be compiled to overcome this issue. You can use a tool like Shell Script Compiler (SHC) to achieve that. Doing so, if trying to access a protected location, you will be prompted a Security Notification and can choose whether to grant access or not.Pirbhai
I
0
usr/libexec/java_home -V

Matching Java Virtual Machines (2): 1.8.271.09 (x86_64) "Oracle Corporation" - "Java" /Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home 1.8.0_271 (x86_64) "Oracle Corporation" - "Java SE 8" /Library/Java/JavaVirtualMachines/jdk1.8.0_271.jdk/Contents/Home /Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home

I was facing similar issue, that when I set my java_home as

echo export "JAVA_HOME=\$(/usr/libexec/java_home)" >> ~/.bash_profile

it got set to /Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home

so I did it like echo export "JAVA_HOME="Library/Java/JavaVirtualMachines/jdk1.8.0_271.jdk/Contents/Home" >> ~/.bash_profile

It result's into

Admins-MacBook-Pro:carot arun$ echo $JAVA_HOME

/Library/Java/JavaVirtualMachines/jdk1.8.0_271.jdk/Contents/Home

You can also edit it in future if required go to your user, in my case arun folder press command + shift + . to see hidden files open .bash_profile in any of your favourite editor

India answered 15/11, 2020 at 15:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.