Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java AppBundler application pointing to JRE defined by JAVA_HOME

Tags:

java

macos

java-7

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?

like image 646
Jurica Krizanic Avatar asked Jul 09 '13 10:07

Jurica Krizanic


People also ask

Can we set JAVA_HOME to JRE?

Set the JAVA_HOME System Variable Click the Advanced tab, and then click Environment Variables. Under System Variables, look for the JAVA_HOME system variable. The JAVA_HOME path should point to the location that you recorded when you installed the JRE.

Should I use home point to JDK or JRE?

If you're doing any sort of development, or building with Maven or Ant, you need to point to the JDK (Java Development Kit) where utilities such as javac (the Java Compiler) reside. Otherwise, you can point to the JRE (Java Runtime Environment). The JDK contains everything the JRE has and more.

What does JAVA_HOME point to?

JAVA_HOME is an operating system (OS) environment variable which can optionally be set after either the Java Development Kit (JDK) or the Java Runtime Environment (JRE) is installed. The JAVA_HOME environment variable points to the file system location where the JDK or JRE was installed.


1 Answers

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.

like image 71
Ian Roberts Avatar answered Sep 24 '22 19:09

Ian Roberts