Nerd-World Problems

Installing Oracle JDK along-side OpenJDK using Linux Alternatives

Many professional developers, due to their work or dependencies, have a need to run Oracle Java instead of OpenJDK on their Linux development workstations. It’d be nice if there were a simple, straightforward way to do this, however we don’t live in such a world yet. But luckily it’s not too difficult to do this using the alternatives utility (available on many RedHat and Debian distributions).

The alternatives utility allows you to create groups of sym-link configurations that you can easily switch between, thus allowing you leave the OpenJDK installation in-tact while allowing you to use Oracle JDK instead.

First: confirm that your system is using alternatives in the first place

sudo alternatives --display java

You should see a list of currently configured sym-links for the java group. If you do, then that means that OpenJDK is currently setup in alternatives, and you can now install OracleJDK on your system and register it in the alternatives database.

While there already exist many examples online for doing just that, many of them only focus on properly replacing a few of the key java binaries. This example will hopefully show how to do a complete substitution for all binaries in the JRE and JDK.

Here’s an example of doing this on a RedHat based system (same concepts will apply for other distributions):

  1. Download the desired RPM package from Oracle
  2. Install the package (adjust command to match downloaded package name and location)

    sudo rpm -Uvh /path/to/binary/jdk-7u55-linux-x64.rpm
    
  3. Now install two new alternative groups for java & javac into the alternatives database. (example assumes that package installed Oracle JDK into /usr/java)

    sudo alternatives --install /usr/bin/java java /usr/java/latest/jre/bin/java 200000
        --slave /usr/bin/java_vm java_vm /usr/java/latest/jre/bin/java_vm
        --slave /usr/bin/javaws javaws /usr/java/latest/jre/bin/javaws
        --slave /usr/bin/jcontrol jcontrol /usr/java/latest/jre/bin/jcontrol
        --slave /usr/bin/policytool policytool /usr/java/latest/jre/bin/policytool
        --slave /usr/bin/keytool keytool /usr/java/latest/jre/bin/keytool
        --slave /usr/bin/orbd orbd /usr/java/latest/jre/bin/orbd
        --slave /usr/bin/pack200 pack200 /usr/java/latest/jre/bin/pack200
        --slave /usr/bin/rmid rmid /usr/java/latest/jre/bin/rmid
        --slave /usr/bin/rmiregistry rmiregistry /usr/java/latest/jre/bin/rmiregistry
        --slave /usr/bin/servertool servertool /usr/java/latest/jre/bin/servertool
        --slave /usr/bin/tnameserv tnameserv /usr/java/latest/jre/bin/tnameserv
        --slave /usr/bin/unpack200 unpack200 /usr/java/latest/jre/bin/unpack200
        --slave /usr/bin/tnameserv tnameserv /usr/java/latest/jre/bin/tnameserv
    
    sudo alternatives --install /usr/bin/javac javac /usr/java/latest/bin/javac 200000
        --slave /usr/bin/appletviewer appletviewer /usr/java/latest/bin/appletviewer
        --slave /usr/bin/apt apt /usr/java/latest/bin/apt
        --slave /usr/bin/extcheck extcheck /usr/java/latest/bin/extcheck
        --slave /usr/bin/idlj idlj /usr/java/latest/bin/idlj
        --slave /usr/bin/jar jar /usr/java/latest/bin/jar
        --slave /usr/bin/jarsigner jarsigner /usr/java/latest/bin/jarsigner
        --slave /usr/bin/javadoc javadoc /usr/java/latest/bin/javadoc
        --slave /usr/bin/javafxpackager javafxpackager /usr/java/latest/bin/javafxpackager
        --slave /usr/bin/javah javah /usr/java/latest/bin/javah
        --slave /usr/bin/javap javap /usr/java/latest/bin/javap
        --slave /usr/bin/java-rmi.cgi java-rmi.cgi /usr/java/latest/bin/java-rmi.cgi
        --slave /usr/bin/jcmd jcmd /usr/java/latest/bin/jcmd
        --slave /usr/bin/jconsole jconsole /usr/java/latest/bin/jconsole
        --slave /usr/bin/jdb jdb /usr/java/latest/bin/jdb
        --slave /usr/bin/jhat jhat /usr/java/latest/bin/jhat
        --slave /usr/bin/jinfo jinfo /usr/java/latest/bin/jinfo
        --slave /usr/bin/jmap jmap /usr/java/latest/bin/jmap
        --slave /usr/bin/jmc jmc /usr/java/latest/bin/jmc
        --slave /usr/bin/jmc.ini jmc.ini /usr/java/latest/bin/jmc.ini
        --slave /usr/bin/jps jps /usr/java/latest/bin/jps
        --slave /usr/bin/jrunscript jrunscript /usr/java/latest/bin/jrunscript
        --slave /usr/bin/jsadebugd jsadebugd /usr/java/latest/bin/jsadebugd
        --slave /usr/bin/jstack jstack /usr/java/latest/bin/jstack
        --slave /usr/bin/jstat jstat /usr/java/latest/bin/jstat
        --slave /usr/bin/jstatd jstatd /usr/java/latest/bin/jstatd
        --slave /usr/bin/jvisualvm jvisualvm /usr/java/latest/bin/jvisualvm
        --slave /usr/bin/native2ascii native2ascii /usr/java/latest/bin/native2ascii
        --slave /usr/bin/rmic rmic /usr/java/latest/bin/rmic
        --slave /usr/bin/schemagen schemagen /usr/java/latest/bin/schemagen
        --slave /usr/bin/serialver serialver /usr/java/latest/bin/serialver
        --slave /usr/bin/wsgen wsgen /usr/java/latest/bin/wsgen
        --slave /usr/bin/wsimport wsimport /usr/java/latest/bin/wsimport
        --slave /usr/bin/xjc xjc /usr/java/latest/bin/xjc
    
  4. Ensure that the appropriate alternative group is selected for the JRE and JDK. (Note: these same commands can be used to switch back and forth between the OpenJDK install and Oracle JDK)

    sudo alternatives --config java
    sudo alternatives --config javac
    
  5. Ensure that the JAVA_HOME environment variable is appropriately configured across the system

    sudo cat > /etc/profile.d/java.sh <<EOF
    #!/bin/bash
    
    export JAVA_HOME=/usr/java/latest
    EOF
    
  6. You may need to reboot just to be sure that everything is setup right. But the alternatives changes should take effect immediately

(thanks to If-Not-True-Then-False for much of the original research/writing on how to do this)