Processing math: 100%

Wednesday, 29 January 2014

Linux Alternatives and Oracle Java

If, like me, you prefer to run the Oracle version of Java on your Linux machine as the default JDK, you will often find that the Linux distro will have other ideas.  Fedora for example has a number of Java based applications as part of the distribution which will include a dependency on the OpenJDK.  When the distro installs OpenJDK is will generally be setup as the default for executing the various Java binaries (e.g. 'java', 'javac').  However, the team at Redhat built a system called alternatives which maintains a set of symbolic links that allows the user to switch between multiple implementations of a package the supports the same functionality.  I've managed to understand enough about the alternatives package that I can now easily switch between the Oracle JDK and the OpenJDK.

Alternatives has the notion of master and slave configurations.  The way that the OpenJDK sets up the alternatives is that it uses 2 masters 'java' for the runtime (JRE) and 'javac' for the development tools (JDK).  To set the Oracle JDK in a similar way you need a script like this:

#!/bin/bash
LINKDIR=/usr/bin
JHOME=/usr/java/latest
JREDIR=$JHOME/jre/bin
JDKDIR=$JHOME/bin
sudo alternatives --install LINKDIR/java java JREDIR/java 20000 \
--slave LINKDIR/keytool keytool JREDIR/keytool \
--slave LINKDIR/orbd orbd JREDIR/orbd \
--slave LINKDIR/pack200 pack200 JREDIR/pack200 \
--slave LINKDIR/rmid rmid JREDIR/rmid \
--slave LINKDIR/rmiregistry rmiregistry JREDIR/rmiregistry \
--slave LINKDIR/servertool servertool JREDIR/servertool \
--slave LINKDIR/tnameserv tnameserv JREDIR/tnameserv \
--slave LINKDIR/unpack200 unpack200 JREDIR/unpack200 \
--slave LINKDIR/jcontrol jcontrol JREDIR/jcontrol \
--slave LINKDIR/javaws javaws JREDIR/javaws
sudo alternatives --install LINKDIR/javac javac JDKDIR/javac 20000 \
--slave LINKDIR/appletviewer appletviewer JDKDIR/appletviewer \
--slave LINKDIR/apt apt JDKDIR/apt \
--slave LINKDIR/extcheck extcheck JDKDIR/extcheck \
--slave LINKDIR/idlj idlj JDKDIR/idlj \
--slave LINKDIR/jar jar JDKDIR/jar \
--slave LINKDIR/jarsigner jarsigner JDKDIR/jarsigner \
--slave LINKDIR/javadoc javadoc JDKDIR/javadoc \
--slave LINKDIR/javah javah JDKDIR/javah \
--slave LINKDIR/javap javap JDKDIR/javap \
--slave LINKDIR/jcmd jcmd JDKDIR/jcmd \
--slave LINKDIR/jconsole jconsole JDKDIR/jconsole \
--slave LINKDIR/jdb jdb JDKDIR/jdb \
--slave LINKDIR/jhat jhat JDKDIR/jhat \
--slave LINKDIR/jinfo jinfo JDKDIR/jinfo \
--slave LINKDIR/jmap jmap JDKDIR/jmap \
--slave LINKDIR/jps jps JDKDIR/jps \
--slave LINKDIR/jrunscript jrunscript JDKDIR/jrunscript \
--slave LINKDIR/jsadebugd jsadebugd JDKDIR/jsadebugd \
--slave LINKDIR/jstack jstack JDKDIR/jstack \
--slave LINKDIR/jstat jstat JDKDIR/jstat \
--slave LINKDIR/jstatd jstatd JDKDIR/jstatd \
--slave LINKDIR/native2ascii native2ascii JDKDIR/native2ascii \
--slave LINKDIR/policytool policytool JDKDIR/policytool \
--slave LINKDIR/rmic rmic JDKDIR/rmic \
--slave LINKDIR/schemagen schemagen JDKDIR/schemagen \
--slave LINKDIR/serialver serialver JDKDIR/serialver \
--slave LINKDIR/wsgen wsgen JDKDIR/wsgen \
--slave LINKDIR/wsimport wsimport JDKDIR/wsimport \
--slave LINKDIR/xjc xjc JDKDIR/xjc
sudo alternatives --install /usr/lib64/mozilla/plugins/libjavaplugin.so libjavaplugin.so.x86_64 $JHOME/jre/lib/amd64/libnpjp2.so 20000

Once you have run that script then you can configure the JRE and JDK of your choice:

$ sudo alternatives --config java

Which will provide a prompt allowing you to choose your desired JRE

There is 2 program that provides 'java'.

  Selection    Command
-----------------------------------------------
*  1           /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.60...
 + 2           /usr/java/latest/jre/bin/java

Enter to keep the current selection[+], or type selection number:

And run the same thing for the JDK:

$ sudo alternatives --config javac


8 comments:

Vladimir Dolzhenko said...

Jesus !

It's quiet easy to switch between jdk in gentoo:

java-config-2 -L The following VMs are available for generation-2: 1) GCJ 4.7.2 [gcj-jdk] 2) IcedTea JDK 6.1.12.4 [icedtea-6] 3) IcedTea JDK 7.2.3.9 [icedtea-7] *) Oracle JDK 1.7.0.45 [oracle-jdk-bin-1.7] 5) Sun JDK 1.6.0.45 [sun-jdk-1.6] java -version
java version "1.7.0_45"
Java(TM) SE Runtime Environment (build 1.7.0_45-b18)
Java HotSpot(TM) Server VM (build 24.45-b08, mixed mode)

java-config-2 -s 1 Now using gcj-jdk as your user JVM java -version
java version "1.5.0"
gij (GNU libgcj) version 4.7.2

Harish G. Naik said...

On my Ubuntu based distro, I often do this and it works:

for binary in (ls /usr/lib/java/jdk1.7.0_51/bin/); do sudo update-alternatives --install /usr/bin/binary binary /usr/lib/java/jdk1.7.0_51/bin/binary 0; done

Anonymous said...

I just add my different Java environments in my .bashrc and select which one I want to use.

I always remove the installed one because they are installed at impractical locations.

JAVA_HOME=/java/jdk/jdk1.7.0_51/
#JAVA_HOME=/java/jdk/jdk1.8.0/
PATH=JAVA_HOME/bin:PATH

randy said...

Hi, Nice blog I had a great time reading it. Would you please consider adding a link to my website on link list? Please email me back. Thanks!

Randy
randydavis387 at gmail.com

Michael said...

update-java-alternatives

Anonymous said...
This comment has been removed by a blog administrator.
Grzegorz Gajos said...

When I see posts like this and so many confusions about alternatives I completely agree with Peter Veentjer here. .bashrc is the most simple and least surprise approach. It is also cross-platform solution and working fine on windows, see http://ggajos.com/environment-variables-management/

Unknown said...
This comment has been removed by a blog administrator.