Tomcat Native with Atlassian on RHEL6

Post date: May 27, 2015 2:20:50 PM

You may have noticed this intriguing little entry in the catalina.out log when starting up many of the products in the Atlassian suite:

INFO: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: ...

The official KB articles currently advise "You do not need to do anything.", so like an itch that needed scratching I had to delve a little deeper into this. The Tomcat Native lib does indeed super charge your application servers. Atlassian supply the source files for Tomcat Native in the products "bin" directory along with what appear to be the pre-compiled DLL for the Windows platform. So what's involved in getting this to work on RHEL6?

Download Java Development Kit

First thing, get Java 7 JDK and place it on the server. Grab the latest or if you'd like to play it safe try to match the version supplied with the product. I prefer to download the tgz and extract it to /usr/lib/jvm as the RPM tends to clean up older versions without asking.

While you're at it, shutdown your applications and configure them to use this java instead, especially if it's newer than the one supplied with the product. The bin/setenv.sh file is my personal preference for all such customisations. Example below is good for jira. Issuing the stop-<product>.sh command and reviewing the output is a good way to confirm Tomcat will use the updated jre.

export JAVA_HOME="/usr/lib/jvm/jdk1.7.0_79"

export JRE_HOME="/usr/lib/jvm/jdk1.7.0_79/jre"

Build Tomcat Native Library

Copy tomcat-native.tar.gz into your home directory so as not to clutter up product directories. Then issue the following commands. Optionally, an example including SSL is featured on the right (I normally try to avoid using Tomcat to provide SSL):

$ sudo yum install apr apr-devel gcc

$ tar -zxvf tomcat-native.tar.gz

$ cd ~/tomcat-native-1.1.XX-src/jni/native/

$ sudo ./configure \

--with-apr=/usr/bin/apr-1-config \

--with-java-home=/usr/lib/jvm/jdk1.7.0_79 \

--prefix=/usr/lib/jvm/tomcat-native-1.1.XX

$ sudo make

$ sudo make install

$ sudo yum install apr apr-devel gcc openssl-devel.<arch>

$ tar -zxvf tomcat-native.tar.gz

$ cd ~/tomcat-native-1.1.XX-src/jni/native/

$ sudo ./configure \

--with-apr=/usr/bin/apr-1-config \

--with-java-home=/usr/lib/jvm/jdk1.7.0_79 \

--with-ssl=/usr/include/openssl \

--prefix=/usr/lib/jvm/tomcat-native-1.1.XX

$ sudo make

$ sudo make install

Note: you'll need to enter the specific version number of tomcat-native (denoted by XX above). I've chosen to put the libraries in the jvm directory, you can pick any location that suits. In the logs on startup, you will notice an error about SSLEngine failing to start if you chose to go with the example on the left.

Including Tomcat Native

By this point you'll have a new lib directory you'll need to include in the java.library.path. Edit setenv.sh again and find the appropriate variable to update. Stash has JVM_LIBRARY_PATH, otherwise JVM_SUPPORT_RECOMMENDED_ARGS or JAVA_OPTS are possible alternatives. Some examples, the last one appends our directive to any existing JAVA_OPTS so as to maintain previous values. You'd want to put that one at the very end of the file.

JVM_LIBRARY_PATH="$CATALINA_HOME/lib/native:$STASH_HOME/lib/native:/usr/lib/jvm/tomcat-native-1.1.XX/lib"

JVM_SUPPORT_RECOMMENDED_ARGS="-Djava.library.path=/usr/lib/jvm/tomcat-native-1.1.XX/lib:/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib"

export JAVA_OPTS="$JAVA_OPTS -Djava.library.path=/usr/lib/jvm/tomcat-native-1.1.XX/lib:/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib"

Note: not sure how to append to the existing java.library.path used by Tomcat, so I hard coded the value listed in the INFO log message.

This all of course requires further attention the next time you upgrade, which is why I prefer not to have these libraries added to the existing library directories such as /usr/lib64 so they are easier to clean up. This approach also allow for different versions of Tomcat Native to be in use by several Tomcats on the same server.

I observed server start ups in half the time after applying this. Really makes me wonder what other hidden power-ups might be out there...

References: