Introduction
If you are Java Developer, new to the Linux environment, installing and configuring Java updates can be a bit daunting. In the following post, we will update a VirtualBox VM running Canonical’s popular Ubuntu Linux operating system. The VM currently contains an earlier version of Java. We will update the VM to the latest release of the Java.
All code for this post is available as Gists on GitHub.com, including a complete install script, explained at the end of this post.
Current Version of Java?
First, we will use the ‘update-alternatives –display java’ command to review all the versions of Java currently installed on the VM. We can have multiple copies installed, but only one will be configured and active. We can verify the active version using the ‘java -version’ command.
# preview java alternatives | |
update-alternatives --display java | |
# check current version of java | |
java -version |
In the above example, the 1.7.0_17 JDK version of Java is configured and active. That version is located in the ‘/usr/lib/jvm/jdk1.7.0_17’ subdirectory. There are two other Java versions also installed but not active, an Oracle 1.7.0_17 JRE version and an older 1.7.0_04 JDK version. These three versions are referred to as ‘alternatives’, thus the ‘alternatives’ command. By selecting an alternative version of Java, we control which java.exe binary executable file the system calls when the ‘java’ command is executed. In a many software development environments, you may need different versions of Java, depending on different client project’s level of technology.
Alternatives
According to About.com, alternatives ‘make it possible for several programs fulfilling the same or similar functions to be installed on a single system at the same time. A generic name in the filesystem is shared by all files providing interchangeable functionality. The alternatives system and the system administrator together determine which actual file is referenced by this generic name. The generic name is not a direct symbolic link to the selected alternative. Instead, it is a symbolic link to a name in the alternatives directory, which in turn is a symbolic link to the actual file referenced.’
We can see this system at work by changing to our ‘/usr/bin’ directory. This directory contains the majority of binary executables on the system. Executing an ‘ls -Al /usr/bin/* | grep -e java -e jar -e appletviewer -e mozilla-javaplugin.so’ command, we see that each Java executable is actually a symbolic link to the alternatives directory, not a binary executable file.
# view java-related executables | |
ls -Al /usr/bin/* | \ | |
grep -e java -e jar -e jexec -e appletviewer -e mozilla-javaplugin.so | |
# view all the commands which support alternatives | |
update-alternatives --get-selections | |
# view all java-related executables which support alternatives | |
update-alternatives --get-selections | \ | |
grep -e java -e jar -e jexec -e appletviewer -e mozilla-javaplugin.so |
To find out all the commands which support alternatives, you can use the ‘update-alternatives –get-selections’ command. We can use a similar command to get just the Java commands, ‘update-alternatives –get-selections | grep -e java -e jar -e appletview -e mozilla-javaplugin.so’.
Computer Architecture?
Next, we need to determine the computer processor architecture of the VM. The architecture determines which version of Java to download. The machine that hosts our VM may have a 64-bit architecture (also known as x86-64, x64, and amd64), while the VM might have a 32-bit architecture (also known as IA-32 or x86). Trying to install 64-bit versions of software onto 32-bit VMs is a common mistake.
The VM’s architecture was originally displayed with the ‘java -version’ command, above. To confirm the 64-bit architecture we can use either the ‘uname -a’ or ‘arch’ command.
# determine the processor architecture | |
uname -a | |
arch |
JRE or JDK?
One last decision. The Java Runtime Environment (JRE) purpose is to run Java applications. The JRE covers most end-user’s needs. The Java Development Kit (JDK) purpose is to develop Java applications. The JDK includes a complete JRE, plus tools for developing, debugging, and monitoring Java applications. As developers, we will choose to install the JDK.
Download Latest Version
In the above screen grab, you see our VM is running a 64-bit version of Ubuntu 12.04.3 LTS (Precise Pangolin). Therefore, we will download the most recent version of the 64-bit Linux JDK. We could choose either Oracle’s commercial version of Java or the OpenJDK version. According to Oracle, the ‘OpenJDK is an open-source implementation of the Java Platform, Standard Edition (Java SE) specifications’. We will choose the latest commercial version of Oracle’s JDK. At the time of this post, that is JDK 7u45 (aka 1.7.0_45-b18).
The Linux file formats available for download, are a .rpm (Red Hat Package Manager) file and a .tar.gz file (aka tarball). For this post, we will download the tarball, the ‘jdk-7u45-linux-x64.tar.gz’ file.
Extract Tarball
We will use the command ‘sudo tar -zxvf jdk-7u45-linux-x64.tar.gz -C /usr/lib/jvm’, to extract the files directly to the ‘/usr/lib/jvm’ folder. This folder contains all previously installed versions of Java. Once the tarball’s files are extracted, we should see a new directory containing the new version of Java, ‘jdk1.7.0_45’, in the ‘/usr/lib/jvm’ directory.
# extract new version of java from the downloaded tarball | |
cd ~/Downloads/Java | |
ls | |
sudo tar -zxvf jdk-7u45-linux-x64.tar.gz -C /usr/lib/jvm/ | |
# change directories to the location of the extracted version of java | |
cd /usr/lib/jvm/ | |
ls |
Installation
There are two configuration modes available in the alternatives system, manual and automatic mode. According to die.net, ‘when a link group is in manual mode, the alternatives system will not (automatically) make any changes to the system administrator’s settings’. When a link group is in automatic mode, the alternatives system ensures that the links in the group point to the highest priority alternatives appropriate for the group’.
We will first install and configure the new version of Java in manual mode. To install the new version of Java, we run ‘update-alternatives –install /usr/bin/java java /usr/lib/jvm/jdk1.7.0_45/jre/bin/java 4’. Note the last parameter, ‘4’, the priority. Why ‘4’? If we chose to use automatic mode, as we will a little later, we want our new Java version to have the highest numeric priority. In automatic mode, the system looks at the priority to determine which version of Java it will run. In the post’s first screen grab, note each of the three installed Java versions had different priorities: 1, 2, and 3. If we want to use automatic mode later, we must set a higher priority on our new version of Java, ‘4’ or greater. We will set it now as part of the install, so we can use it later in automatic mode.
Configuration
First, to configure (activate) the new Java version in alternatives manual mode, we will run ‘update-alternatives –config java’. We are prompted to choose from the list of alternatives for Java executables (java.exe), which has now grown from three to four choices. Choose the new JDK version of Java, which we just installed.
That’s it. The system has been instructed to use the version we selected as the Java alternative. Now, when we run the ‘java’ command, the system will access the newly configured JDK version. To verify, we rerun the ‘java -version’ command. The version of Java has changed since the first time we ran the command (see first screen grab).
# find a higher priority number | |
update-alternatives --display java | |
# install new version of java | |
sudo update-alternatives --install /usr/bin/java java \ | |
/usr/lib/jvm/jdk1.7.0_45/jre/bin/java 4 | |
# configure new version of java | |
update-alternatives --config java | |
# select the new version when prompted |
Now let’s switch to automatic mode. To switch to automatic mode, we use ‘update-alternatives –auto java’. Notice how the mode has changed in the screen grab below and our version with the highest priority is selected.
Other Java Command Alternatives
We will repeat this process for the other Java-related executables. Many are part of the JDK Tools and Utilities. Java-related executables include the Javadoc Tool (javadoc), Java Web Start (javaws), Java Compiler (javac), and Java Archive Tool (jar), javap, javah, appletviewer, and the Java Plugin for Linux. Note if you are updating a headless VM, you would not have a web browser installed. Therefore it would not be necessary to configuring the mozilla-javaplugin.
# install and configure other java executable alternatives in manual mode | |
# install and update Java Web Start (javaws) | |
update-alternatives --display javaws | |
sudo update-alternatives --install /usr/bin/javaws javaws \ | |
/usr/lib/jvm/jdk1.7.0_45/jre/bin/javaws 20000 | |
update-alternatives --config javaws | |
# install and update Java Compiler (javac) | |
update-alternatives --display javac | |
sudo update-alternatives --install /usr/bin/javac javac \ | |
/usr/lib/jvm/jdk1.7.0_45/bin/javac 20000 | |
update-alternatives --config javac | |
# install and update Java Archive Tool (jar) | |
update-alternatives --display jar | |
sudo update-alternatives --install /usr/bin/jar jar \ | |
/usr/lib/jvm/jdk1.7.0_45/bin/jar 20000 | |
update-alternatives --config jar | |
# jar signing and verification tool (jarsigner) | |
update-alternatives --display jarsigner | |
sudo sudo update-alternatives --install /usr/bin/jarsigner jarsigner \ | |
/usr/lib/jvm/jdk1.7.0_45/bin/jarsigner 20000 | |
update-alternatives --config jarsigner | |
# install and update Java Archive Tool (javadoc) | |
update-alternatives --display javadoc | |
sudo update-alternatives --install /usr/bin/javadoc javadoc \ | |
/usr/lib/jvm/jdk1.7.0_45/bin/javadoc 20000 | |
update-alternatives --config javadoc | |
# install and update Java Plugin for Linux (mozilla-javaplugin.so) | |
update-alternatives --display mozilla-javaplugin.so | |
sudo update-alternatives --install \ | |
/usr/lib/mozilla/plugins/libjavaplugin.so mozilla-javaplugin.so \ | |
/usr/lib/jvm/jdk1.7.0_45/jre/lib/amd64/libnpjp2.so 20000 | |
update-alternatives --config mozilla-javaplugin.so | |
# install and update Java disassembler (javap) | |
update-alternatives --display javap | |
sudo update-alternatives --install /usr/bin/javap javap \ | |
/usr/lib/jvm/jdk1.7.0_45/bin/javap 20000 | |
update-alternatives --config javap | |
# install and update file that creates C header files and C stub (javah) | |
update-alternatives --display javah | |
sudo update-alternatives --install /usr/bin/javah javah \ | |
/usr/lib/jvm/jdk1.7.0_45/bin/javah 20000 | |
update-alternatives --config javah | |
# jexec utility executes command inside the jail (jexec) | |
update-alternatives --display jexec | |
sudo update-alternatives --install /usr/bin/jexec jexec \ | |
/usr/lib/jvm/jdk1.7.0_45/lib/jexec 20000 | |
update-alternatives --config jexec | |
# install and update file to run applets without a web browser (appletviewer) | |
update-alternatives --display appletviewer | |
sudo update-alternatives --install /usr/bin/appletviewer appletviewer \ | |
/usr/lib/jvm/jdk1.7.0_45/bin/appletviewer 20000 | |
update-alternatives --config appletviewer |
JAVA_HOME
Many applications which need the JDK/JRE to run, look up the JAVA_HOME environment variable for the location of the Java compiler/interpreter. The most common approach is to hard-wire the JAVA_HOME variable to the current JDK directory. User the ‘sudo nano ~/.bashrc’ command to open the bashrc file. Add or modify the following line, ‘export JAVA_HOME=/usr/lib/jvm/jdk1.7.0_45’. Remember to also add the java executable path to the PATH variable, ‘export PATH=$PATH:$JAVA_HOME/bin’. Lastly, execute a ‘bash –login’ command for the changes to be visible in the current session.
Alternately, we could use a symbolic link to ‘default-java’. There are several good posts on the Internet on using the ‘default-java’ link.
# open bashrc | |
sudo nano ~/.bashrc | |
#add these lines to bashrc file | |
export JAVA_HOME=/usr/lib/jvm/jdk1.7.0_45 | |
export PATH=$PATH:$JAVA_HOME/bin | |
# for the changes to be visible in the current session | |
bash --login |
Complete Scripted Example
Below is a complete script to install or update the latest JDK on Ubuntu. Simply download the tarball to your home directory, along with the below script, available on GitHub. Execute the script with a ‘sh install_java_complete.sh’. All java executables will be installed and configured as alternatives in automatic mode. The JAVA_HOME and PATH environment variables will also be set.
#!/bin/bash | |
################################################################# | |
# author: Gary A. Stafford | |
# date: 2013-12-17 | |
# source: http://www.programmaticponderings.com | |
# description: complete code for install and config on Ubuntu | |
# of jdk 1.7.0_45 in alteratives automatic mode | |
################################################################# | |
########## variables start ########## | |
# priority value | |
priority=20000 | |
# path to binaries directory | |
binaries=/usr/bin | |
# path to libraries directory | |
libraries=/usr/lib | |
# path to new java version | |
javapath=$libraries/jvm/jdk1.7.0_45 | |
# path to downloaded java version | |
java_download=~/jdk-7u45-linux-x64.tar.gz | |
########## variables end ########## | |
cd $libraries | |
[ -d jvm ] || sudo mkdir jvm | |
cd ~/ | |
# change permissions on jvm subdirectory | |
sudo chmod +x $libraries/jvm/ | |
# extract new version of java from the downloaded tarball | |
if [ -f $java_download ]; then | |
sudo tar -zxf $java_download -C $libraries/jvm | |
else | |
echo "Cannot locate Java download. Check 'java_download' variable." | |
echo 'Exiting script.' | |
exit 1 | |
fi | |
# install and config java web start (java) | |
sudo update-alternatives --install $binaries/java java \ | |
$javapath/jre/bin/java $priority | |
sudo update-alternatives --auto java | |
# install and config java web start (javaws) | |
sudo update-alternatives --install $binaries/javaws javaws \ | |
$javapath/jre/bin/javaws $priority | |
sudo update-alternatives --auto javaws | |
# install and config java compiler (javac) | |
sudo update-alternatives --install $binaries/javac javac \ | |
$javapath/bin/javac $priority | |
sudo update-alternatives --auto javac | |
# install and config java archive tool (jar) | |
sudo update-alternatives --install $binaries/jar jar \ | |
$javapath/bin/jar $priority | |
sudo update-alternatives --auto jar | |
# jar signing and verification tool (jarsigner) | |
sudo update-alternatives --install $binaries/jarsigner jarsigner \ | |
$javapath/bin/jarsigner $priority | |
sudo update-alternatives --auto jarsigner | |
# install and config java tool for generating api documentation in html (javadoc) | |
sudo update-alternatives --install $binaries/javadoc javadoc \ | |
$javapath/bin/javadoc $priority | |
sudo update-alternatives --auto javadoc | |
# install and config java disassembler (javap) | |
sudo update-alternatives --install $binaries/javap javap \ | |
$javapath/bin/javap $priority | |
sudo update-alternatives --auto javap | |
# install and config file that creates c header files and c stub (javah) | |
sudo update-alternatives --install $binaries/javah javah \ | |
$javapath/bin/javah $priority | |
sudo update-alternatives --auto javah | |
# jexec utility executes command inside the jail (jexec) | |
sudo update-alternatives --install $binaries/jexec jexec \ | |
$javapath/lib/jexec $priority | |
sudo update-alternatives --auto jexec | |
# install and config file to run applets without a web browser (appletviewer) | |
sudo update-alternatives --install $binaries/appletviewer appletviewer \ | |
$javapath/bin/appletviewer $priority | |
sudo update-alternatives --auto appletviewer | |
# install and config java plugin for linux (mozilla-javaplugin.so) | |
if [ -f '$libraries/mozilla/plugins/libjavaplugin.so mozilla-javaplugin.so' ]; then | |
sudo update-alternatives --install \ | |
$libraries/mozilla/plugins/libjavaplugin.so mozilla-javaplugin.so \ | |
$javapath/jre/lib/amd64/libnpjp2.so $priority | |
sudo update-alternatives --auto mozilla-javaplugin.so | |
else | |
echo 'Mozilla Firefox not found. Java Plugin for Linux will not be installed.' | |
fi | |
echo | |
########## add JAVA_HOME start ########## | |
grep -q 'JAVA_HOME' ~/.bashrc | |
if [ $? -ne 0 ]; then | |
echo 'JAVA_HOME not found. Adding JAVA_HOME to ~/.bashrc' | |
echo >> ~/.bashrc | |
echo 'export JAVA_HOME=/usr/lib/jvm/jdk1.7.0_45' >> ~/.bashrc | |
echo 'export PATH=$JAVA_HOME/bin:$PATH' >> ~/.bashrc | |
else | |
echo 'JAVA_HOME found. No changes required to ~/.bashrc.' | |
fi | |
########## add JAVA_HOME start ########## | |
echo | |
echo '*** Java update script completed successfully ***' | |
echo | |
# confirm alternative for java-related executables | |
update-alternatives --get-selections | \ | |
grep -e java -e jar -e jexec -e appletviewer -e mozilla-javaplugin.so | |
# confirm JAVA_HOME environment variable is set | |
echo "To confirm JAVA_HOME, execute 'bash --login' and then 'echo \$JAVA_HOME'" |
Below is a test of the script on a fresh Vagrant VM of an Ubuntu Cloud Image of Ubuntu Server 13.10 (Saucy Salamander). Ubuntu Cloud Images are pre-installed disk images that have been customized by Ubuntu engineering to run on cloud-platforms such as Amazon EC2, Openstack, Windows, LXC, and Vagrant. The script was able to successfully install and configure the JDK, as well as the JAVA_HOME and PATH environment variables.
Deleting Old Versions?
Before deciding to completely delete previously installed versions of Java from the ‘/usr/lib/jvm’ directory, ensure there are no links to those versions from OS and application configuration files. Many applications, such as NetBeans, eclipse, soapUI, and WebLogic Server, may contain their own Java configurations. If they don’t use the JAVA_HOME variable, they should be updated to reflect the current active Java version when possible.
Resources
Ubuntu Linux: Install Latest Oracle Java 7
update-alternatives(8) – Linux man page