Pages

Sunday, 13 May 2012

Migrating Spring Application from Tomcat 7.0 to JBoss EAP 5.1

It may appear quite obvious that any Spring based web application that works under Tomcat should be working when deployed to JBoss EAP 5.1. In fact, this is further than the truth. Most often than not, the Spring based web application would just spew out tones of exception messages. This is exactly what happened when I tried to deploy a Spring 3.0.5/Hibernate 3.5.6 web application to JBoss EAP 5.1. I did finally get the application to work but not after spending many hours of trial and error to figure out the exceptions. Here are my eventual fixes.

1. Removed all the XML parsers under WEB-INF/lib directory, i.e. xmlParsers, xml-api, xalan, xerces.

2. Added hibernate-validator-4.1.0.Final.jar to WEB-INF/lib directory. For some unknown reason, JBoss EAP 5.1 absolutely need this.

3. Add 2 entries to hibernate.properties to pass into Spring. See text in red below.

hibernate.properties hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
hibernate.show_sql=true
hibernate.bytecode.use_reflection_optimizer=true
#hibernate.cglib.use_reflection_optimizer=true
#hibernate.cache.provider_class=org.hibernate.cache.HashtableCacheProvider
hibernate.cache.use_second_level_cache=true
hibernate.cache.region.factory_class=net.sf.ehcache.hibernate.EhCacheRegionFactory
hibernate.cache.provider_class=org.hibernate.cache.EhCacheProvider
hibernate.hbm2ddl.auto=update
hibernate.generate_statistics=true
hibernate.jdbc.batch_size=20
hibernate.validator.autoregister_listeners=false
hibernate.validator.apply_to_ddl=false

With these changes, the web application finally works.

Tuesday, 1 May 2012

Analysing Ant Project with Jenkins and Sonar

Jenkins(or Hudson) and Sonar are perhaps two of the most mature open source tools available today for implementing continuous integration. They comes with a plethora of features that make life easier at monitoring and managing quality of multiple software development projects. Out of the box, Sonar is designed for Maven project. However, it can be configured to work with Ant projects. The following steps show you how to achieve this:

Installation
1. Download this plugin Sonar Ant Jar
2. Copy the jar file into <ANT_HOME>/lib

This is very important, otherwise your project would not compile properly.

Configuration
Ant projects typically come with <PROJECT>.properties and <PROJECT>.xml files. So, just add the following code snippets into the existing ant build file. The code snippets assume that Sonar has already been installed to run at http://localhost:8080/sonar with Postgresql database.

myproject.properties #Application Information
app.name=myproject
app.version=1.0.0-RELEASE
app.prettyName=My Project
artifact.id=org.mycompany.myapp:myproject

# Sonar configuration
sonar.db.url=jdbc:postgresql://localhost:5432/sonar?charset=utf-8
sonar.db.driverClass=org.postgresql.Driver
sonar.db.username=username
sonar.db.password=password
sonar.web.url=http://localhost:8080/sonar

# For Linux
# ant.home=/usr/local/ant

# ForWindows
ant.home=C:/apps/ant


myproject.xml
<project name="My Project - Build" default="compile" basedir=".">
     
     <!-- Define the properties file -->
     <property file="myproject_build.properties"/>

     <!-- Sonar database configuration -->
     <property name="sonar.jdbc.url" value="${sonar.db.url}" />
     <property name="sonar.jdbc.driverClassName" value="${sonar.db.driverClass}" />
     <property name="sonar.jdbc.username" value="${sonar.db.username}" />
     <property name="sonar.jdbc.password" value="${sonar.db.password}" />


     <!-- Sonar url -->
     <property name="sonar.host.url" value="${sonar.web.url}" />


     <!-- Add the Sonar task -->
     <target name="sonar" depends="compile" description="Sonar static code analysis" >
       
         <taskdef name="sonar" classname="org.sonar.ant.SonarTask"
                       classpath="${ant.home}/lib/sonar-ant-task-1.3.jar" />
   
         <!-- list of mandatories Sonar properties -->
         <property name="sonar.sources" value="${src.home}" />


         <!-- list of optional Sonar properties -->
         <property name="sonar.projectName" value="${app.prettyName}" />
         <property name="sonar.binaries" value="${build.all}" />
         <property name="sonar.tests" value="${test.home}" />
             <path id="sonar.libraries">
                 <path refid="compile.classpath"/>
             </path>    
         <sonar key="${artifact.id}" version="${app.version}" />
    </target>
