Installing Jira on Glassfish. A Step by Step Guide.

18 July 2010 7:40 PM

For this installation we will be using:

  • Ubuntu Server 10.04
  • Glassfish V3
  • Jira 4.1.2
  • MySQL 5.1

Glassfish is not officially supported as a Jira Application Server, so we need to make some changes to get it to work. This guide is a compilation of several posts and information I’ve read over the internet.  It’s the first time I work with most of this technologies so what I did was just follow the instructions and do a little of research on my own,  but there are some things I barely understand.  So please  if you know a better way of how to do things, leave a comment,  so we all can learn and improve the guide.

Special thanks to:

  • Jason Lee for this tutorial
  • Michał Lipski for all the information shared here
  • Risky and Jordi for pointing out some mistakes I made

Now, lets start with the tutorial.

First of all,  we need to download  the WAR/EAR version of  Jira.

wget http://www.atlassian.com/software/jira/downloads/binary/atlassian-jira-enterprise-4.1.2.tar.gz

Untar the document

tar -xjvf atlassian-jira-enterprise-4.1.2.tar.gz

We will identify the newly created directory:  ./atlassian-jira-enterprise-4.1.2 as $JIRA_ROOT in this tutorial.

Fixing the Seraph Library

We need to change some code in one of Jira’s  libraries called Seraph and create a new jar file for it. I’ve uploaded a copy of the modified jar here, you can use it and skip this section. If you want to do it by yourself follow the incoming instructions.

Get the Seraph code from here:

https://svn.atlassian.com/svn/public/atlassian/seraph/tags/atlassian-seraph-2.1.4

Use your favorite SVN client to get the source. The directory of the project: atlassian-seraph-2.1.4 will be called $SERAPH_ROOT from now on.

To compile it we need to install the maven tool.  For Ubuntu type:

sudo apt-get install maven2

We also need to configure Atlassian Repositories in our maven settings.  To do this edit the file  /etc/maven2/settings.xml and add the following lines within the profiles section 1

<profile>
       <id>AtlassianProfile</id>
       <activation>
         <activeByDefault>true</activeByDefault>
       </activation>
 
       <repositories>
         <repository>
           <id>atlassian-public</id>
           <url>https://m2proxy.atlassian.com/repository/public</url>
           <snapshots>
             <enabled>true</enabled>
             <updatePolicy>daily</updatePolicy>
             <checksumPolicy>warn</checksumPolicy>
           </snapshots>
           <releases>
             <enabled>true</enabled>
             <checksumPolicy>warn</checksumPolicy>
           </releases>
         </repository>
 	      <repository>
 	        <id>atlassian-plugin-sdk</id>
           <url>file://${env.ATLAS_HOME}/repository</url>
           <snapshots>
             <enabled>false</enabled>
           </snapshots>
           <releases>
             <enabled>true</enabled>
             <checksumPolicy>warn</checksumPolicy>
           </releases>
         </repository>
       </repositories>
 
       <pluginRepositories>
         <pluginRepository>
           <id>atlassian-public</id>
           <url>https://m2proxy.atlassian.com/repository/public</url>
           <releases>
             <enabled>true</enabled>
             <checksumPolicy>warn</checksumPolicy>
           </releases>
           <snapshots>
             <checksumPolicy>warn</checksumPolicy>
           </snapshots>
         </pluginRepository>
       </pluginRepositories>
       <properties>
         <downloadSources>true</downloadSources>
         <downloadJavadocs>true</downloadJavadocs>
       </properties>
  </profile>

Now change the method init(), from the file BaseLoginFilter.java located in $SERAPH_ROOT/src/com/atlassian/seraph/filter,  to look like this:  2

public void init(FilterConfig config) {
        //log.warn("LoginFilter.init" + config.getFilterName());
        this.filterConfig = config;
 
        String configFileLocation = null;
 
        if (config.getInitParameter("config.file") != null) {
            configFileLocation = config.getInitParameter("config.file");
            //log.warn("Security config file location: " + configFileLocation);
        }
 
        securityConfig = SecurityConfigFactory.getInstance(configFileLocation);
        config.getServletContext().setAttribute(SecurityConfig.STORAGE_KEY, securityConfig);
        //log.warn("SecurityFilter.init completed successfully.");
    }

Change directory to $SERAPH_ROOT.  A file named pom.xml should be there.  To compile execute

mvn package

This command should build atlassian-seraph-2.1.4.jar inside the $SERAPH_ROOT/target folder.

Create a folder in $JIRA_ROOT/edit-webapp/WEB-INF/ called lib

mkdir $JIRA_ROOT/edit-webapp/WEB-INF/lib

Copy the new seraph library to there

cp $SERAPH_ROOT/target/atlassian-seraph-2.1.4.jar  $JIRA_ROOT/edit-webapp/WEB-INF/lib

The ejb-3_0-api.jar Library

I’m not sure about this step.  But in this bug thread they said its solves a problem.

Download the library ejb-3_0-api.jar

wget http://www.java2s.com/Code/JarDownload/ejb-3_0-api.jar.zip

Unzip and copy ejb-3_0-api.jar to $JIRA_ROOT/edit-webapp/WEB-INF/lib 3

cp ejb-3_0-api.jar $JIRA_ROOT/edit-webapp/WEB-INF/lib

The sun-web file

Classloader Delegation should be switched off for Jira to run properly.  This can be configured in the sun-web.xml  flie. 4

Put this file in $JIRA_ROOT/edit-webapp/WEB-INF/

The file should contain the following text

<?xml version="1.0" encoding="UTF-8"?>
 
<!DOCTYPE sun-web-app PUBLIC '-//Sun Microsystems, Inc.//DTD 
  Application Server 9.0 Servlet 2.5//EN' 
  'http://www.sun.com/software/appserver/dtds/sun-web-app_2_5-0.dtd'>
 
<sun-web-app>
  <class-loader delegate="false" />
</sun-web-app>

The Jira user

We will create a user called jira with a home directory in /usr/local/jira

sudo /usr/sbin/useradd --create-home --home-dir /usr/local/jira --shell /bin/bash jira

Before generating the WAR file we need to tell jira where it’s home directory is located and how it will be connected to a database.

Setting Jira Home

Edit the file $JIRA_ROOT/edit-webapp/WEB-INF/classes/jira-application.properties.  Locate the line referring to jira home and change it

jira.home = /usr/local/jira

Setting up the Database Connection

Edit the file $JIRA_ROOT/edit-webapp/WEB-INF/classes/entityengine.xml
In the transaction-factory section change jndi-name from java:comp/env/UserTransaction to UserTransaction.  As follows.

    <transaction-factory class="org.ofbiz.core.entity.transaction.JNDIFactory">
      <user-transaction-jndi jndi-server-name="default" jndi-name="UserTransaction"/>
      <transaction-manager-jndi jndi-server-name="default" jndi-name="UserTransaction"/>
    </transaction-factory>

In the datasource section change to the following

<datasource name="defaultDS" field-type-name="mysql"
helper-class="org.ofbiz.core.entity.GenericHelperDAO"
check-on-start="true"
use-foreign-keys="true"
use-foreign-key-indices="true"
check-fks-on-start="true"
check-fk-indices-on-start="true"
add-missing-on-start="true"
check-indices-on-start="true">
<jndi-jdbc jndi-server-name="default" jndi-name="jdbc/JiraDS"/>
</datasource>

Notice the removal of the line

schema-name="PUBLIC"

And the jndi-name again is changed from java:comp/env/jdbc/JiraDS to only jdbc/JiraDS 5
Later in this tutorial we will create the correspondent DataSource within Glassfish.

Creating the DB and DBuser

We need to create a jira specific database and a database user.  To do this we use MySQL console.

mysql -u root -p

Inside the console type

CREATE DATABASE jiradb CHARACTER SET UTF8;

To create the user and give it the appropriate permissions execute the following

GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,ALTER,INDEX on  jiradb.* TO 'jirauser'@'localhost' IDENTIFIED BY 'jirauserpasswd';

6

Downloading MySQL Connector For Java

To be able to use MySQL from Java,  as Jira does,  we need a special connector.
Download it from MySQL site

wget http://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-java-5.1.13.tar.gz/from/http://mirror.services.wisc.edu/mysql/

