Host and Run Your Java Tomcat Application for Free on OpenShift’s PaaS

Our users have asked for official Tomcat support on OpenShift and the team has listened! I am happy to annouce that OpenShift now officially supports Tomcat via our JBoss EWS cartridge. Adding this support allows developers to easily deploy their Spring applications to OpenShift while taking advantage of all the great features that a platform as a service (PaaS) provides.

Note: With a few tweaks to your application datasources, you can also deploy Spring based applications to the supported AS7 or EAP JBoss servers provided by OpenShift.

In this blog, I will talk about how you can port a Spring framework reference application to OpenShift. The reference application we will be using in this blog is the famous travel application. The code for this travel application exists in the official Spring subversion repository. OpenShift uses git by default, so I have pushed the code to a new git repository that I created for this post. This application is based on Spring 3.0 using both Spring MVC and Spring Webflow for the frontend. The application also uses JPA to persist entities to HSQLDB.

Step 1: Sign up for an OpenShift Account

If you don’t already have an OpenShift account, head on over to the website and sign up. It is completely free and Red Hat gives every user three free Gears on which to run your applications. At the time of this writing, the combined resources allocated for each user is 1.5 GB of memory and 3 GB of disk space.

Step 2: Install the client tools on your machine

Note: If you would rather watch a screencast of this step, check out the following videos where I demo how to install the client tools.

Windows

Linux Ubuntu

Linux Fedora

OSX

The OpenShift client tools are written in a very popular programming language called Ruby. With OSX 10.6 or later and most Linux distributions, Ruby is installed by default so installing the client tools is a snap. Simply issue the following command on your terminal application:

sudo gem install rhc

Step 3 : Setting up OpenShift

The rhc client tool makes it very easy to setup your OpenShift instance with ssh keys, git and your applications namespace. The namespace is a unique name per user which becomes part of your application url. For example, if your namespace is cix and application name is travel then url of the application will be travel-cix.rhcloud.com. The command is shown below.

rhc setup

Step 4 : Creating a Tomcat Gear

After setting up your OpenShift account, we need to create a gear which will contain the Tomcat environment where we can deploy our application. The -t option specifies the type of the application you want to create. In this blog, we are using jbossews. JBoss EWS is the JBoss Enterprise Web Server built on top on Apache Tomcat. JBoss Enterprise Web Server is a fully-integrated and certified set of components for hosting Java web applications. It is comprised of the web server (Apache HTTP Server), the Apache Tomcat Servlet container, load balancers (mod_jk and mod_cluster), and the Tomcat Native library.To create the tomcat application, execute the command shown below:

rhc app create travel jbossews

This command will create a directory named travel which contains a OpenShift template project. The application will be accessible now. Let us take a look at what’s inside the travel directory to better understand the layout of the EWS container.

  1. src directory : This directory contains the source code for the template application generated by OpenShift. You need to add your application source code here. The src folder helps in achieving source code deployment when following the standard maven directory conventions.
  2. pom.xml file: The Java applications created by OpenShift are Maven based projects. So, a pom.xml file is required when you do source code deployment on OpenShift. This pom.xml has a profile called “openshift” which will be executed when you push code to OpenShift as shown below. This profile will create a ROOT war file based upon your application source code.
    <profiles>
        <profile>
            <id>openshift</id>
            <build>
                <finalName>travel</finalName>
                <plugins>
                    <plugin>
                        <artifactId>maven-war-plugin</artifactId>
                        <version>2.1.1</version>
                        <configuration>
                            <outputDirectory>webapps</outputDirectory>
                            <warName>ROOT</warName>
                        </configuration>
                    </plugin>
                </plugins>
            </build>
        </profile>
    </profiles>
  3. webapps directory: You should use this directory in case you want to do binary deployments on OpenShift i.e. you want to deploy a war file directly instead of pushing the source code.
  4. .git directory : It is a local git repository
  5. .openshift directory : This is an OpenShift specific directory which can be used for following:
    1. the files under the action_hooks sub-directory allow you to hook into the application lifecycle.
    2. the files under the config sub-directory allow you to make changes to tomcat configuration. The directory contains tomcat specific configuration files like server.xml, context.xml, tomcat-users.xml, etc.
    3. the files under the cron sub-directory are used when you add the cron cartridge to your application. This allows you to run scripts or jobs on a periodic basis.
    4. the files under marker sub-directory allow you to specify whether you want to use Java 6 or Java 7, or you want to do hot deploy, or debug the application running in cloud, etc. The README file under the marker sub-directory provides all the marker files available.

Step 5 : Pulling Travel Application Source Code from GitHub

The next step is pulling the code from github. To do this run the following commands.

git rm -rf src/ pom.xml
git commit -am "removed default files"
git remote add upstream -m master git://github.com/shekhargulati/spring-travel.git
git pull -s recursive -X theirs upstream master

