Getting Jenkins working on Ubuntu 14.04 with Tomcat 7
Today I’ve been wrangling with getting Jenkins CI installed on a DigitalOcean droplet running Ubuntu 14.04 LTS and Tomcat7.
What is Jenkins? According to the official site:
“Jenkins is an award-winning, cross-platform, continuous integration and continuous delivery application that increases your productivity. Use Jenkins to build and test your software projects continuously making it easier for developers to integrate changes to the project, and making it easier for users to obtain a fresh build. It also allows you to continuously deliver your software by providing powerful ways to define your build pipelines and integrating with a large number of testing and deployment technologies.”
Sounds pretty cool, and I was eager to get Jenkins up and running especially after reading the simple install instructions (as a Tomcat webapp) which seemed to imply it would be as simple as plopping the latest version of “jenkins.war” into the server’s tomcat7/webapps folder. (You can get the war here.)
Unfortunately things didn’t go so smoothly. After a few hours of rumaging around on various message boards and trying different things, here is a summary of the obstacles I came across and the steps that were helpful in resolving them. Given that I was trying to do something as mundane as getting Jenkins to work with a relatively fresh Ubuntu 14.04 install and tomcat7, I would guess these issues would be affecting a sufficient number of you to be worth writing about.
First Attempt: Installing Jenkins WAR
First step was to download the jenkins war file:
$ wget http://mirrors.jenkins-ci.org/war/latest/jenkins.war
And plop it into tomcat’s webapps folder, in my case:
$ sudo cp jenkins.war /var/lib/tomcat7/webapps/
And restart tomcat:
$ sudo service tomcat7 restart
If your lucky, at this stage upon visiting http://myhost:8080/jenkins/ (or wherever your tomcat install is listening) things should ‘just work’ and the jenkins start page should load up. If you are unlucky like me there are a few things you should check.
You might have an entropy shortage, say what?
First off, upon going with the above steps I found my entire tomcat7 installation hanging, *nothing* not even the default index.html page at http://myhost:8080/ would load, or throw an error – the connection would just hang.
The solution to this turned out to be, IMHO, pretty obscure, but seemingly well known in the tomcat world. This post was the basis of the solution, which states:
“Tomcat 7+ heavily relies on
SecureRandom class to provide random values for its session ids, and other things. Depending on your JRE, it can cause delays during startup if the entropy source that is used to initialize
SecureRandom is short of entropy.”
And that the fix is to add the following runtime java option:
But how do you set this option for tomcat7? The trick is to create the following script:
$ sudo vim /usr/share/tomcat7/bin/setenv.sh
And place the following line inside:
Tomcat7 will automatically scan /usr/share/tomcat7/bin/ on restart and run the scripts contained within (do make sure the tomcat process has the right permissions on this script ie: read +/ execute).
After doing the above, executing a sudo service tomcat7 restart stopped the server hang, and pointing the browser to http://myhost:8080/ once again displayed a non-trivial result. However, more obstacles lay ahead.
Unable to create home directory
Upon restarting jenkins + tomcat you may get the following error:
Unable to create the home directory '/usr/share/tomcat7/.jenkins'. This is most likely a permission problem.
On our system the solution was to simply create this dir and set the proper permissions:
cd /usr/share/tomcat7 sudo mkdir .jenkins sudo chown -R tomcat7:nogroup .jenkins
This directory is where jenkins will be creating workspaces and storing configs for the various projects you will be setting up, so it is important that it exists and that jenkins (or in this case its parent process, tomcat7) has the correct permissions (ie: read, write, execute).
HTTP Status 404 – /jenkins/ and “Unsupported major.minor version 51.0”
This was the trickest error to resolve, and probably the least likely to affect others as it depends on what’s going on with your java install including any legacy versions.
Visiting http://myhost:8080/jenkins/ still failed at this point, though the 404 meant tomcat7 was alive and kicking.
Being a tomcat noob, I had no idea where to even look for the logs that might shed light on this error. Turns out the file that I needed is called catalina.out, located on my machine at:
Upon inspection for jenkins related messages I found the lines:
INFO: Deploying web application archive /var/lib/tomcat7/webapps/jenkins.war SEVERE: Error listenerStart
Not too descriptive, but making progress. The next step was to figure out how to make tomcat7 and jenkins log more useful errors. This article had the solution. One simply creates a file logging.properties with the following lines:
org.apache.catalina.core.ContainerBase.[Catalina].level = INFO org.apache.catalina.core.ContainerBase.[Catalina].handlers = java.util.logging.ConsoleHandler
And places it inside webapps/jenkins/WEB-INF/classes/. (In case you were wondering, the jenkins folder is autocreated by tomcat7 via its autodetection of jenkins.war.)
Restarting tomcat7 now provided the much more useful error report:
INFO: Deploying web application directory /var/lib/tomcat7/webapps/jenkins Nov 10, 2015 10:54:36 AM org.apache.catalina.core.StandardContext listenerStart SEVERE: Error configuring application listener of class hudson.WebAppMain java.lang.UnsupportedClassVersionError: hudson/WebAppMain : Unsupported major.minor version 51.0 (unable to load class hudson.WebAppMain) at org.apache.catalina.loader.WebappClassLoader.findClassInternal(WebappClassLoader.java:2948) ... at java.lang.Thread.run(Thread.java:701) Nov 10, 2015 10:54:36 AM org.apache.catalina.core.StandardContext listenerStart SEVERE: Skipped installing application listeners due to previous error(s)
Looks like the key is “Unsupported major.minor version 51.0” – ie: somewhere there is an invalid java version being used to run jenkins. Major / minor version numbers for different java releases can be found here:
How to figure out which version of java is being used by tomcat7? The answer is to run the following script:
$ /usr/share/tomcat7/bin/catalina.sh version
whose output on my machine is:
Using CATALINA_BASE: /usr/share/tomcat7 Using CATALINA_HOME: /usr/share/tomcat7 Using CATALINA_TMPDIR: /usr/share/tomcat7/temp Using JRE_HOME: /usr Using CLASSPATH: /usr/share/tomcat7/bin/bootstrap.jar:/usr/share/tomcat7/bin/tomcat-juli.jar Server version: Apache Tomcat/7.0.52 (Ubuntu) Server built: Jun 19 2015 08:54:46 Server number: 18.104.22.168 OS Name: Linux OS Version: 3.13.0-43-generic Architecture: amd64 JVM Version: 1.7.0_80-b15 JVM Vendor: Oracle Corporation
This actually thickened the plot, and made little sense because oracle java 1.7 satisfied all Jenkins requirements at the time.
However, I remember that up until recently I had been running openjdk-6. Could it be that for some crazy reason, even though tomcat7 was using java 1.7, there was still some interference with the previous java 1.6 install?
So I uninstalled openjdk6-* via:
sudo apt-get remove openjdk-6-jre:amd64 openjdk-6-jre-lib openjdk-6-jre-headless:amd64
And did a restart of tomcat7.
And voila! Visiting http://myhost:8080/jenkins/ finally worked! Go figure …