Dealing with Java Environments on CentOS and Ubuntu

java
troubleshooting
best-practice
openjdk-11
how-to
#1

A working Java environment is crucial for running OpenNMS services and there are many ways how to set up a Java environment. This guide explains how you can use the tools coming with CentOS 7 and Ubuntu 18 LTS to control and troubleshoot your Java environment on a server with a CLI.

:information_source: For OpenNMS Horizon it is required to have OpenJDK Development Kit installed which is named java-11-openjdk-devel on CentOS and on Ubuntu openjdk-11-jdk.

CentOS 7

Check which Java versions are already installed on my system with yum:

yum list installed | grep java

The update-alternatives tool shows which version is currently used as default:

update-alternatives --display java

Set a default version

update-alternatives --config java

There are 3 programs which provide 'java'.

  Selection    Command
-----------------------------------------------
   1           java-1.7.0-openjdk.x86_64 (/usr/lib/jvm/java-1.7.0-openjdk-1.7.0.221-2.6.18.0.el7_6.x86_64/jre/bin/java)
*+ 2           java-1.8.0-openjdk.x86_64 (/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.212.b04-0.el7_6.x86_64/jre/bin/java)
   3           java-11-openjdk.x86_64 (/usr/lib/jvm/java-11-openjdk-11.0.3.7-0.el7_6.x86_64/bin/java)

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

The * is what the distribution to prefer as the “best version” and the + tells you what is selected.
Set the java-11-openjdk.x86_64 as your selected by type 3.

There are 3 programs which provide 'java'.

  Selection    Command
-----------------------------------------------
   1           java-1.7.0-openjdk.x86_64 (/usr/lib/jvm/java-1.7.0-openjdk-1.7.0.221-2.6.18.0.el7_6.x86_64/jre/bin/java)
*  2           java-1.8.0-openjdk.x86_64 (/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.212.b04-0.el7_6.x86_64/jre/bin/java)
 + 3           java-11-openjdk.x86_64 (/usr/lib/jvm/java-11-openjdk-11.0.3.7-0.el7_6.x86_64/bin/java)

Verify your settings

Test if the Java Runtime Environment is the version you’ve selected:

java -version
openjdk version "11.0.3" 2019-04-16 LTS
OpenJDK Runtime Environment 18.9 (build 11.0.3+7-LTS)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.3+7-LTS, mixed mode, sharing)

Test if the Java compiler is set to the same version you’ve selected:

javac -version
javac 11.0.3

Java auto selection

The first output line of the update-alternatives --display java shows you the default setting and how it is selected. By default you will see java - status is auto. For CentOS 7 by default tells you OpenJDK 1.8.0 is the best-suited version for your system. This means if you just install OpenJDK 11 it will be your default JDK. As soon as you install OpenJDK 1.8.0 it will change your system to use this as your new default because it is set as auto selection by default.

This can cause weird behavior when you restart running Java applications and can get you in some unnecessary trouble. To prevent this behavior, run the update-alternative --config java tool and set it manually, even you have just one JDK installed. It will change the mechanism from auto to manual and gives you more control which default Java environment is used on your system.

You can verify this here:

update-alternatives --display java
java - status is manual.

Ubuntu 18 LTS

Check which Java versions are already installed on my system with yum:

apt list --installed | grep openjdk

The update-alternatives tool shows which version is currently used as default:

update-alternatives --display java

Set a default version

update-alternatives --config java
There are 2 choices for the alternative java (providing /usr/bin/java).

  Selection    Path                                            Priority   Status
------------------------------------------------------------
* 0            /usr/lib/jvm/java-11-openjdk-amd64/bin/java      1111      auto mode
  1            /usr/lib/jvm/java-11-openjdk-amd64/bin/java      1111      manual mode
  2            /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java   1081      manual mode

Press <enter> to keep the current choice[*], or type selection number:

The + tells you what is selected, in auto mode the version with the highest priority is selected.
Set the java-11-openjdk-amd64 as your manual selected version by type 1.

Verify your settings

Test if the Java Runtime Environment is the version you’ve selected:

java -version
openjdk version "11.0.2" 2019-01-15
OpenJDK Runtime Environment (build 11.0.2+9-Ubuntu-3ubuntu118.04.3)
OpenJDK 64-Bit Server VM (build 11.0.2+9-Ubuntu-3ubuntu118.04.3, mixed mode, sharing)

Test if the Java compiler is set to the same version you’ve selected:

javac -version
javac 11.0.2

Java auto selection

The first output line of the update-alternatives --display java shows you the default setting which is java - status is auto and the Java version with the highest priority defines which Java is set by default.

To prevent changes affecting your running Java applications, run the update-alternative --config java tool and set it manually, even you have just one JDK installed. It will change the mechanism from auto to manual and gives you more control which default Java environment is used on your system.

You can verify this here:

update-alternatives --display java
java - status is manual.

Updating Java packages

Over time there will be updates on Java packages. Let’s say you have the package java-11-openjdk-devel installed which comes in version 11.0.2.7 and there is a new version of OpenJDK 11.0.3.7 available and you want to update your system.

Running yum update on CentOS or respectively apt update && apt upgrade on Ubuntu replaces your OpenJDK 11.0.2.7 with the new version 11.0.3.7.