You can compile the code and run the application on your local system by executing mvn tomcat:run command. To deploy on OpenShift we have to add openshift maven profile which I talked earlier in the post. Add the profile to pom.xml as shown below. I have removed dependencies, repository, and plugins from pom.xml for brevity.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.springframework.samples</groupId>
    <artifactId>travel</artifactId>
    <name>travel</name>
    <packaging>war</packaging>
    <version>1.0.0-BUILD-SNAPSHOT</version>
    <properties>
        <java-version>1.6</java-version>
        <org.springframework-version>3.0.5.RELEASE</org.springframework-version>
        <org.springwebflow-version>2.2.1.RELEASE</org.springwebflow-version>
        <org.springsecurity-version>3.0.5.RELEASE</org.springsecurity-version>
        <org.aspectj-version>1.6.9</org.aspectj-version>
        <org.slf4j-version>1.6.1</org.slf4j-version>
    </properties>
    <dependencies>
        <!-- Dependencies -->
 
    </dependencies>
    <repositories>
        <!-- Repositories -->
 
    </repositories>
    <build>
        <plugins>
            <!--Plugins -->
        </plugins>
    </build>
 
    <profiles>
        <profile>
            <id>openshift</id>
            <build>
                <finalName>travel</finalName>
                <plugins>
                    <plugin>
                        <artifactId>maven-war-plugin</artifactId>
                        <version>2.1.1</version>
                        <configuration>
                            <outputDirectory>webapps</outputDirectory>
                            <warName>ROOT</warName>
                        </configuration>
                    </plugin>
                </plugins>
            </build>
        </profile>
    </profiles>
</project>

Step 6 : Deploying the application to OpenShift

Next you can push the code to git repository managed by OpenShift. To push the code execute the command shown below. This will run the maven openshift profile.

git commit -am "added openshift profile to pom.xml"
git push

Next when you go to your app, you will see the application homepage as shown below.

Step 7 : Adding PostgreSQL support

By default, the travel application comes bundled with an in-memory database called HSQLDB. Let’s update the code to use a very popular open source RDMS called PostgreSQL. Let’s first add PostgreSQL support to our application.

rhc cartridge add postgresql -a travel

The output returned by the command will be something like as shown below.

RESULT:
 
PostgreSQL 8.4 database added.  Please make note of these credentials:
 
   Root User: admin
   Root Password: EwiuS5_i4vfp
   Database Name: travel
 
Connection URL: postgresql://$OPENSHIFT_POSTGRESQL_DB_HOST:$OPENSHIFT_POSTGRESQL_DB_PORT/

The one change that you will find in the output shown above is that there are new environment variables for PostgreSQL databases.

Step 8 : Application Code changes required for PostgreSQL database

To make the application use PostgreSQL instead of HSQLDB we have to make few changes. Let’s take a look at them one by one.

  1. Adding maven dependencies : The first change that we have to make is to add Maven dependencies for PostgreSQL database driver and commons-dbcp for connection pooling as shown below.

    <dependency>
        <groupId>commons-dbcp</groupId>
        <artifactId>commons-dbcp</artifactId>
        <version>1.3</version>
        <exclusions>
            <exclusion>
                <groupId>commons-logging</groupId>
                <artifactId>commons-logging</artifactId>
            </exclusion>
            <exclusion>
                <groupId>xml-apis</groupId>
                <artifactId>xml-apis</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>postgresql</groupId>
        <artifactId>postgresql</artifactId>
        <version>8.4-702.jdbc4</version>
    </dependency>
  2. Updating persistence.xml  : The second change that we have to make is to update the peristence.xml with PostgreSQL hibernate dialect instead of HSQLDB. The persistence.xml is shown below.

    <?xml version="1.0" encoding="UTF-8"?>
    <persistence xmlns="http://java.sun.com/xml/ns/persistence"
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                 xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
                 version="1.0">
       <persistence-unit name="travelDatabase">
          <provider>org.hibernate.ejb.HibernatePersistence</provider>
          <class>org.springframework.samples.travel.User</class>
          <class>org.springframework.samples.travel.Booking</class>
          <class>org.springframework.samples.travel.Hotel</class>
          <properties>
             <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
             <property name="hibernate.hbm2ddl.auto" value="create-drop" />
             <property name="hibernate.show_sql" value="true"/>
             <property name="hibernate.cache.provider_class" value="org.hibernate.cache.HashtableCacheProvider"/>
          </properties>
       </persistence-unit>
    </persistence>
  3. Updating data.xml application context file: The last change that we have to make is in data.xm application context file. Replace hsqldb datasource with BasicDataSource in data.xml application context file as shown below and add PropertyPlaceholderConfigurer bean to replace ${…} placeholders.

    <context:property-placeholder/>
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
            <property name="driverClassName" value="org.postgresql.Driver"></property>
            <property name="username" value="${OPENSHIFT_POSTGRESQL_DB_USERNAME}"></property>
            <property name="password" value="${OPENSHIFT_POSTGRESQL_DB_PASSWORD}"></property>
            <property name="url" value="jdbc:postgresql://${OPENSHIFT_POSTGRESQL_DB_HOST}:${OPENSHIFT_POSTGRESQL_DB_PORT}/${OPENSHIFT_APP_NAME}"></property>
            <property name="testOnBorrow" value="true"></property>
            <property name="testOnReturn" value="true"></property>
            <property name="testWhileIdle" value="true"></property>
            <property name="timeBetweenEvictionRunsMillis" value="1800000"></property>
            <property name="numTestsPerEvictionRun" value="3"></property>
            <property name="minEvictableIdleTimeMillis" value="1800000"></property>
            <property name="validationQuery" value="SELECT version()"></property>
        </bean>

Step 9 : Pushing code to Git

After making all changes mentioned above we are ready to push the code to OpenShift. Execute the command shown below.

git commit -am "made all necessary changes for supporting PostgreSQL database."
git push

Step 10 : Play with the application

After the Maven build runs and the deployment is complete, you can start booking hotels in the app. The source code with PostgreSQL changes is on github.

Next Steps:

Automatic Updates

Stay informed and learn more about OpenShift by receiving email updates.

Categories
Java, JBoss, OpenShift Online, Tomcat, Videos
Tags
Comments are closed.