Atlassian JIRA is a very good issue tracking system. Many open source projects use it, including our own CometD project and most notably OpenJDK.
While Atlassian supports JIRA on Tomcat, JIRA runs in Jetty as well, and can benefit of Jetty’s support for SPDY.
Below you can find the instructions on how to setup JIRA 6.1.5 in Jetty 9.1.0 with HTTP and SPDY support on Linux.

1. Download JIRA’s WAR version

JIRA can be downloaded in two versions: the distro installer version (the default download from JIRA’s website), and the distro WAR version. You need to download the distro WAR version by clicking on “All JIRA Download Options” on the download page.

2. Build the JIRA WAR

Unpack the JIRA distro WAR file. It will create a directory called atlassian-jira-<version>-war referred to later as $JIRA_DISTRO_WAR.

2.1 Specify the JIRA HOME directory

$ cd $JIRA_DISTRO_WAR/edit-webapp/WEB-INF/classes/
$ vi

The file contains just one property:

jira.home =

You need to specify the full path of your JIRA home directory, for example:

jira.home = /var/jira

2.2 Change the JNDI name for UserTransaction

The JIRA configuration files come with a non standard JNDI name for the UserTransaction object.
This non standard name works in Tomcat, but it’s wrong for any other compliant Servlet container, so it must be modified to the standard name to work in Jetty.

$ cd $JIRA_DISTRO_WAR/edit-webapp/WEB-INF/classes/
$ vi entityengine.xml

You need to search in the entityengine.xml file for two lines inside the <transaction-factory> element:

<transaction-factory class="org.ofbiz.core.entity.transaction.JNDIFactory">
    <user-transaction-jndi jndi-server-name="default" jndi-name="java:comp/env/UserTransaction"/>    <-- First line to change
    <transaction-manager-jndi jndi-server-name="default" jndi-name="java:comp/env/UserTransaction"/> <-- Second line to change

You need to change the jndi-name attribute from the non standard name java:comp/env/UserTransaction to the standard name java:comp/UserTransaction. You have to remove the /env part in the JNDI name in both lines.

2.3 Execute the build

At this point you need to build the JIRA WAR file, starting from the JIRA distro WAR file:

$ ./

When the build completes, it generates a file called $JIRA_DISTRO_WAR/dist-generic/atlassian-jira-<version>.war. The build also generates a Tomcat version, but you need to use the generic version of the WAR.

3. Install Jetty 9.1

Download Jetty 9.1 and unpack it in the directory of your choice, for example /opt, so that Jetty will be installed in a directory such as /opt/jetty-distribution-9.1.0.v20131115 referred to later as $JETTY_HOME.
We will not modify any file in this directory, but only refer to it to start Jetty.

4. Setup the database

JIRA requires a relational database to work. Follow the instructions on how to setup a database for JIRA.
When you run JIRA for the first time, it will ask you for the database name, user name and password.

5. Setup the Jetty Base

Jetty 9.1 introduced a mechanism to separate the Jetty installation directory ($JETTY_HOME) from the directory where you configure your web applications, referred to as $JETTY_BASE. The documentation offers more information about this mechanism.
Create the Jetty base directory in the location you prefer, for example /var/www/jira, referred to later as $JETTY_BASE.

$ mkdir -p /var/www/jira

5.1 Setup the transaction manager

JIRA requires a transaction manager to work, and Jetty does not provide one out of the box. However, it’s not difficult to provide support for it.
You will use Atomikos’ TransactionsEssentials, an open source transaction manager released under the Apache 2 License.
For a transaction manager to work, you need the transaction manager jars (in this case Atomikos’) and you need to instruct Jetty to bind a UserTransaction object in JNDI.

5.1.1 Create the Jetty module definition

You can use a Jetty module to define the transaction manager support in Jetty following these instructions:

$ mkdir modules
$ vi modules/atomikos.mod

Create a file in the modules directory called atomikos.mod with this content:

# Atomikos Module

This file states that the atomikos module depends on Jetty’s built-in plus and resources modules, that requires all the jars in the $JETTY_BASE/lib/atomikos directory in the classpath, and that it is configured by a file in the $JETTY_BASE/etc directory called jetty-atomikos.xml.

5.1.2 Download the module dependencies

Create the lib/atomikos directory:

$ mkdir -p lib/atomikos

and save into it the following files, downloaded from Maven Central from this location (at the time of this writing the latest Atomikos version is 3.9.1):

  • atomikos-util.jar
  • transactions-api.jar
  • transactions.jar
  • transactions-jta.jar
  • transactions-jdbc.jar