Untar the files

tar -zxvf mysql-connector-java-5.1.13.tar.gz

Copy the required library to your Glassfish external library directory. My GF installation directory is: /usr/local/glassfishv3/glassfish/. I’ll name it $GF_ROOT, so the ext lib directory is in: $GF_ROOT/domains/domain1/lib/ext or the one for your specific domain.

cp mysql-connector-java-5.1.13/mysql-connector-java-5.1.13-bin.jar $GF_ROOT/domains/domain1/lib/ext

Restart Glassfish
Change the working directory to your Glassfish bin folder.

cd $GF_ROOT/bin

Stop and start again the domain

./asadmin stop-domain domain1
./asadmin start-domain domain1

Creating the Data Source on Glassfish

Open your Glassfish web console.  If you left the default port set,  it should be accessible through  http://yoursite:4848,  for example

http://localhost:4848

Inside Glassfish Web Console Select Resources > Connection Pools

Click on new and fill out the form with the following values

Click on next.  In the second step of the Connection Pool creation, scroll down to Additional Properties. Erase all properties loaded by default and leave only the following:


Select the new connection pool and click ping to test it

You should see a “Ping Succeeded” message like this

Now, we need to create a JDBC Resource named JiraDS as we specified in the file entityengine.xml.  To do this,  click in JDBC resources.  And fill out the form with the following information,

Constructing the WAR File and Deploying

Change the current working directory to $JIRA_ROOT,  and execute

./build.sh war

The builder generates two WAR files,  one intended to be used on Tomcat,  and other dist-generic.  We will use the last one.
Copy the WAR file to your Glassfish autodeploy directory.  For example,

cp ./dist-generic/atlassian-jira-4.1.2.war /usr/local/glassfishv3/glassfish/domains/domain1/autodeploy/jira.war

Now Jira should be accessible through   http://yourserver:yourport/jira

http://localhost:8080/jira

About warnings…

Thanks to my new friend Benny Neugebauer I’ve know that Jira has some issues with the OpenJDK. Here’s a post in how to uninstall it and install the Sun version.

http://www.bennyn.de/webanwendungen/virtual-server/openjdk-deinstallieren.html

Also Benny wrote a post in how to properly set the mail.mime.decodeparameters to true. The post can be found here.

http://www.bennyn.de/webanwendungen/virtual-server/mail-mime-decodeparameters-setzen.html

Both posts are in German, but it’s easy to understand what you have to do by reading the commands and files involved. Thank you Benny :) .

Edits

Edit 20100824: Added a copy of the modified atlassian-seraph-2.1.4.jar .
Edit 20100831: Added links about how to solve Jira’s warnings.

<profile>
       <id>AtlassianProfile</id>
       <activation>
         <activeByDefault>true</activeByDefault>
       </activation>

       <repositories>
         <repository>
           <id>atlassian-public</id>
           <url>https://m2proxy.atlassian.com/repository/public</url>
           <snapshots>
             <enabled>true</enabled>
             <updatePolicy>daily</updatePolicy>
             <checksumPolicy>warn</checksumPolicy>
           </snapshots>
           <releases>
             <enabled>true</enabled>
             <checksumPolicy>warn</checksumPolicy>
           </releases>
         </repository>
 	      <repository>
 	        <id>atlassian-plugin-sdk</id>
           <url>file://${env.ATLAS_HOME}/repository</url>
           <snapshots>
             <enabled>false</enabled>
           </snapshots>
           <releases>
             <enabled>true</enabled>
             <checksumPolicy>warn</checksumPolicy>
           </releases>
         </repository>
       </repositories>

       <pluginRepositories>
         <pluginRepository>
           <id>atlassian-public</id>
           <url>https://m2proxy.atlassian.com/repository/public</url>
           <releases>
             <enabled>true</enabled>
             <checksumPolicy>warn</checksumPolicy>
           </releases>
           <snapshots>
             <checksumPolicy>warn</checksumPolicy>
           </snapshots>
         </pluginRepository>
       </pluginRepositories>
       <properties>
         <downloadSources>true</downloadSources>
         <downloadJavadocs>true</downloadJavadocs>
       </properties>
    </profile>
Read More