Switching Java versions on a Mac (setting JAVA_HOME and using Java 6 Revisited)

Switching Java versions from say, Java 5 to Java 6 or back is (probably) not intuitive for the new Mac user. This blog will point out a few things you might not expect coming from a Windows or Linux environment.  This article is also intended to correct many other (now incorrect) articles attempting to help with the same issue.  These articles were valid until some very recent updates to Java were released, specifically the Leopard 10.5.7 Java Update 4 (referred to as UPD4 from here on).

If you just want to fix it quick, because something broke since you installed UPD4, then see the Bottom Line below.

For those that want to know a little bit more why your environment broke and the Java Preferences app doesn’t seem to do what you think it should, please read on.

Some Background

Here are a few concepts that need to be understood about the Mac/Java environment before you go off and just try to set JAVA_HOME in your favorite shell environment to some other location.  Even though you might get away with this for a little while, it will bite you eventually for various reasons.  Mac OSX 10.5 comes with Java installed by default and includes multiple versions.  With UPD4 (and some earlier updates), Java 6 is installed as well, but it is not set as the default JDK.

  • The Mac includes a Java Preferences App (Applications -> Utilities -> Java Preferences) that lets you set the preferred order of Java versions to run when you launch a Java application or applet within a browser.  This article shows you how to use the Java Preferences App, but the methods presented for switching Java versions is out of date.
  • The Mac has a couple different ways to set environment variables that are accessible to Java programs
    • Within your shell using normal environment variables, exactly as you would expect from Linux
    • Using a ‘plist’ (preferences list) file, specifically ~/.MacOSX/environment.plist
  • Just setting JAVA_HOME in your shell can cause unexpected behavior if you don’t know how Apple installs Java on the Mac
    • Apple uses several soft links to provide a “flexible” way to refer to a particular Java version and they recently changed how this works.

If you have tried to find where Apple stores all these versions, you may have discovered the /System/Library/Frameworks/JavaVM.Framework directory.  Under that is a directory called Versions and under that is a slew of versions, links, and a suspicious directory called A.  This directory holds (among other things) a bunch of shared command line tools under the Commands subdirectory (like java, javac, etc.) that are available to user programs.  These versions are supposed to pick the top version of Java from your Java Preferences app settings.  If you have JAVA_HOME set somewhere else, then all bets are off.

BTW, there is a lot of debate as to whether you should or should not manipulate these links manually.  After my research, I am a now a strong proponent of using the recommendations of Apple and tools that are provided.  The problem is finding their recommendations.  There are several articles on switching Java versions on the Mac and where you should point JAVA_HOME.  Just google any of the following phrases and you’ll see what I mean:

  • switch java version on mac
  • switch jdk version on mac
  • setting JAVA_HOME on mac

Even Apples’ own java development support site has it wrong now, according to my latest findings.  They are not immune to having outdated documentation and I have found lots of examples that point to information that is roughly 2 years out of date.

The most informative find I came across that helped me understand the issue better was a thread on lists.apple.com and can be summarized as follows.

  • There is a mess with how Java versions are installed and Apple’s approach to this is changing
  • Apple needs to maintain backwards compatibility, which means the mess will be with us for awhile
  • There is a new program to help us (/usr/libexec/java_home) and you should read up on it by doing a “man java_home”
    • java_home appears to be a very nice addition and can help you pick the best version of java for a program given some hints on version level (1.4, 1.5+, 1.6*, etc.)  as well as architecture (i386, x86_64, ppc) and data model (32 bit vs 64 bit)
  • Use the Java Preferences App to set an appropriate “default” Java runtime for your environment
  • Do NOT muck with the soft links (or anything under the /System hierarchy) manually
  • Use the java_home program in shell scripts to help you set an appropriate Java runtime for standalone programs – e.g. eclipse, ant, maven, your own java programs, etc.

Bottom Line

Here is the approach I now take for switching Java versions, but still allowing other programs to pick there favorite JDK:

  • do NOT set JAVA_HOME using the plist method – it’s not dynamic enough
  • use the Java Preferences app to switch the “default” Java version used for those programs that don’t care
  • (optional) set JAVA_HOME in your shell startup script (e.g. ~/.bashrc or equivalent) using the new /usr/libexec/java_home program – it will set the value to the one you chose in the Java Preferences app
    • NOTE: if you change the Java Preferences ordering, then you need to reset the JAVA_HOME variable in all open shell sessions to reflect that change.  You can simply run the following command (if using bash)
      • export JAVA_HOME=`/usr/libexec/java_home`
  • set JAVA_HOME specifically for each standalone java program in the shell script that runs the program.
    • Recommended approach: use the java_home program to help you decide which version is “best” by supplying it hints (version level, architecture, or data model)
      • export JAVA_HOME=`/usr/libexec/java_home -v 1.5+ -d32`
    • Optional approach is to set JAVA_HOME directly to one of the frameworks you know works.  So, if you want to run a program with Java 5, then do the following:
      • export JAVA_HOME=/System/Library/Frameworks/JavaVM.Framework/Versions/1.5/Home