5.1.3 Create the module XML file

Create the etc directory:

$ mkdir etc
$ vi etc/jetty-atomikos.xml

Create a file in the etc directory called jetty-atomikos.xml with this content:

<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "">
<Configure id="Server" class="org.eclipse.jetty.server.Server">
    <New class="">
            <New class="com.atomikos.icatch.jta.UserTransactionImp" />

5.1.4 Create the file

Create the resources directory:

$ mkdir resources
$ vi resources/

Create a file in the resources directory called with this content:

com.atomikos.icatch.service = com.atomikos.icatch.standalone.UserTransactionServiceFactory

This file configures the Atomikos transaction manager; you can read about other supported properties in the Atomikos documentation, but the one specified above is sufficient.

5.2 Setup the JDBC driver

JIRA is able to autoconfigure the database connectivity during the first run, but it requires the JDBC driver to be available.
Create the lib/ext directory:

$ mkdir -p lib/ext

Download the JDBC driver and copy it in the $JETTY_BASE/lib/ext directory.
For example, if you use MySQL you would copy the JDBC driver as $JETTY_BASE/lib/ext/mysql-connector-java-5.1.27.jar.

5.3 Deploy the JIRA WAR

Create the webapps directory:

$ mkdir webapps

Copy the JIRA generic WAR created at step 2.3 in the webapps directory:

$ cp $JIRA_DISTRO_WAR/dist-generic/atlassian-jira-<version>.war webapps/

5.5 Create the Jetty start.ini file

Jetty 9.1 uses the $JETTY_BASE/start.ini file to configure the modules that will be activated when Jetty starts. You need:

  • the atomikos module that you created above
  • Jetty’s built-in ext module, to have the JDBC driver in classpath
  • Jetty’s built-in deploy module, to deploy web applications present in the webapps directory
  • Jetty’s built-in jsp module, for JSP support required by JIRA
  • Jetty’s built-in http module, to have Jetty listen for HTTP requests

Create the start.ini file:

$ vi start.ini

with the following content:


The last property instructs Jetty to listen on port 8080 for HTTP requests.

6. Start Jetty

At this point you are ready to start Jetty.
If you are using JDK 7, JIRA requires a larger than default permanent generation, and a larger than default heap as well to work properly.
Start Jetty in the following way:

$ java -Xmx1g -XX:MaxPermSize=256m -jar $JETTY_HOME/start.jar

Be patient, JIRA may be slow to start up.

7. SPDY support

In order to enable SPDY support, you need to deploy your site over SSL. In order to do so, you need to have a valid X509 certificate for your site.
Follow the SSL documentation for details about how to configure SSL for your site.
If you want to just try SPDY locally on your computer, you can use a self-signed certificate stored in a keystore.

7.1 Create the keystore

Create a keystore with a self-signed certificate:

$ keytool -genkeypair -keystore etc/keystore -keyalg RSA -dname "cn=localhost" -storepass <password> -keypass <password>

The certificate must be stored in the $JETTY_BASE/etc/keystore file so that it will be automatically picked up by Jetty (this is configurable via the jetty.keystore property if you prefer a different location).

7.2 Setup the NPN jar

SPDY also requires the NPN jar, that depends on the JDK version you are using.
Please refer to the NPN versions table to download the right NPN jar for your JDK.
Create the lib/npn directory:

$ mkdir -p lib/npn

Download the right version of the NPN boot jar from this location and save it in the $JETTY_BASE/lib/npn directory.

7.3 Modify the start.ini file

Modify the $JETTY_BASE/start.ini file to have the following content:


The http module has been replaced by the spdy module, and so has the configuration property for the port to listen to.
There are new properties that specifies the password you used to create the keystore in various ways to obfuscate them to avoid that they appear in clear in configuration files.

7.4 Start Jetty with SPDY support

$ java -Xbootclasspath/p:lib/npn/npn-boot-<version>.jar -Xmx1g -XX:MaxPermSize=256m -jar $JETTY_HOME/start.jar


We have seen how JIRA 6.1 can be deployed to Jetty 9.1 following the steps above.
The advantage of using Jetty are the support for SPDY, which will improve the performance of the website, the high scalability of Jetty and the flexibility of Jetty in defining modules and starting only the modules needed by your web applications, and no more.
One disadvantage over Tomcat is the lack of out-of-the-box support for a transaction manager. While the step to add this support are not complicated, we recognize that it will be great if the transaction manager module would be available out-of-the-box.
We are working on providing such feature to improve Jetty, so stay tuned !


Leave a Reply

Avatar placeholder

Your email address will not be published. Required fields are marked *