Installing and switching between versions of Java on Ubuntu is a relatively simple process (with a couple of caveats), you just need to know the right commands. Considering that there was a time when I didn’t know this either I thought I’d share what I know (shouldn’t take long :)).

Anyways, first thing first. When we talk about installing Java on Ubuntu we are of course talking about Sun Java. You can also install Open JDK if you want, but most people will use the Sun version for their Java development. Of course these days there are several versions of Sun Java that are in mainstream use; well basically 2, Java1.5 and Java6 (I am sure things will be even more interesting when Java 7 comes out). Regardless of which version of the JDK you want to install the process to do this on Ubuntu is the same. You need to know what package you want to install and then you need to use our old friend apt-get.

Installing Java

In the case of the Sun JDK you will want to install either (or both) of:

sun-java5-jdk<br /> sun-java6-jdk

The commands for this will be:

sudo apt-get install sun-java5-jdk

or

sudo apt-get install sun-java6-jdk

Once you put in your password apt-get will go ahead and do it’s thing. The only thing to watch out for is that with Java you might get a license screen popping up during the installation (i.e. it won’t just finish by itself, so don’t go away), you will need to accept. That’s it, you now have one or several version of Java installed.

Switching Between Versions

Of course, if you have more than one version installed it is probably for a reason and you will need to switch between them at some point. Ubuntu has a very handy command just for this, update-java-alternatives. Using this command is simple:

update-java-alternatives -l

Which will produce output similar to the following:

java-1.5.0-sun 53 /usr/lib/jvm/java-1.5.0-sun<br /> java-6-sun 63 /usr/lib/jvm/java-6-sun

You can now pick one of the alternatives that were printed out and use the same command, with a different switch, to make Ubuntu use it as it’s default Java installation:

sudo update-java-alternatives -s java-6-sun

This will output a bunch of stuff:

Using '/usr/lib/jvm/java-6-sun/bin/appletviewer' to provide 'appletviewer'.<br /> Using '/usr/lib/jvm/java-6-sun/bin/apt' to provide 'apt'.<br /> Using '/usr/lib/jvm/java-6-sun/bin/extcheck' to provide 'extcheck'.<br /> Using '/usr/lib/jvm/java-6-sun/bin/HtmlConverter' to provide 'HtmlConverter'.<br /> Using '/usr/lib/jvm/java-6-sun/bin/idlj' to provide 'idlj'.<br /> Using '/usr/lib/jvm/java-6-sun/bin/jarsigner' to provide 'jarsigner'.<br /> Using '/usr/lib/jvm/java-6-sun/bin/jar' to provide 'jar'.<br /> Using '/usr/lib/jvm/java-6-sun/bin/javac' to provide 'javac'.<br /> Using '/usr/lib/jvm/java-6-sun/bin/javadoc' to provide 'javadoc'.<br /> Using '/usr/lib/jvm/java-6-sun/bin/javah' to provide 'javah'.<br /> Using '/usr/lib/jvm/java-6-sun/bin/javap' to provide 'javap'.<br /> Using '/usr/lib/jvm/java-6-sun/bin/java-rmi.cgi' to provide 'java-rmi.cgi'.<br /> Using '/usr/lib/jvm/java-6-sun/bin/jconsole' to provide 'jconsole'.<br /> Using '/usr/lib/jvm/java-6-sun/bin/jdb' to provide 'jdb'.<br /> Using '/usr/lib/jvm/java-6-sun/bin/jhat' to provide 'jhat'.<br /> Using '/usr/lib/jvm/java-6-sun/bin/jinfo' to provide 'jinfo'.<br /> Using '/usr/lib/jvm/java-6-sun/bin/jmap' to provide 'jmap'.<br /> Using '/usr/lib/jvm/java-6-sun/bin/jps' to provide 'jps'.<br /> Using '/usr/lib/jvm/java-6-sun/bin/jrunscript' to provide 'jrunscript'.<br /> Using '/usr/lib/jvm/java-6-sun/bin/jsadebugd' to provide 'jsadebugd'.<br /> Using '/usr/lib/jvm/java-6-sun/bin/jstack' to provide 'jstack'.<br /> Using '/usr/lib/jvm/java-6-sun/bin/jstatd' to provide 'jstatd'.<br /> Using '/usr/lib/jvm/java-6-sun/bin/jstat' to provide 'jstat'.<br /> Using '/usr/lib/jvm/java-6-sun/bin/native2ascii' to provide 'native2ascii'.<br /> Using '/usr/lib/jvm/java-6-sun/bin/rmic' to provide 'rmic'.<br /> Using '/usr/lib/jvm/java-6-sun/bin/schemagen' to provide 'schemagen'.<br /> Using '/usr/lib/jvm/java-6-sun/bin/serialver' to provide 'serialver'.<br /> Using '/usr/lib/jvm/java-6-sun/bin/wsgen' to provide 'wsgen'.<br /> Using '/usr/lib/jvm/java-6-sun/bin/wsimport' to provide 'wsimport'.<br /> Using '/usr/lib/jvm/java-6-sun/bin/xjc' to provide 'xjc'.<br /> Using '/usr/lib/jvm/java-6-sun/jre/bin/ControlPanel' to provide 'ControlPanel'.<br /> Using '/usr/lib/jvm/java-6-sun/jre/bin/java' to provide 'java'.<br /> Using '/usr/lib/jvm/java-6-sun/jre/bin/java_vm' to provide 'java_vm'.<br /> Using '/usr/lib/jvm/java-6-sun/jre/bin/javaws' to provide 'javaws'.<br /> Using '/usr/lib/jvm/java-6-sun/jre/bin/jcontrol' to provide 'jcontrol'.<br /> Using '/usr/lib/jvm/java-6-sun/jre/lib/jexec' to provide 'jexec'.<br /> Using '/usr/lib/jvm/java-6-sun/jre/bin/keytool' to provide 'keytool'.<br /> Using '/usr/lib/jvm/java-6-sun/jre/bin/orbd' to provide 'orbd'.<br /> Using '/usr/lib/jvm/java-6-sun/jre/bin/pack200' to provide 'pack200'.<br /> Using '/usr/lib/jvm/java-6-sun/jre/bin/policytool' to provide 'policytool'.<br /> Using '/usr/lib/jvm/java-6-sun/jre/bin/rmid' to provide 'rmid'.<br /> Using '/usr/lib/jvm/java-6-sun/jre/bin/rmiregistry' to provide 'rmiregistry'.<br /> Using '/usr/lib/jvm/java-6-sun/jre/bin/servertool' to provide 'servertool'.<br /> Using '/usr/lib/jvm/java-6-sun/jre/bin/tnameserv' to provide 'tnameserv'.<br /> Using '/usr/lib/jvm/java-6-sun/jre/bin/unpack200' to provide 'unpack200'.<br /> Using '/usr/lib/jvm/java-6-sun/jre/lib/i386/libnpjp2.so' to provide<br /> 'firefox-javaplugin.so'.<br /> Using '/usr/lib/jvm/java-6-sun/jre/lib/i386/libnpjp2.so' to provide<br /> 'iceape-javaplugin.so'.<br /> Using '/usr/lib/jvm/java-6-sun/jre/lib/i386/libnpjp2.so' to provide<br /> 'iceweasel-javaplugin.so'.<br /> Using '/usr/lib/jvm/java-6-sun/jre/lib/i386/libnpjp2.so' to provide<br /> 'midbrowser-javaplugin.so'.<br /> Using '/usr/lib/jvm/java-6-sun/jre/lib/i386/libnpjp2.so' to provide<br /> 'mozilla-javaplugin.so'.<br /> Using '/usr/lib/jvm/java-6-sun/jre/lib/i386/libnpjp2.so' to provide<br /> '<a href="http://xulrunner-1.9-javaplugin.so">xulrunner-1.9-javaplugin.so</a>'.<br /> Using '/usr/lib/jvm/java-6-sun/jre/lib/i386/libnpjp2.so' to provide<br /> 'xulrunner-javaplugin.so'.