</project

Running
From the command prompt or inside your favourite IDE, run "ant -f myproject.xml sonar". This will take awhile depending on your project size. Once completed, myproject should show up on the project list inside Sonar.

Integrating with Jenkins/Hudson
Under "configure" panel, just add a new ant task to execute the "sonar" task.

Reference: 
1. For more details on Ant Task, see Analyse with Ant Task 
2. For more details on Jenkins, see Jenkins 
3. For more details on Sonar, see Sonar

Saturday, 28 April 2012

Running Liferay 6.1 CE on Non Root Context

By default Liferay 6.1 CE runs on root context after installation. Sometimes this may not be possible. Assuming that we would like Liferay 6.1 CE to work as http://<hostname>/myportal instead of http://<hostname>/, just make the following changes.

1. Under liferay-portal-6.1.0/tomcat-7.0.23/webapps directory
  • Rename directory ROOT to myportal
2. Under liferay-portal-6.1.0/tomcat-7.0.23/conf/Catalina/localhost directory
  • Rename file root to myportal
  • Edit myportal file and change  <Context path=""...> to  <Context path="/myportal"...>
3. Under  liferay-portal-6.1.0 directory
  • Edit portal-ext.properties (create one if it does not exist), add in portal.ctx=/myportal
4. After restarting Liferay, it is very important to perform the following additional step. Without making this change, a number of portlets such as message board would not work properly.
  • Login as portal administrator
  • Bring up "Control Panel" and click on "Portal Instances" under "Server" tab
  • Change the default value "localhost" at "Virtual Host" to the domain where Liferay is hosted.
5. Liferay should be working on http://<hostname>/myportal

Wednesday, 18 April 2012

Adding Apache document root permission to SELinux

On redhat linux with SELinux enabled, merely changing the document root path in the /etc/httpd/conf/httpd.conf file is not enough to make Apache work with the new location. Apache will give "File Not Found" error. To fix this problem, just use the following script. Make sure to change $HTTP_DOC to the location of the new apache document root.

#!/bin/sh

HTTP_DOC=/home/www/html

setsebool -P httpd_enable_homedirs on
chmod 755 $HTTP_DOC
chown -R apache.apache $HTTP_DOC
chcon -R -t httpd_sys_content_t $HTTP_DOC
 

Sunday, 15 April 2012

Running multiple Tomcat 7.0 as services on Windows

On a Window system with more than 8G of RAM, it is more beneficial to run multiple Tomcat 7.0. This can easily be achieved by following the steps outlined below.

1. Edit <TOMCAT_HOME>\bin\services.bat

















2. Edit <TOMCAT_HOME>\conf\server.xml

Saturday, 14 April 2012

Getting vTiger to work with Postgresql

Recently while looking at vTiger CRM, decided to spend some time getting it to work on Postgresql 9 database. It turned out to be a lot more work than I have initially anticipated. Someone has make quite a significant contribution to make vTiger working with Postgresql database. However, there is still a lot of work to be done. Most of the the problems are due to SQL syntax. I'm quite surprise at the syntax that works with MySQL. The list below contains the SQL syntax that are broken in Postgresql but works in MySQL.
  • Joining character field to integer field
  • Using '0000-00-00 00:00:00' as default date
  • Using limit min, max
  • Using duplicate index name
  • Using non standard GROUP BY syntax
  • Using double quote to enclose character data
  • Inserting NULL into integer field
  • Updating character field without enclosing it in single quote
  • Using MYSQL specific build-in functions
  • Comparing true/false on integer field
IMHO, some of these syntax should never be allowed in the first place. If only the developers were using standard SQL syntax, most of this problems would have been avoided. For more details on the work done, checkout  vTiger Postgresql Patch