Tuesday Feb 17, 2009

Switching JDKs on Mac

We've recently been discussing this at work, and now that I have a setup working well for me (and working simply), I wanted to document the steps. My goal was to switch JDKs used by all the tools in my enviornment: NetBeans, ant, maven, command line Java, etc., so that they were all using either Java 5 or 6. After some missteps, here's what works for me.

I'm using Mac OS 10.5.6, but this info should be valid for any nearby version. The Mac comes with, and occasionally updates, JDKs 1.4 through 1.6. You can see the versions you have installed in this directory:

  • /System/Library/Frameworks/JavaVM.framework/Versions
While I initially played with the Current and CurrentJDK symbolic links in that directory to switch the JDK my system was using, I have seen the error of my ways and there is an easier solution. There are two steps, listed below:

1. Command Line Java

My Java is coming from /usr/bin/java, which points off to one of the versions in the 'Versions' dir described above. To change the version of the JDK you're getting here, use the Java Preferences application under Applications -> Utilities -> Java:

You can drag the JDK you'd like to the top and it should be reflected immediately from the command line:

hostname% java -version
java version "1.5.0_16"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_16-b06-284)
Java HotSpot(TM) 64-Bit Server VM (build 1.5.0_16-133, mixed mode)
hostname% java -version
java version "1.6.0_07"
Java(TM) SE Runtime Environment (build 1.6.0_07-b06-153)
Java HotSpot(TM) 64-Bit Server VM (build 1.6.0_07-b06-57, mixed mode)

2. Scripts and Applications That Use Java

Generally, other built-in applications or one that you install will use the JAVA_HOME environment variable to pick a JDK. By default, you won't have this set, and Mac-specific versions of startup scripts will usually create one by using the CurrentJDK link in the Java 'Versions' directory. The steps to add environment variables are documented in this article, but I can save you a little time. Create a directory .MacOSX in your home directory and add a file called environment.plist. Here are the entire contents of my ~/.MacOSX/environment.plist file:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
<plist version="0.9">

    <!-- When changing this, also run Java Preferences and change there. -->


With this value set, all processes started as you will have JAVA_HOME available to them. Since this file is read when you log in, you'll have to log out/in once after you create or edit this file.

Special case: NetBeans

The IDE I use is NetBeans, but the following idea probably applies to other large applications as well. When NetBeans is installed, it will pick a JDK to use and hard code it in a properties file. If you want it to rely on the JAVA_HOME that you're now setting in environment.plist, you just need to edit one file. Edit this file:

  • /Applications/NetBeans/NetBeans\\ 6.5.app/Contents/Resources/NetBeans/etc/netbeans.conf
..and you can set the JDK by changing this line:
  • netbeans_jdkhome=$JAVA_HOME

Note that, as the netbeans.conf file points out, you can always force a different JDK to be used by specifying it on the command line when starting the IDE. For your copying and pasting pleasure, here is the command to use to start it from terminal (I'm giving the 'help' option in this case). If you're using a different version, autocomplete ought to help with the version part of the path:

  • /Applications/NetBeans/NetBeans\\ 6.5.app/Contents/MacOS/netbeans --help


To recap, you can switch JDKs for your whole system by using the Java Preferences application along with changing the value in your environment.plist file. To switch on the fly, use the Preferences app and set a new value for JAVA_HOME in whatever terminal you're using, though some apps like NetBeans will still pick up the system value and you should specify the desired JDK on the command line.

Bonus links:
Just to get some useful info in one place, here are some links I've found very helpful for people first switching to Mac, whether developer or not.

Monday Apr 28, 2008

NetBeans: The Only [CVS] You'll Need

I was recently setting up a couple new machines and went through my normal process:

  • Install a new browser or two.
  • Install Java if there isn't a version I want already.
  • Install NetBeans.

Need ant? It's already in NetBeans -- add the ant/bin directory in your NetBeans installation to your path (a good idea so you don't run into version mismatches between command line and IDE). Need cvs? There's already a nice cvs GUI in the IDE. So I'm ready for development, or so I thought.

A project I was working on, as part of the build process, used ant to check out a couple other workspaces under cvs. This failed since ant was expecting cvs to exist in my path. Oops. Ok, I could go download one of the many cvs clients, or on a Mac installation install the large developer bundle. But there's already some form of cvs inside NetBeans, so why can't I use that? No point duplicating bits on my hard drive.

Well, you can use the cvs client inside NetBeans from the command line. There is no executable cvs(.sh, .bat) script, but there's a cvs client jar file that will do the trick: org-netbeans-lib-cvsclient.jar

You can find it easily enough but here are the locations in NB 6.X:

  • 6.0: <netbeans>/ide8/modules/org-netbeans-lib-cvsclient.jar
  • 6.1: <netbeans>/ide9/modules/org-netbeans-lib-cvsclient.jar

So I just create a little script called "cvs" (or cvs.bat) to call the jar file. Here's the one I'm using on a Mac, with the full path left out for readability:
  java -jar <path>/org-netbeans-lib-cvsclient.jar "$@"


  hostname:~ bobby$ cvs -version
  Java Concurrent Versions System (JavaCVS) 1.9 (client)

That's all there is to it. With this simple cvs script, I can now run all the command line cvs I want and use the GUI to handle the heavy lifting (ok, the heavy, the medium, and most of the light lifting).


Whatever part of GlassFish or the Java EE world that catches my attention. (Also, go Red Sox.)


« August 2016