There are two things to note about the command.

It needs root privileges, so you will need to execute it with sudo The name of the java version you pass to the command is one of the things that was printed out when you ran update-java-alternatives –l (i.e. java-6-sun or java-1.5.0-sun)

This is all you need to do to have your whole Ubuntu installation use a different version of Java. That’s all great, but there is one big problem.

The Built-In FAIL And How To Fix It

Many Java applications written these days rely on the existence of the JAVA_HOME environment variable (they use this variable to know which Java they should execute with). Unfortunately none of the commands we ran above set the JAVA_HOME environment variable. Instead you will normally have to wait until the first time you execute a Java application which fails when it tries to find JAVA_HOME before you realize that you will need to set this yourself.

Even then things are not quite that simple. The update-java-alternatives command relies quite heavily on symlinks so it may take a while to even figure out where your current Java is installed. Once you do figure it out and set your JAVA_HOME environment variable, you have to remember to update it if you decide to switch java versions later (by using the update-java-alternatives command).

I will try to save you some pain and tell you where things live and then show you how I set my JAVA_HOME so that it is automatically (almost) updated when you switch Java versions. So, the first thing you would need to do to figure out where things live is to run the following command:

which java

Which tells you that your java executable lives in:

/usr/bin/java

Of course if you go and have a look you will see that it is actually a symlink to:

/etc/alternatives/java

That in turn is also a symlink to something like (depending on your java version):

/usr/lib/jvm/java-6-sun/jre/bin/java

We’re almost there but not quite. You need to go back a few directories from the path above, more specifically you need to go to:

/usr/lib/jvm

This is where all the JVMs that are on your system will be found, you will also notice that java-6-sun in this directory is actually a symlink to the java-6-sun-1.6.0.14 (your actual version may differ) directory. The story for java-1.5.0-sun is similar. So, now you know that if you’re currently using Java 6 then your JAVA_HOME path should be:

/usr/lib/jvm/java-6-sun-1.6.0.14

To make sure this path persists between shutdowns, you will need to put it in your .bashrc file. But, as I mentioned you don’t want to just hard-code it as you would need to come and change it when you switch versions. So instead you can add the following line to the end of your .bashrc file:

export JAVA_HOME=`readlink -f \`which javac\` | awk -Fbin '{print $1}'`

What this does is automatically work out what your JAVA_HOME path should be (and sets it) depending on what version of Java you’re currently using. It finds where your java interpreter lives and follows all the symlinks if there are any (and we know there are several). It then uses awk to extract the path before any bin folders which will be the path to your JAVA_HOME. The reason all of this works is because:

the java compiler javac will always be in the bin folder of your JDK as opposed to the bin folder of your JRE (like the java executable itself could be), so extracting the path before the bin folder using awk, gives is the path to what JAVA_HOME should be

as opposed to the bin folder of your JRE (like the java executable itself could be), so extracting the path before the bin folder using awk, gives is the path to what JAVA_HOME should be using readlink –f, allows us to follow multiple levels of symlinks, which is handy in this case since that’s what we need to do to actually get the real path of where the javac compiler lives

The only thing to remember with this is that once it is in your .bashrc, every time you switch Java versions you will need to close the terminal and open a new one, or source your .bashrc again to make sure the JAVA_HOME path is updated. It is not a perfect solution but it is a decent one and it does the job. However if someone knows of a way to do this without having to start a new terminal or source your profile, do leave a comment and share your knowledge with everyone.

That’s all you need to know to install and work with Java on Ubuntu like a pro :).

Image by Refracted Moments