:biohazard: Replacing a Java environment with running Java applications can lead to side effects and uncontrolled behavior. Schedule downtimes and ensure you stop all your Java applications and restart them after an update so you have them cleanly running with your update Java environment.

Debian 9

With a minimal server install of Debian 9 you will notice you have just OpenJDK 8 available in your repositories. To be able to install an OpenJDK 11 JDK you have to enable the stable-backports repository in your /etc/apt/sources.list.

deb http://ftp.de.debian.org/debian/ stretch-backports main
deb-src http://ftp.de.debian.org/debian/ stretch-backports main

Run apt update && apt install openjdk-11-jdk to install the JDK on your system.

The configuration to set the default Java environment with update-alternatives is similar to Ubuntu 18 LTS.

Set a JAVA_HOME environment variable

Setting a JAVA_HOME environment variable is common practice for Java applications.

On CentOS there are symlinks used to address JDKs by less specific names, e.g.

ls -l /usr/lib/jvm
total 0
lrwxrwxrwx. 1 root root 26 May  8 04:53 java -> /etc/alternatives/java_sdk
lrwxrwxrwx. 1 root root 29 May  8 04:53 java-11 -> /etc/alternatives/java_sdk_11
lrwxrwxrwx. 1 root root 37 May  8 04:53 java-11-openjdk -> /etc/alternatives/java_sdk_11_openjdk
drwxr-xr-x. 8 root root 97 May  8 04:53 java-11-openjdk-11.0.3.7-0.el7_6.x86_64
drwxr-xr-x. 3 root root 17 Apr 17 13:15 java-1.8.0-openjdk-1.8.0.212.b04-0.el7_6.x86_64
lrwxrwxrwx. 1 root root 34 May  8 04:53 java-openjdk -> /etc/alternatives/java_sdk_openjdk
lrwxrwxrwx. 1 root root 21 May  8 05:10 jre -> /etc/alternatives/jre
lrwxrwxrwx. 1 root root 24 May  8 04:53 jre-11 -> /etc/alternatives/jre_11
lrwxrwxrwx. 1 root root 32 May  8 04:53 jre-11-openjdk -> /etc/alternatives/jre_11_openjdk
lrwxrwxrwx. 1 root root 39 May  8 04:53 jre-11-openjdk-11.0.3.7-0.el7_6.x86_64 -> java-11-openjdk-11.0.3.7-0.el7_6.x86_64
lrwxrwxrwx. 1 root root 27 May  8 04:00 jre-1.8.0 -> /etc/alternatives/jre_1.8.0
lrwxrwxrwx. 1 root root 35 May  8 04:00 jre-1.8.0-openjdk -> /etc/alternatives/jre_1.8.0_openjdk
lrwxrwxrwx. 1 root root 51 May  8 03:59 jre-1.8.0-openjdk-1.8.0.212.b04-0.el7_6.x86_64 -> java-1.8.0-openjdk-1.8.0.212.b04-0.el7_6.x86_64/jre
lrwxrwxrwx. 1 root root 29 May  8 07:32 jre-openjdk -> /etc/alternatives/jre_openjdk

On Ubuntu there are no specific version numbers as part of the directory names, e.g.

ls -l /usr/lib/jvm
lrwxrwxrwx 1 root root   21 Mar 26 20:57 java-1.11.0-openjdk-amd64 -> java-11-openjdk-amd64
lrwxrwxrwx 1 root root   20 Jan 14 21:02 java-1.8.0-openjdk-amd64 -> java-8-openjdk-amd64
drwxr-xr-x 9 root root 4096 May  8 10:41 java-11-openjdk-amd64
drwxr-xr-x 7 root root 4096 May  8 10:40 java-8-openjdk-amd64
:raising_hand_woman: If you need to set a JAVA_HOME environment variable, use /usr/lib/jvm/java-11-openjdk instead of /usr/lib/jvm/java-11-openjdk-11.0.2.7-0.el7_6.x86_64 on CentOS. As soon you make an update to 11.0.3 your JAVA_HOME points to a non-existing directory 11.0.2 and won’t work anymore. On Ubuntu you can use the /usr/lib/jvm/java-11-openjdk-amd64 if you require to stay on a Java JDK 11.

On Ubuntu and CentOS, you can set a JAVA_HOME variable globally or just for a logged in user. If you want to set it globally create /etc/profile.d/java.sh with the following content:

export JAVA_HOME=/usr/lib/jvm/java-11-openjdk

Restart your system and JAVA_HOME will be set.

If you want to set it just for a specific user, add the following line to your users ~/.bash_profile file:

export JAVA_HOME=/usr/lib/jvm/java-11-openjdk

Log out and log in again or run source ~/.bash_profile to apply the changes immediately. In case you have also set a global environment, the user-specific setting will overwrite the system specific one.

OpenNMS and JAVA_HOME

During the setup of OpenNMS the ${OPENNMS_HOME}/bin/runjava tool is used to specify a Java environment. The command runjava -s will search for a Java environment in your system and pick them in the following order:

  1. Set the Java environment from JAVA_HOME and exit
  2. If JAVA_HOME is not set, use the system’s default Java environment

You can manually set the Java environment for OpenNMS by running

./runjava -S /usr/lib/jvm/java-11-openjdk/bin/java

The Java version is stored in ${OPENNMS_HOME}/etc/java.conf.

1 Like
Upgrading Horizon 23 to 24 on CentOS 7 and switch to OpenJDK 11