Most guides for installing Oracle’s JDK on Ubuntu (and ubuntu derivatives like Linux Mint) provide enough to get a few common binaries like java, javac, javaws, and the java browser plugin to function correctly using Ubuntu’s “alternatives” system. However the JDK provides much more than this, and Ubuntu provides a richer system for handling this. This post provides a more complete version of the install guide.
Preparing the System
Ensure the system already has a full JDK installed. This will ensure there are existing entries for all known jdk “alternatives” (more on this later). I recommend the following packages be installed:
- openjdk-7-doc
- openjdk-7-jdk
- openjdk-7-jre
- openjdk-7-jre-headless
- openjdk-7-jre-lib
- openjdk-7-source
If any of these are not installed, they can be installed via:
sudo aptitude install <package>
By default, Ubuntu installs JDKs/JREs to /usr/lib/jvm. Each installed JDK/JRE has a name, and each ‘type’ will have its own .jinfo file (hidden, use ‘ls -la‘ to show). Download Oracle’s JDK and unpack/install the package to /usr/lib/jvm. Assuming you’ve downloaded version 1.7.0_21, the resulting directory will likely be /usr/lib/jvm/jdk1.7.0_21.
This guide will utilize a custom JDK installed named ‘latest’ which will be managed via a symlink. The name ‘latest’ is unimportant; you may name it anything you want like ‘custom’ or ‘managed’ or whatever. The premise behind the symlink is that once you’ve completed this guide, switching Oracle JDK versions in the future will be as simple as changing this one symlink. No need to re-run update-alternatives (or update-java-alternatives) or go though any part of this walkthrough again. Anyway, set up the symlink via:
sudo ln -s /usr/lib/jvm/jdk1.7.0_21 /usr/lib/jvm/latest
Ubuntu’s default man pages are gzipped while Oracle’s are not. To normalize the installation, gzip them all via:
sudo -u gzip -9v /usr/lib/jvm/latest/man/man1/*.1
Prepare Alternatives
Ubuntu manages desired installations/versions of packages/binaries via an “alternatives” system. See the man page for update-alternatives for more on this. Further, they provide a customized update-java-alternatives for switching an entire JDK/JRE version and all of its incorporated binaries in one command. In order to support this, Ubunutu’s JRE/JDK installations include a .jinfo file for each runtime, e.g. /usr/lib/jvm/.java-1.7.0-openjdk-amd64.jinfo. This file describes a java “alternative” named “java-7-openjdk-amd64”. Your system may include a different one depending on your hardware but the current name is unimportant. To determine the currently-installed version, run:
update-java-alternatives -l
You will probably see output like:
java-1.7.0-openjdk-amd64 1071 /usr/lib/jvm/java-1.7.0-openjdk-amd64
This signifies your JDK installation name is java-1.7.0-openjdk-amd64 and has “priority” 1071.
We’ll see up a JDK with name latest with some higher priority. I will use 1075 for this post. To set up this up:
- copy the .jinfo file:
sudo cp /usr/lib/jvm/.java-1.7.0-openjdk-amd64.jinfo /usr/lib/jvm/.latest.jinfo
- Edit the new .latest.jinfo file as follows:
- change the “name” to latest
- change the “alias” to java-latest
- change the “priority” to 1075
- change all jre/bin instances to bin
- change the jre/lib/jexec entry to lib/jexec
- change the mozilla-javaplugin.so entry’s path to /usr/lib/jvm/latest/jre/lib/amd64/libjavaplugin_jni.so
As an example of the complete .jinfo file:
name=latest alias=java-latest priority=1075 section=main hl java /usr/lib/jvm/latest/bin/java hl keytool /usr/lib/jvm/latest/bin/keytool hl pack200 /usr/lib/jvm/latest/bin/pack200 hl rmid /usr/lib/jvm/latest/bin/rmid hl rmiregistry /usr/lib/jvm/latest/bin/rmiregistry hl unpack200 /usr/lib/jvm/latest/bin/unpack200 hl orbd /usr/lib/jvm/latest/bin/orbd hl servertool /usr/lib/jvm/latest/bin/servertool hl tnameserv /usr/lib/jvm/latest/bin/tnameserv hl jexec /usr/lib/jvm/latest/lib/jexec jre policytool /usr/lib/jvm/latest/bin/policytool jdk appletviewer /usr/lib/jvm/latest/bin/appletviewer jdk extcheck /usr/lib/jvm/latest/bin/extcheck jdk idlj /usr/lib/jvm/latest/bin/idlj jdk jar /usr/lib/jvm/latest/bin/jar jdk jarsigner /usr/lib/jvm/latest/bin/jarsigner jdk javac /usr/lib/jvm/latest/bin/javac jdk javadoc /usr/lib/jvm/latest/bin/javadoc jdk javah /usr/lib/jvm/latest/bin/javah jdk javap /usr/lib/jvm/latest/bin/javap jdk jcmd /usr/lib/jvm/latest/bin/jcmd jdk jconsole /usr/lib/jvm/latest/bin/jconsole jdk jdb /usr/lib/jvm/latest/bin/jdb jdk jhat /usr/lib/jvm/latest/bin/jhat jdk jinfo /usr/lib/jvm/latest/bin/jinfo jdk jmap /usr/lib/jvm/latest/bin/jmap jdk jps /usr/lib/jvm/latest/bin/jps jdk jrunscript /usr/lib/jvm/latest/bin/jrunscript jdk jsadebugd /usr/lib/jvm/latest/bin/jsadebugd jdk jstack /usr/lib/jvm/latest/bin/jstack jdk jstat /usr/lib/jvm/latest/bin/jstat jdk jstatd /usr/lib/jvm/latest/bin/jstatd jdk native2ascii /usr/lib/jvm/latest/bin/native2ascii jdk rmic /usr/lib/jvm/latest/bin/rmic jdk schemagen /usr/lib/jvm/latest/bin/schemagen jdk serialver /usr/lib/jvm/latest/bin/serialver jdk wsgen /usr/lib/jvm/latest/bin/wsgen jdk wsimport /usr/lib/jvm/latest/bin/wsimport jdk xjc /usr/lib/jvm/latest/bin/xjc plugin mozilla-javaplugin.so /usr/lib/jvm/latest/jre/lib/amd64/libjavaplugin_jni.so
- Ensure the system recognizes your changes by re-running the update-java-alternatives -l command again. You should now see a second java alternative listed, now with name latest and priority 1075.
Register Alternatives
Here’s where Ubuntu has made this a pain. Instead of installing java with each of the included binaries in bin as a “slave” alternative, each one of these binaries has been registered as a separately-managed, standalone product. So we have to register an alternative for every single one of them. So here they all are in painstaking detail:
sudo update-alternatives --install /usr/bin/java java /usr/lib/jvm/latest/bin/java 1075 --slave /usr/share/man/man1/java.1.gz java.1.gz /usr/lib/jvm/latest/man/man1/java.1.gz sudo update-alternatives --install /usr/bin/appletviewer appletviewer /usr/lib/jvm/latest/bin/appletviewer 1075 --slave /usr/share/man/man1/appletviewer.1.gz appletviewer.1.gz /usr/lib/jvm/latest/man/man1/appletviewer.1.gz sudo update-alternatives --install /usr/bin/extcheck extcheck /usr/lib/jvm/latest/bin/extcheck 1075 --slave /usr/share/man/man1/extcheck.1.gz extcheck.1.gz /usr/lib/jvm/latest/man/man1/extcheck.1.gz sudo update-alternatives --install /usr/bin/idlj idlj /usr/lib/jvm/latest/bin/idlj 1075 --slave /usr/share/man/man1/idlj.1.gz idlj.1.gz /usr/lib/jvm/latest/man/man1/idlj.1.gz sudo update-alternatives --install /usr/bin/jar jar /usr/lib/jvm/latest/bin/jar 1075 --slave /usr/share/man/man1/jar.1.gz jar.1.gz /usr/lib/jvm/latest/man/man1/jar.1.gz sudo update-alternatives --install /usr/bin/jarsigner jarsigner /usr/lib/jvm/latest/bin/jarsigner 1075 --slave /usr/share/man/man1/jarsigner.1.gz jarsigner.1.gz /usr/lib/jvm/latest/man/man1/jarsigner.1.gz sudo update-alternatives --install /usr/bin/javac javac /usr/lib/jvm/latest/bin/javac 1075 --slave /usr/share/man/man1/javac.1.gz javac.1.gz /usr/lib/jvm/latest/man/man1/javac.1.gz sudo update-alternatives --install /usr/bin/javadoc javadoc /usr/lib/jvm/latest/bin/javadoc 1075 --slave /usr/share/man/man1/javadoc.1.gz javadoc.1.gz /usr/lib/jvm/latest/man/man1/javadoc.1.gz sudo update-alternatives --install /usr/bin/javah javah /usr/lib/jvm/latest/bin/javah 1075 --slave /usr/share/man/man1/javah.1.gz javah.1.gz /usr/lib/jvm/latest/man/man1/javah.1.gz sudo update-alternatives --install /usr/bin/javap javap /usr/lib/jvm/latest/bin/javap 1075 --slave /usr/share/man/man1/javap.1.gz javap.1.gz /usr/lib/jvm/latest/man/man1/javap.1.gz sudo update-alternatives --install /usr/bin/javaws javaws /usr/lib/jvm/latest/bin/javaws 1075 --slave /usr/share/man/man1/javaws.1.gz javaws.1.gz /usr/lib/jvm/latest/man/man1/javaws.1.gz sudo update-alternatives --install /usr/bin/jcmd jcmd /usr/lib/jvm/latest/bin/jcmd 1075 --slave /usr/share/man/man1/jcmd.1.gz jcmd.1.gz /usr/lib/jvm/latest/man/man1/jcmd.1.gz sudo update-alternatives --install /usr/bin/jconsole jconsole /usr/lib/jvm/latest/bin/jconsole 1075 --slave /usr/share/man/man1/jconsole.1.gz jconsole.1.gz /usr/lib/jvm/latest/man/man1/jconsole.1.gz sudo update-alternatives --install /usr/bin/jvisualvm jvisualvm /usr/lib/jvm/latest/bin/jvisualvm 1075 --slave /usr/share/man/man1/jvisualvm.1.gz jvisualvm.1.gz /usr/lib/jvm/latest/man/man1/jvisualvm.1.gz sudo update-alternatives --install /usr/bin/jdb jdb /usr/lib/jvm/latest/bin/jdb 1075 --slave /usr/share/man/man1/jdb.1.gz jdb.1.gz /usr/lib/jvm/latest/man/man1/jdb.1.gz sudo update-alternatives --install /usr/bin/jhat jhat /usr/lib/jvm/latest/bin/jhat 1075 --slave /usr/share/man/man1/jhat.1.gz jhat.1.gz /usr/lib/jvm/latest/man/man1/jhat.1.gz sudo update-alternatives --install /usr/bin/jinfo jinfo /usr/lib/jvm/latest/bin/jinfo 1075 --slave /usr/share/man/man1/jinfo.1.gz jinfo.1.gz /usr/lib/jvm/latest/man/man1/jinfo.1.gz sudo update-alternatives --install /usr/bin/jmap jmap /usr/lib/jvm/latest/bin/jmap 1075 --slave /usr/share/man/man1/jmap.1.gz jmap.1.gz /usr/lib/jvm/latest/man/man1/jmap.1.gz sudo update-alternatives --install /usr/bin/jps jps /usr/lib/jvm/latest/bin/jps 1075 --slave /usr/share/man/man1/jps.1.gz jps.1.gz /usr/lib/jvm/latest/man/man1/jps.1.gz sudo update-alternatives --install /usr/bin/jrunscript jrunscript /usr/lib/jvm/latest/bin/jrunscript 1075 --slave /usr/share/man/man1/jrunscript.1.gz jrunscript.1.gz /usr/lib/jvm/latest/man/man1/jrunscript.1.gz sudo update-alternatives --install /usr/bin/jsadebugd jsadebugd /usr/lib/jvm/latest/bin/jsadebugd 1075 --slave /usr/share/man/man1/jsadebugd.1.gz jsadebugd.1.gz /usr/lib/jvm/latest/man/man1/jsadebugd.1.gz sudo update-alternatives --install /usr/bin/jstack jstack /usr/lib/jvm/latest/bin/jstack 1075 --slave /usr/share/man/man1/jstack.1.gz jstack.1.gz /usr/lib/jvm/latest/man/man1/jstack.1.gz sudo update-alternatives --install /usr/bin/jstat jstat /usr/lib/jvm/latest/bin/jstat 1075 --slave /usr/share/man/man1/jstat.1.gz jstat.1.gz /usr/lib/jvm/latest/man/man1/jstat.1.gz sudo update-alternatives --install /usr/bin/jstatd jstatd /usr/lib/jvm/latest/bin/jstatd 1075 --slave /usr/share/man/man1/jstatd.1.gz jstatd.1.gz /usr/lib/jvm/latest/man/man1/jstatd.1.gz sudo update-alternatives --install /usr/bin/native2ascii native2ascii /usr/lib/jvm/latest/bin/native2ascii 1075 --slave /usr/share/man/man1/native2ascii.1.gz native2ascii.1.gz /usr/lib/jvm/latest/man/man1/native2ascii.1.gz sudo update-alternatives --install /usr/bin/rmic rmic /usr/lib/jvm/latest/bin/rmic 1075 --slave /usr/share/man/man1/rmic.1.gz rmic.1.gz /usr/lib/jvm/latest/man/man1/rmic.1.gz sudo update-alternatives --install /usr/bin/schemagen schemagen /usr/lib/jvm/latest/bin/schemagen 1075 --slave /usr/share/man/man1/schemagen.1.gz schemagen.1.gz /usr/lib/jvm/latest/man/man1/schemagen.1.gz sudo update-alternatives --install /usr/bin/serialver serialver /usr/lib/jvm/latest/bin/serialver 1075 --slave /usr/share/man/man1/serialver.1.gz serialver.1.gz /usr/lib/jvm/latest/man/man1/serialver.1.gz sudo update-alternatives --install /usr/bin/wsgen wsgen /usr/lib/jvm/latest/bin/wsgen 1075 --slave /usr/share/man/man1/wsgen.1.gz wsgen.1.gz /usr/lib/jvm/latest/man/man1/wsgen.1.gz sudo update-alternatives --install /usr/bin/wsimport wsimport /usr/lib/jvm/latest/bin/wsimport 1075 --slave /usr/share/man/man1/wsimport.1.gz wsimport.1.gz /usr/lib/jvm/latest/man/man1/wsimport.1.gz sudo update-alternatives --install /usr/bin/xjc xjc /usr/lib/jvm/latest/bin/xjc 1075 --slave /usr/share/man/man1/xjc.1.gz xjc.1.gz /usr/lib/jvm/latest/man/man1/xjc.1.gz sudo update-alternatives --install /usr/bin/keytool keytool /usr/lib/jvm/latest/bin/keytool 1075 --slave /usr/share/man/man1/keytool.1.gz keytool.1.gz /usr/lib/jvm/latest/man/man1/keytool.1.gz sudo update-alternatives --install /usr/bin/pack200 pack200 /usr/lib/jvm/latest/bin/pack200 1075 --slave /usr/share/man/man1/pack200.1.gz pack200.1.gz /usr/lib/jvm/latest/man/man1/pack200.1.gz sudo update-alternatives --install /usr/bin/unpack200 unpack200 /usr/lib/jvm/latest/bin/unpack200 1075 --slave /usr/share/man/man1/unpack200.1.gz unpack200.1.gz /usr/lib/jvm/latest/man/man1/unpack200.1.gz sudo update-alternatives --install /usr/bin/rmid rmid /usr/lib/jvm/latest/bin/rmid 1075 --slave /usr/share/man/man1/rmid.1.gz rmid.1.gz /usr/lib/jvm/latest/man/man1/rmid.1.gz sudo update-alternatives --install /usr/bin/rmiregistry rmiregistry /usr/lib/jvm/latest/bin/rmiregistry 1075 --slave /usr/share/man/man1/rmiregistry.1.gz rmiregistry.1.gz /usr/lib/jvm/latest/man/man1/rmiregistry.1.gz sudo update-alternatives --install /usr/bin/orbd orbd /usr/lib/jvm/latest/bin/orbd 1075 --slave /usr/share/man/man1/orbd.1.gz orbd.1.gz /usr/lib/jvm/latest/man/man1/orbd.1.gz sudo update-alternatives --install /usr/bin/servertool servertool /usr/lib/jvm/latest/bin/servertool 1075 --slave /usr/share/man/man1/servertool.1.gz servertool.1.gz /usr/lib/jvm/latest/man/man1/servertool.1.gz sudo update-alternatives --install /usr/bin/tnameserv tnameserv /usr/lib/jvm/latest/bin/tnameserv 1075 --slave /usr/share/man/man1/tnameserv.1.gz tnameserv.1.gz /usr/lib/jvm/latest/man/man1/tnameserv.1.gz sudo update-alternatives --install /usr/bin/policytool policytool /usr/lib/jvm/latest/bin/policytool 1075 --slave /usr/share/man/man1/policytool.1.gz policytool.1.gz /usr/lib/jvm/latest/man/man1/policytool.1.gz sudo update-alternatives --install /usr/bin/jexec jexec /usr/lib/jvm/latest/lib/jexec 1075 sudo update-alternatives --install /usr/lib/mozilla/plugins/libjavaplugin.so mozilla-javaplugin.so /usr/lib/jvm/latest/jre/lib/amd64/libjavaplugin_jni.so 1075
(Astute readers may note that, all save the last two entries, are identical except the name of the binary/alternative. This could absolutely have been done via a bash for loop instead. I’m leaving this as an exercise to the reader. Also note that jexec does not have a man page.)
Switching to the Oracle JDK
Everything should now be all set to fully switch from the openjdk Ubuntu came with to Oracle’s JDK. This can now be down with the following one-liner:
sudo update-java-alternatives -s latest
Upgrading the Oracle JDK Later
Now that the Oracle JDK is managed via a symlink, upgrading in the future is trivial. Simply download and install the latest Oracle JDK to /usr/lib/jvm/<path> where path will be something like jdk1.7.0_35, then update the /usr/lib/jvm/latest symlink to reference this new version. All of the “alternatives” have already been set to follow this symlink so the entire system will update just like that. Example:
sudo ln -sf /usr/lib/jvm/jdk1.7.0_35 /usr/lib/jvm/latest