References (examples I read in my research)

  • MOST HELPFUL thread to understand the issues caused by UPD4 (read from the bottom up)
  • Macosxhints.com (dated, for your amusement only)
    • A suggestion and debate (read the comments) about manipulating the soft links “manually” to point to a particular version.
  • Java on Mac OS X on about.com (not quite as dated and somewhat helpful to the newbie Java developer on Mac)
    • NOTE: the reference to the location of the Java Preferences App is wrong in this article
  • Apple.com (much of this is dated, some is useful, read with caution)
  • Switch JDKs on Mac on blogs.sun.com (talks about Java Preferences App and the plist file.  But, I’m not recommending you use the plist file for setting JAVA_HOME)

Hope this helps!

Posted in Development | Tagged , , | 2 Comments

Running Mule 2.2.x with 64-bit Tanuki Wrapper and Java 6 on Mac OS X

If you tried to run (or are running) Mule 2.2.x on an Intel based Mac using Java 6 and are tired of seeing the following error message, then read on!

WARNING - Unable to load the Wrapper's native library because none of the
 following files:
 libwrapper-macosx-x86-64.jnilib
 libwrapper-macosx-universal-64.jnilib
 libwrapper.jnilib
 could be located on the following java.library.path:

MULE_HOME/bin/%LD_LIBRARY_PATH%
 MULE_HOME/lib/boot
 Please see the documentation for the wrapper.java.library.path

This issue has been raised a few times and there was a suggestion on how to handle it here. NOTE: the suggestion (although reasonable) does not work – the Tanuki Wrapper is smart enough to know you are trying to fool it.

NOTE:  I only updated the “macosx” wrapper files within the mule hierarchy, so what I suggest here will not directly work for other OSes.  The concepts presented here could be applied, and may work, but I have not tried this for any other OS like Windows or Linux.

WARNING: All suggestions here are to be done at your own risk. You can mess things up on your Mac if you attempt any of these steps.  Make backups, use your brain, be careful.  Consider yourself warned 🙂

Steps to update the Tanuki Wrapper embedded within Mule

  1. Download the latest Tanuki Wrapper software from and unpack it somewhere
    1. I grabbed the full “Delta Pack” (tar.gz) version 3.3.5, which was the latest at the time
    2. From here on I refer to TANUKI_WRAPPER_HOME as the root of the folder where you unpacked the archive
  2. Make a backup copy of mule’s boot directory (to work around Murphy’s Law)
    1. Assume MULE_HOME is set to the root of your Mule 2.2.x install (e.g. /opt/mule-standalone-2.2.1)
    2. I made a complete copy and called it boot.orig by doing the following
    3. cd $MULE_HOME/lib; cp -p boot boot.orig
  3. Copy the new wrapper executables
    1. cp $TANUKI_WRAPPER_HOME/wrapper-delta-pack-3.3.5/bin/wrapper-macosx-universal-* $MULE_HOME/lib/boot/exec
    2. NOTE: this will replace the 32-bit one that was installed already and adds the 64-bit version
  4. Remove the old and copy the new wrapper libraries
    1. rm $MULE_HOME/lib/boot/libwrapper-macosx-*
    2. cp $TANUKI_WRAPPER_HOME/wrapper-delta-pack-3.3.5/lib/libwrapper-macosx-universal-* $MULE_HOME/lib/boot
    3. NOTE: I decided to remove the existing macosx libraries first, because there was a ppc version that I won’t use and didn’t want a mix of old/new libraries
  5. Copy the new wrapper.jar (adding the version number) and remove the old jar
    1. cp $TANUKI_WRAPPER_HOME/wrapper-delta-pack-3.3.5/lib/wrapper.jar $MULE_HOME/lib/boot/wrapper-3.3.5.jar
    2. rm $MULE_HOME/lib/boot/wrapper-3.2.3.jar

You should be good to go at this point, so give your mule a kick and see what happens!  If all went well, you should see something similar to the following:

Java Service Wrapper Community Edition 32-bit 3.3.5
Copyright (C) 1999-2009 Tanuki Software, Ltd.  All Rights Reserved.
http://wrapper.tanukisoftware.org

Launching a JVM...
Starting the Mule Server...
...

Please submit your comments to help improve this blog.  I’ll do my best to update this for clarity and completeness in a timely manner.

Happy Trails!
Rich Remington

Posted in Development | Tagged , , , , | 4 Comments