If you’re a Java developer and are using a Linux system, probably you’ve had to deal with the alternatives program. I’m going to be honest, I hate ‘alternatives‘ (with a passion). I use the command-line all the time, but I just think the interface of this command is counterintuitive. I will try in this post to explain how the ‘alternatives‘ program works, specifically for configuring Java, and how I think its interface could be improved.
When there are several programs that response to the same command in a system, the ‘alternatives‘ command let us set which will be the real program that will be executed when that command is called. This is very clear to see in the case of Java. There are several JDK implementations: OpenJDK, GNU, JDK from Oracle, etc. All these JDKs come with a ‘java‘ executable. Supposing we got several JDKs from different vendors installed, which will be the one executed in our system when the ‘java‘ program runs?
Firstly, I’ll check what are the Java alternatives configured in my system:
$ alternatives --config java + 1 /usr/lib/jvm/jre-1.6.0-openjdk/bin/java * 2 /etc/alternatives/java_sdk/bin/java 3 /usr/lib/jvm/jre-1.5.0-gcj/bin/java 4 /usr/java/latest/bin/java 5 /usr/java/jdk1.7.0/bin/java
It seems I got several If you just installed Fedora and run the command above, probably you’ll see nothing, as you haven’t added an alternative yet. So, how to add a new alternative? I run the help first:
$ alternatives --help
Says that: *‘alternatives –install
** is the name under which the alternative will be grouped. If we set * * as *‘java’*, then when later we do: ‘*alternatives –config java*‘, the alternatives for ‘*java*‘ will be listed.
- is the full path to the command that will be executed. If we set as ‘/usr/bin/java’, this means that when the ‘/usr/bin/java‘ command is executed in our system, the default alternative for ‘java‘ will be run.
** is the full path to the command of the alternative. The program which will be actually run.
** a priority number. The highest the number, the higher the priority. That means that the alternative with the highest number will be executed by default, unless we manually set which is the default.
So, imagine I’m doing a fresh installation, downloaded the latest version of Oracle JDK 1.6 and would like to add it as an alternative. We should run the following command:
$ sudo alternatives --install /usr/bin/java java /usr/java/jdk1.6.0_25/bin/java 1000
Now if we list the alternatives for ‘java‘.
$ sudo alternatives --config java Selection Command ----------------------------------------------- *+ 1 /usr/java/jdk1.6.0_25/bin/java
When you run this command the prompt asks you which alternative will be the default.
Enter to keep the current selection[+], or type selection number:
The ‘+‘ symbol indicates the manual default, the ‘***‘ indicates the automatic default (the one with the highest number). In this case as there is only one alternative both signs point to the same alternative.
Let’s execute the ‘java‘ command and see what happens:
$ java -version java version "1.6.0_25" Java(TM) SE Runtime Environment (build 1.6.0_25-b06) Java HotSpot(TM) Server VM (build 20.0-b11, mixed mode)
You may think this is a pretty stupid example as there is only one alternative. Let’s add OpenJDK as an alternative (imagine I just downloaded and have successfully installed in my system). I should run the following:
$ sudo alternatives --install /usr/bin/java java /usr/lib/jvm/jre-1.6.0-openjdk/bin/java 2000
As we have set OpenJDK with a priority of 2000, higher that Oracle JDK (which was 1000), that means that now OpenJDK is the default alternative for ‘java‘.
$ alternatives --config java
There are 2 programs which provide 'java'. Selection Command ----------------------------------------------- 1 /usr/java/jdk1.6.0_25/bin/java *+ 2 /usr/lib/jvm/jre-1.6.0-openjdk/bin/java
Let’s see what happens if we run ‘java‘ now.
$ java -version java version "1.6.0_22" OpenJDK Runtime Environment (IcedTea6 1.10.3) (fedora-184.108.40.206.fc15-i386) OpenJDK Server VM (build 20.0-b11, mixed mode)
As the OpenJDK is now the default alternative, OpenJDK is executed.
What if we would like to remove an alternative. The help says:
alternatives --remove <name> <path>
Remember that *
$ sudo alternatives --remove java /usr/lib/jvm/jre-1.6.0-openjdk/bin/java
Now Oracle JDK should be the only alternative available:
$ alternatives --config java There is 1 program that provides 'java'. Selection Command ----------------------------------------------- *+ 1 /usr/java/jdk1.6.0_25/bin/java
Another interesting parameter is the* ‘–display’* option, which show information about the available alternatives.
$ sudo alternatives --display java java - status is auto. link currently points to /usr/java/jdk1.6.0_25/bin/java /usr/java/jdk1.6.0_25/bin/java - priority 1000 Current `best' version is /usr/java/jdk1.6.0_25/bin/java.
And that’s basically all you need to know about alternatives with regard to Java configuration.
Now, why I think the interface of alternatives is somehow counterintuitive?
Well, the first thing is that when you list the alternatives there are two headers: *