Helping JAVA to find its way _HOME

Wilfred Springer

This entry is about JAVA_HOME. (Yep, you read that right.) I never imagined I would ever write a post on an environment variable, but - hey - I have been breaking my jaws on this one for a while, so I figured there are probably a couple of other people happy to learn about the solution.

Now, mind you, this is a problem for people on MacOS only.

I will now take a pause for people cheering and rolling over from laughing.

(I know, I know, I have been zealously preaching Mac and Linux superiority over Windows for as long as I remember...)

Anyway, with that out of the way - this is the problem:

fringe:~ wilfred$ java -version
java version "1.6.0_13"
Java(TM) SE Runtime Environment (build 1.6.0_13-b03-211)
Java HotSpot(TM) 64-Bit Server VM (build 11.3-b02-83, mixed mode)</pre>
fringe:~ wilfred$ mvn -version
Maven version: 2.0.9
Java version: 1.5.0_19
OS name: "mac os x" version: "10.5.7" arch: "i386" Family: "unix"
fringe:~ wilfred$ echo $JAVA_HOME

Can you tell what's going on here? First of all, I run 'java -version', and it tells me its version is 1.6.0_something. Then I run 'mvn -version', and it tells me the version of Java is 1.5.0_something. That's annoying. In fact, it is totally retarded.

The idea is that - on Mac - you set the default versions of Java through some kind of preferences pane. From that point on, everything would just work. No matter how often you would flip back and forward between different versions, it would just be fine. However, that clearly no longer works. It turns out that most Java-based tools on my system get it wrong.

Looking a little further, it turns out that this is the problem:

case "`uname`" in
  CYGWIN*) cygwin=true ;;
  MINGW*) mingw=true;;
  Darwin*) darwin=true 
           if [ -z "$JAVA_VERSION" ] ; then
             JAVA_VERSION="CurrentJDK"
           else
             echo "Using Java version: $JAVA_VERSION"
           fi
           if [ -z "$JAVA_HOME" ] ; then
             JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/${JAVA_VERSION}/Home
           fi
           ;;
esac

It turns out that a lot of scripts take /System/Library/Frameworks/JavaVM.framework/Versions/${JAVA_VERSION}/Home as the default for JAVA_HOME, and it turns out that this is no longer the location of your current JDK set through the preference pane.

So you need to set JAVA_HOME manually. But how do you do that if you want it to be in line with the JDK selected through your preferences? There just doesn't seem to be a easy way out.

The solution is actually quite simple, but also quite well hidden. Since Java for Mac OS X v10.5 Update 4, there is a new tool in '/usr/libexec' called 'java_home'. And guess what: it by default returns the location of the current version of Java set through the preference pane.

Now, solving the problem outlined above turns out to be fairly easy. You just set JAVA_HOME to the output of this command in your .profile file, and everything works like a charm:

fringe:~ wilfred$ export JAVA_HOME=`/usr/libexec/java_home`
fringe:~ wilfred$ mvn -version
Maven version: 2.0.9
Java version: 1.6.0_13
OS name: "mac os x" version: "10.5.7" arch: "x86_64" Family: "mac"

The interesting thing is: java_home also accepts a whole slew of commandline options. So instead of saying that you want the version of Java listed atop of the preference pane, you can actually make it pick a 64-bit version, a version in a particular range of versions or a version supporting a particular task. I think that's pretty sweet. What do you say?

Comments (3)

  1. Porter - Reply

    July 8, 2009 at 10:09 pm

    Interesting.

    I find myself doing something sort of similar on Windows systems on occasion. Essentially, I end up creating 2 - 3 JAVA_"HOME" variables... Where:

    JAVA_14 -> path to Java 1.4 installation
    JAVA_15 -> path to Java 1.5 installation
    JAVA_16 -> path to Java 1.6 installation

    Then, I just toggle JAVA_HOME = JAVA_14|15|16 as needed. The command path uses JAVA_HOME\bin and so does the classpath variable. Makes it relatively easy to toggle between various Java execution environments for local applications. The tricky bit is dealing with the browser plugin etc.

    Also on Linux (Ubuntu) it's fairly easy to use 'sudo update-alternatives --config java' and use the menu to select which Java to use...

    (and you can use the same technique - EXPORT JAVA13, etc. as on Windows.)

  2. Luís Miranda - Reply

    July 9, 2009 at 12:21 pm

    Good find! 🙂

  3. iwein - Reply

    July 14, 2009 at 7:34 am

    Nice to know that if you don't have the /usr/libexec/java_home you probably need to install java for mac osx update 4 or higher.

Add a Comment