R, FastRWeb/Rserve (CGI) with Nginx and database support on Debian Linux

The following details how to install R with FastRWeb/Rserve support using Nginx web server on Debian Linux.

An acknowledgement is made in advance to this important post by Jay Emerson, which covers Apache2 / Ubuntu.

The procedure below has been tested on Debian 7u2 64 bit and should be applicable to Debian / Ubuntu Linux instances. At time of writing, R version 2.15 binaries are available in the default Debian repositories.

If building R from source ensure that it is configured with the option:

--enable-R-shlib

SE-Linux users should be aware that the FastRWeb CGI process will attempt to open a Unix socket connection in order to communicate with Rserve so users may need to adjust their security policy for FCGI accordingly.

An optional procedure for installing R-CRAN archived ggplot2 is included at the end of this post, and a sample script for use of ggplot2 with FastRWeb is included also.

It is assumed that the Debian installation is relatively clean and a functional Nginx has been installed.

For R package installation, build-essentials and a functional GCC is also required.

For some optional modules, a functional gfortran is also needed.

Cairo >1.2 should be installed. There is no requirement for a full X11 installation.

0: Install required Debian packages.

$ sudo apt-get update
$ sudo apt-get install fcgiwrap r-base

NB: libxml2 should be additionally installed if the R XML package is required.

The R XML package is not required for running FastRWeb.

1: Install required R-Packages from CRAN.

$ sudo apt-get update
$ sudo R
> install.packages('Rserve')
> install.packages('Cairo')
> install.packages('FastRWeb')
> # The following is not required, but will require libxml2 (see above) if installed
> install.packages('XML')
> # The following can be substituted for any other R database interface, or omitted
> install.packages('RPostgreSQL')
> quit()

Confirm the installation folder for the R packages:

$ sudo R
> system.file("", package="FastRWeb")
[1] "/usr/local/lib/R/site-library/FastRWeb/"
> quit()

Adjust $R_SITELIB_PATH=/usr/local/lib/R/site-library as per result [1].

2: Install FastRWeb:

$ cd $R_SITELIB_PATH
$ sudo ./install.sh

This creates the FastRWeb home folder: /var/FastRWeb

3: Configure Nginx.

In the following:

  • $WWW_ROOT = Nginx ‘root’ as defined in the sites-available file.
  • $WWW_USER = Account which has ownership of $WWW_ROOT (eg. www-data)
$ sudo mkdir $WWW_ROOT/cgi-bin
$ sudo cp $R_SITELIB_PATH/FastRWeb/cgi-bin/Rcgi $WWW_ROOT/cgi-bin/R
$ sudo chown -R $WWW_USER:$WWW_USER $WWW_ROOT/cgi-bin 

Edit the Nginx sites file located: /etc/nginx/sites-available).

Before the ‘server’ definition add:

map $request_uri $request_basename {
    ~/(?[^/?]*)(?:\?|$)
    $captured_request_basename;
}

Within the ‘server’ definition, add the following fastcgi ‘location’ definition for the FastRWeb cgi-bin executable.

NB: Substitute ‘$WWW_ROOT’ with the actual root.

location ~ ^/cgi-bin/R/.*$ {
    gzip           off;
    root           $WWW_ROOT;
    fastcgi_pass   unix:/var/run/fcgiwrap.socket;
    # include      fastcgi_params;
    fastcgi_param  QUERY_STRING       $query_string;
    fastcgi_param  REQUEST_METHOD     $request_method;
    fastcgi_param  CONTENT_TYPE       $content_type;
    fastcgi_param  CONTENT_LENGTH     $content_length;

    fastcgi_param  SCRIPT_FILENAME    $document_root/cgi-bin/R;
    fastcgi_param  SCRIPT_NAME        $request_filename;
    fastcgi_param  REQUEST_URI        $request_uri;
    fastcgi_param  DOCUMENT_URI       $document_uri;
    fastcgi_param  DOCUMENT_ROOT      $document_root;
    fastcgi_param  SERVER_PROTOCOL    $server_protocol;

    fastcgi_param  PATH_INFO          $request_basename; # Key for Rcgi

    fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
    fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;

    fastcgi_param  REMOTE_ADDR        $remote_addr;
    fastcgi_param  REMOTE_PORT        $remote_port;
    fastcgi_param  SERVER_ADDR        $server_addr;
    fastcgi_param  SERVER_PORT        $server_port;

    # According to RFC3875 (https://tools.ietf.org/html/rfc3875#section-4.1.14) in SERVER_NAME
    # we should put actual hostname user came to. For nginx it is in $http_host
    # This will allow to run multihost instances
    fastcgi_param  SERVER_NAME        $http_host;
}

Once updated, restart Nginx and ensure fastcgi is up.

$ sudo /etc/init.d/nginx restart
$ sudo /etc/init.d/fcgiwrap start

If there are errors during the Nginx restart check through the changes made to the site configuration file.

4: Update the Rserve configuration.

a) Security:

i) Change ownership of folders and files under: /var/FastRWeb to $WWW_USER (eg. www-data):

$ sudo chown -R $WWW_USER:$WWW_USER /var/FastRWeb

ii) Update file /var/FastRWeb/code/rserve.conf to have the following content:

umask 0007
socket /var/FastRWeb/socket
sockmod 0660
source /var/FastRWeb/code/rserve.R
control enable

(Added / modified lines in bold)

b) Start up packages:

Packages required by FastRWeb scripts can be pre-loaded by Rserve. These packages will then be available to all FastRWeb scripts.

The Rserve configuration is stored in the following file:

/var/FastRWeb/code/rserve.R

The relevant section of the file is as follows by default:

## This is jsut a friendly way to load package and report success/failure
## You will definiteily need FastRWeb, others are optional
pkgs <- c("XML", "Cairo", "Matrix", "FastRWeb") 
cat("Loading packages...\n")
for (pkg in pkgs) cat(pkg, ": ",require(pkg, quietly=TRUE, character.only=TRUE),"\n",sep='')

The bold line, pkgs <- …, needs to be updated.

If database support with package RPostgreSQL is required, update as follows:

## This is jsut a friendly way to load package and report success/failure
## You will definiteily need FastRWeb, others are optional
pkgs <- c("XML", "Cairo", "Matrix", "FastRWeb", "RPostgreSQL")
cat("Loading packages...\n")
for (pkg in pkgs) cat(pkg, ": ",require(pkg, quietly=TRUE, character.only=TRUE),"\n",sep='')

If XML support is not required the XML entry can be removed.

NB: Changes to this file would require a restart of Rserve.

5: Create an init script for Rserve.

a) Create file /etc/init.d/rserve with the following content, updating ‘WWW_USER’ if different to ‘www-data’:

#!/bin/sh
set -e

### BEGIN INIT INFO
# Provides:             Rserve
# Required-Start:       $nginx
# Required-Stop:        $nginx
# Should-Start:         $syslog
# Should-Stop:          $syslog
# Default-Start:        2 3 4 5
# Default-Stop:         0 1 6
# Short-Description:    Rserve Daemon
### END INIT INFO

# WWW_USER - Update the following if Nginx running in different context.
WWW_USER=www-data

# Must be a valid filename
NAME=rserve
PIDFILE=/var/run/$NAME.pid

#This is the command to be run, give the full pathname
DAEMON='/var/FastRWeb/code/start'
DAEMON_OPTS="--daemon --quiet"

export PATH="${PATH:+$PATH:}/usr/sbin:/sbin"
cd /var/FastRWeb/code/

case "$1" in
  start)
        echo -n "Starting daemon: "$NAME
        start-stop-daemon --start --quiet --chuid $WWW_USER:$WWW_USER \ 
--background --exec $DAEMON -- $DAEMON_OPTS > /dev/null
        echo "."
        ;;
  stop)
        echo -n "Stopping daemon: "$NAME
        killall -INT Rserve
        echo "."
        ;;
  restart)
        echo -n "Restarting daemon: "$NAME
        killall -INT Rserve
        start-stop-daemon --start --quiet --chuid $WWW_USER:$WWW_USER \
--exec $DAEMON -- $DAEMON_OPTS > /dev/null &
        echo "."
        ;;

  *)
        echo "Usage: "$1" {start|stop|restart}"
        exit 1
esac

exit 0

b) Make the rserve init.d script executable:

$ sudo chmod 750 /etc/init.d/rserve

c) For Rserve to automatically start with the operating system update the start up resources:

$ sudo update-rc.d rserve defaults

6: Create a test FastRWeb R Script.

FastRWeb R scripts are located by default in the following location:

/var/FastRWeb/web.R

To test the installation and configuration create the file:

/var/FastRWeb/web.R/foo.png.R

With this content:

# foo.png.R:
run <- function(n=100, ...) {
    n <- as.integer(n)
    p <- WebPlot(800, 600)
    plot(rnorm(n), rnorm(n), pch=19, col=2)
    p
}

7: Start up Rserve and test FastRWeb

a) If Nginx is stopped, start Nginx.
b) Start Rserve

$ sudo /etc/init.d/rserve start

c) Assuming the Nginx is serving cgi-bin on localhost/cgi-bin, navigate to:

http://localhost/cgi-bin/R/foo.png?n=500

An 800×600 scatter-plot image should be displayed.

Optional: Archive installation of ggplot2 and use of ggplot2 with FastRWeb

At time of writing R version 2.15 was available from Debian repositories.

The CRAN ggplot2 package hosted on mirrors requires R 3.0 or higher.

The following procedure installs a functional ggplot2 from CRAN archive into R 2.15 which can be used with FastRWeb. (Strictly not recommended for production use.)

The test script below shows how to use ggplot2 with FastRWeb.

a) Perform a baseline (broken) installation of ggplot2 with current compatible dependencies available from CRAN:

$ sudo R
> install.packages("ggplot2", dependencies=TRUE)

This will break on a number of dependencies towards the end.

b) Correct the baseline installation by installing R-CRAN archive packages.

These archive packages were located by looking for the last releases from 2012 – close to R 2.15’s date.

They may be substituted with compatible packages located in the archive, and packages may need to be added to the following depending on installed R version and CRAN updates.

$ sudo R
> installarchive <- function(url, pkgFile) {
>    download.file(url = url, destfile = pkgFile)
>    install.packages(pkgs=pkgFile, type="source", repos=NULL)
>    unlink(pkgFile)
> }
> installarchive('http://cran.r-project.org/src/contrib/Archive/plyr/plyr_1.8.tar.gz','plyr_1.8.tar.gz')
> installarchive('http://cran.r-project.org/src/contrib/Archive/reshape2/reshape2_1.2.2.tar.gz','reshape2_1.2.2.tar.gz')
> installarchive('http://cran.r-project.org/src/contrib/Archive/scales/scales_0.2.3.tar.gz','scales_0.2.3.tar.gz')
> installarchive('http://cran.r-project.org/src/contrib/Archive/ggplot2/ggplot2_0.9.3.tar.gz','ggplot2_0.9.3.tar.gz')

The following are not required for a functional ggplot2 operation:

  • acepack
  • mvtnorm
  • multcomp
  • Hmisc

If these packages are required then a working gfortran should be installed.

Once gfortran is installed, the following will install these packages:

$ sudo R
> installarchive <- function(url, pkgFile) {
>    download.file(url = url, destfile = pkgFile)
>    install.packages(pkgs=pkgFile, type="source", repos=NULL)
>    unlink(pkgFile)
> }
> installarchive('http://cran.r-project.org/src/contrib/Archive/acepack/acepack_1.3-3.2.tar.gz','acepack_1.3-3.2.tar.gz')
> installarchive('http://cran.r-project.org/src/contrib/Archive/Hmisc/Hmisc_3.10-1.tar.gz','Hmisc_3.10-1.tar.gz')
> installarchive('http://cran.r-project.org/src/contrib/Archive/mvtnorm/mvtnorm_0.9-9994.tar.gz','mvtnorm_0.9-9994.tar.gz')
> installarchive('http://cran.r-project.org/src/contrib/Archive/multcomp/multcomp_1.2-14.tar.gz','mvtnorm_0.9-9994.tar.gz','multcomp_1.2-14.tar.gz')

c) Update Rserve

Add ggplot2 to the list of packages to be loaded by default in:

/var/FastRWeb/code/rserve.R
## This is jsut a friendly way to load package and report success/failure
## You will definiteily need FastRWeb, others are optional
pkgs <- c("XML", "Cairo", "Matrix", "FastRWeb", "RPostgreSQL", "ggplot2")
cat("Loading packages...\n")
for (pkg in pkgs) cat(pkg, ": ",require(pkg, quietly=TRUE, character.only=TRUE),"\n",sep='')

It will be necessary to restart Rserve if Rserve was previously running.

$ sudo /etc/init.d/rserve restart

d) Create a ggplot2 FastRWeb R script.

Create file /var/FastRWeb/web.R/ggplottest.png.R with the following content:

# ggplottest.png.R
run <- function(...) {
    p <- WebPlot(800,600)
    gp <- ggplot(diamonds, aes(clarity, fill=cut))+geom_bar()
    print(gp)
    p
}

e) Test the installation.

Navigate to the following location:

http://localhost/cgi-bin/R/ggplottest.png

A chart of size 800×600 should be displayed for ggplot2 diamonds data.

Further resources:

Advertisements

Tomcat 7 JNDI : Limitations and solution for enterprise application

Tomcat 7 is a very good Servlet Container.

However – in practice Tomcat finds itself drafted to be used as an Application Server (AS) rather than Servlet container in many situations. In particular in development.

Tomcat 7 JNDI is explicitly not designed to allow real AS use though.

In particular it is limited to:

i) Being configurable (via server.xml / context.xml) to only add items to context’s rooted: java:comp/env

(I am ignoring the <TRANSACTION> tag here…)

ii) The Tomcat JNDI takes exclusive control of java: namespace. This means that if using a separate Initial Factory Context which is declaring java: items, these will be hidden from the regular Tomcat runtime.

iii) There is no visibility into the loaded JNDI structure through the included management tool.

The minimal consequence of this is that certain solutions developed on Tomcat will be forced to contain configurations which are not compatible with real AS’s.

The bigger picture though is that there is a certain degree of uncertainty involved with setting up object within JNDI – particularly if dependent components are locked to referencing items outside of java:/comp/env, and if working with separate distinct Initial Contexts – for example that of the Bitronix Transaction manager.

To address these issues and provide visibility and a bridge between Tomcat and the real AS world a Tomcat JNDI Management interface has been implemented.

It is downloadble from here: http://sourceforge.net/projects/jndimanagertc7/

The help file / further information (included in the above) can be viewed here: https://ironclaws.files.wordpress.com/2012/07/jndimanagerhelp_v1.pdf

 

 

JBPM 5.3 / Tomcat 7 / H2 / Demo

The following details how to install jBPM 5.3 onto Tomcat 7, configured to run the provided ‘Demo’.
re
A H2 database instance shall be used – which is reflected in the JTA / Hibernate configuration specified below.

The following are assumed installed and relatively clean:

NB: Tomcat should be stopped prior to installation.

0: Download required software:

JBPM : Select 5.3.0 – Final Installer Full

Once downloaded, unzip to a staging area separate from Tomcat – subsequent actions below will take place within the ‘jbpm-install’ folder.

1: Pre-Installation Configuration of Tomcat: Prepare for J2EE
It should be understood that Tomcat is not a J2EE application server – but rather a servlet container.

However – Tomcat can be made to behave like a J2EE application server.

In order to make this so, J2EE components need to be installed and configured on Tomcat.

For JBPM this is an apriori requirement. The steps below shall add the following J2EE services to Tomcat:

  • JTA (Java Transaction API)
  • Bitronix 2.1.3 Transaction Manager
  • JMS
  • JACC

a) In jbpm-install create folder: tomcat2j2ee

b) In jbpm-install\tomcat2j2ee create the following files:

ivy.xml

<ivy-module version="2.0">
<info organisation="jbpm" module="btm" />
<dependencies>
    <dependency org="org.codehaus.btm" name="btm-dist" rev="2.1.3" />
	<dependency org="org.codehaus.btm" name="btm" rev="2.1.3">
		<artifact name="btm" type="jar" />
	</dependency>

	<dependency org="javax.transaction" name="jta" rev="1.1">
		<artifact name="jta" type="jar" />
	</dependency>
	
    <dependency org="org.apache.geronimo.specs" name="geronimo-jacc_1.1_spec" rev="1.0.2" >
		<artifact name="geronimo-jacc_1.1_spec" type="jar" />
	</dependency>
    </dependencies>
</ivy-module>

build.xml


<?xml version="1.0" encoding="UTF-8"?>

<project xmlns:ivy="antlib:org.apache.ivy.ant" name="J2EE.install">

  <property name="install.home" value="./" />

  <property environment="env"/>
  <property name="tomcat.home" value="${env.CATALINA_HOME}"/>  
  <property name="tomcat.7.server.lib.dir" value="${tomcat.home}/lib" />

  <!-- ############ TOP LEVEL INSTALLATION ########### -->
  <target name="install.j2ee.to.tomcat.7" depends="download.j2ee">
	<copy todir="${tomcat.7.server.lib.dir}/">
	    <fileset dir="${install.home}/lib" includes="*.jar" />
    </copy>
  </target>

  <target name="download.j2ee.check">
    <echo message="Checking J2EE Download..." />
	<condition property="btm.not.available">
	  <not>
	    <available file="${install.home}/lib/btm-2.1.3.jar" />
	  </not>
	</condition>
  </target>
  <target name="download.j2ee" depends="download.j2ee.check" if="btm.not.available">
    <echo message="Getting J2EE..." />
	<mkdir dir="${install.home}/lib"/>
	<ivy:retrieve />  
  </target>
  
</project>

c) In jbpm-install\tomcat2j2ee execute:

ant install.j2ee.to.tomcat.7

d) Create the following file in ${CATALINA_HOME}\conf

btm-config.properties

bitronix.tm.serverId=tomcat-btm-node0
bitronix.tm.journal.disk.logPart1Filename=${btm.root}/work/btm1.tlog
bitronix.tm.journal.disk.logPart2Filename=${btm.root}/work/btm2.tlog
bitronix.tm.resource.configuration=${btm.root}/conf/resources.properties

e) Add the following parameters to $CATALINA_OPTS – such that they are passed to JVM when Tomcat starts:

-Dbtm.root=${CATALINA_HOME}
-Dbitronix.tm.configuration=${CATALINA_HOME}/conf/btm-config.properties

NB: On windows do this through the configuration tool – do not set environment variable unless you understand the implications.
You will need to specify ${CATALINA_HOME} in full rather than using environment variable.

You should now have a Tomcat 7 installation with J2EE services required for JBPM present.

2: Installation JBPM 5.3 : Pre-Configuration

The installation process for JBPM 5.3 shall be presented in script form below.

Before that step though it is required to create and perform some initial configuration of both JBPM and Tomcat.

i) Configuration of Tomcat

a) Reconfigure ${CATALINA_HOME}/server.xml

Add following entries to ${CATALINA_HOME}/server.xml after the server entry for: org.apache.catalina.core.JreMemoryLeakPreventionListener

<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Listener className="bitronix.tm.integration.tomcat55.BTMLifecycleListener" />

Add the following entries to the section:

<Resource name="jdbc/testDS1" uniqueName="jdbc/testDS1" auth="Container" removeAbandoned="true" factory="bitronix.tm.resource.ResourceObjectFactory" type="javax.sql.DataSource" />
<Resource name="jta/UserTransaction" auth="Container" type="javax.transaction.UserTransaction" factory="bitronix.tm.BitronixUserTransactionObjectFactory" /> 
<Resource name="TransactionManager" auth="Container" type="javax.transaction.TransactionManager" factory="bitronix.tm.BitronixTransactionManagerObjectFactory" />
<Resource name="TransactionSynchronizationRegistry" auth="Container" type="javax.transaction.TransactionSynchronizationRegistry" factory="bitronix.tm.BitronixTransactionSynchronizationRegistryObjectFactory" />

b) Reconfigure ${CATALINA_HOME}/context.xml

Add the following entries to context.xml after ‘WatchedResource’:

<Transaction factory="bitronix.tm.BitronixUserTransactionObjectFactory" />
<!-- To make java:comp/env/testDS1 available for reports - via jdbc/testDS1 -->
<ResourceLink global="jdbc/testDS1" name="jdbc/testDS1" type="javax.sql.DataSource" /> 
<ResourceLink global="jta/UserTransaction" name="UserTransaction" type="javax.transaction.UserTransaction" />

NB: The Birt reporting by default will use Tomcat JNDI to look up resources.

The global resources defined in server.xml in terms of Bitronix JNDI are aliased to Tomcat’s JNDI using resourcelink’s above.

The hibernate configuration (below…) uses the Bitronix JNDI references

ii) Configuration of JBPM

a) Create the following files in: jbpm-install\db

resources.properties

resource.ds1.className=bitronix.tm.resource.jdbc.lrc.LrcXADataSource
resource.ds1.uniqueName=jdbc/testDS1
resource.ds1.minPoolSize=0
resource.ds1.maxPoolSize=5
resource.ds1.driverProperties.driverClassName=org.h2.Driver
resource.ds1.driverProperties.url=jdbc:h2:tcp://localhost/~/test
resource.ds1.driverProperties.user=sa
resource.ds1.driverProperties.password=
resource.ds1.allowLocalTransactions=true
resource.ds1.testQuery=SELECT 1+1

persistence.xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<persistence
    version="1.0"
    xsi:schemaLocation=
    	"http://java.sun.com/xml/ns/persistence
    	 http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd
		 http://java.sun.com/xml/ns/persistence/orm 
		 http://java.sun.com/xml/ns/persistence/orm_1_0.xsd"
    xmlns:orm="http://java.sun.com/xml/ns/persistence/orm"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/persistence">

	<persistence-unit name="org.jbpm.persistence.jpa" transaction-type="JTA">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <jta-data-source>jdbc/testDS1</jta-data-source>       
    <mapping-file>META-INF/JBPMorm.xml</mapping-file>
    <mapping-file>META-INF/ProcessInstanceInfo.hbm.xml</mapping-file>
    <class>org.jbpm.persistence.processinstance.ProcessInstanceInfo</class>
    <class>org.drools.persistence.info.WorkItemInfo</class>
    <class>org.drools.persistence.info.SessionInfo</class>	
    <class>org.jbpm.process.audit.ProcessInstanceLog</class>
    <class>org.jbpm.process.audit.NodeInstanceLog</class>
    <class>org.jbpm.process.audit.VariableInstanceLog</class>
    <properties>
		<property name="hibernate.jndi.class" value="bitronix.tm.jndi.BitronixInitialContextFactory"/> 
		<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
		<property name="hibernate.connection.datasource" value="jdbc/testDS1" />
		<property name="hibernate.max_fetch_depth" value="3"/>
		<property name="hibernate.hbm2ddl.auto" value="update" />
		<property name="hibernate.show_sql" value="false" />  
		<property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.BTMTransactionManagerLookup" />
    </properties>        
  </persistence-unit>
</persistence>

persistence-human-task-service.xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<persistence version="1.0" 
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
                                 http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd
                                 http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_1_0.xsd"
             xmlns:orm="http://java.sun.com/xml/ns/persistence/orm"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns="http://java.sun.com/xml/ns/persistence">
  <persistence-unit name="org.jbpm.task">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <mapping-file>META-INF/Taskorm.xml</mapping-file>
    <class>org.jbpm.task.Attachment</class>
    <class>org.jbpm.task.Content</class>
    <class>org.jbpm.task.BooleanExpression</class>
    <class>org.jbpm.task.Comment</class>
    <class>org.jbpm.task.Deadline</class>
    <class>org.jbpm.task.Comment</class>
    <class>org.jbpm.task.Deadline</class>
    <class>org.jbpm.task.Delegation</class>
    <class>org.jbpm.task.Escalation</class>
    <class>org.jbpm.task.Group</class>
    <class>org.jbpm.task.I18NText</class>
    <class>org.jbpm.task.Notification</class>
    <class>org.jbpm.task.EmailNotification</class>
    <class>org.jbpm.task.EmailNotificationHeader</class>
    <class>org.jbpm.task.PeopleAssignments</class>
    <class>org.jbpm.task.Reassignment</class>
    <class>org.jbpm.task.Status</class>
    <class>org.jbpm.task.Task</class>
    <class>org.jbpm.task.TaskData</class>
    <class>org.jbpm.task.SubTasksStrategy</class>
    <class>org.jbpm.task.OnParentAbortAllSubTasksEndStrategy</class>
    <class>org.jbpm.task.OnAllSubTasksEndParentEndStrategy</class>
    <class>org.jbpm.task.User</class>
    <properties>
      <property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
      <property name="hibernate.connection.driver_class" value="org.h2.Driver"/>
      <property name="hibernate.connection.url" value="jdbc:h2:tcp://localhost/~/test" />
      <property name="hibernate.connection.username" value="sa"/>
      <property name="hibernate.connection.password" value=""/>
      <property name="hibernate.connection.autocommit" value="false" />
      <property name="hibernate.max_fetch_depth" value="3"/>
      <property name="hibernate.hbm2ddl.auto" value="update" />
      <property name="hibernate.show_sql" value="false" />      
	  <property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.BTMTransactionManagerLookup" />
    </properties>
  </persistence-unit>
</persistence>

persistence-human-task-war.xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<persistence version="1.0" 
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
                                 http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd
                                 http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_1_0.xsd"
             xmlns:orm="http://java.sun.com/xml/ns/persistence/orm"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns="http://java.sun.com/xml/ns/persistence">
  <persistence-unit name="org.jbpm.task">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <mapping-file>META-INF/Taskorm.xml</mapping-file>
    <class>org.jbpm.task.Attachment</class>
    <class>org.jbpm.task.Content</class>
    <class>org.jbpm.task.BooleanExpression</class>
    <class>org.jbpm.task.Comment</class>
    <class>org.jbpm.task.Deadline</class>
    <class>org.jbpm.task.Comment</class>
    <class>org.jbpm.task.Deadline</class>
    <class>org.jbpm.task.Delegation</class>
    <class>org.jbpm.task.Escalation</class>
    <class>org.jbpm.task.Group</class>
    <class>org.jbpm.task.I18NText</class>
    <class>org.jbpm.task.Notification</class>
    <class>org.jbpm.task.EmailNotification</class>
    <class>org.jbpm.task.EmailNotificationHeader</class>
    <class>org.jbpm.task.PeopleAssignments</class>
    <class>org.jbpm.task.Reassignment</class>
    <class>org.jbpm.task.Status</class>
    <class>org.jbpm.task.Task</class>
    <class>org.jbpm.task.TaskData</class>
    <class>org.jbpm.task.SubTasksStrategy</class>
    <class>org.jbpm.task.OnParentAbortAllSubTasksEndStrategy</class>
    <class>org.jbpm.task.OnAllSubTasksEndParentEndStrategy</class>
    <class>org.jbpm.task.User</class>
    <properties>
	  <property name="hibernate.jndi.class" value="bitronix.tm.jndi.BitronixInitialContextFactory"/> 	  
      <property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
	  <property name="hibernate.connection.datasource" value="jdbc/testDS1" />
	  <property name="hibernate.max_fetch_depth" value="3"/>
      <property name="hibernate.hbm2ddl.auto" value="update" />
      <property name="hibernate.show_sql" value="false" />
      <property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.BTMTransactionManagerLookup" />
    </properties>
  </persistence-unit>
</persistence>

NB: The above configurations will make use of H2 backend database – data sources are configured through JNDI using Bitronix as initial context.

b) Create the following file in: jbpm-install\conf
web.humantaskwar.xml

<web-app>
  <display-name>Human Task Service WAR</display-name>
  <servlet>
    <servlet-name>HumanTaskServiceServlet</servlet-name>
      <servlet-class>org.jbpm.task.servlet.HumanTaskServiceServlet</servlet-class>
      
      <!-- Following is a list of initialization parameters that HumanTaskService Servlet accepts
      	   Main controller is active.config parameter that dictates what transport to initialize.
      	   
      	   Then there are transport specific parameters that should be filled in only for selected
      	   transport.
      	   
      	   Last part provides access to configuring components of task Service itself. All of them
      	   are optional and in case there are not set default values will apply.
       -->
      
      <!-- active configuration on of hornetq|mina|jms (defauls to hornetq) -->
      <init-param>
      	<param-name>active.config</param-name>
      	<param-value>mina</param-value>
      </init-param>
      
      <!-- Apache Mina configuration parameters -->
      <init-param>
      	<param-name>mina.host</param-name>
      	<param-value>localhost</param-value>
      </init-param>
      <init-param>
      	<param-name>mina.port</param-name>
      	<param-value>9123</param-value>
      </init-param>
      
      <!-- HornetQ configuration parameters -->
      <init-param>
      	<param-name>hornetq.port</param-name>
      	<param-value></param-value>
      </init-param>
      
      <!-- JMS configuration parameters -->
      <init-param>
      	<param-name>JMSTaskServer.connectionFactory</param-name>
      	<param-value></param-value>
      </init-param>
      <init-param>
      	<param-name>JMSTaskServer.transacted</param-name>
      	<param-value></param-value>
      </init-param>
      <init-param>
      	<param-name>JMSTaskServer.acknowledgeMode</param-name>
      	<param-value></param-value>
      </init-param>
      <init-param>
      	<param-name>JMSTaskServer.queueName</param-name>
      	<param-value></param-value>
      </init-param>
      <init-param>
      	<param-name>JMSTaskServer.responseQueueName</param-name>
      	<param-value></param-value>
      </init-param>
      
      <!-- Task Service configuration independent of transport -->
      <init-param>
      	<param-name>task.persistence.unit</param-name>
      	<param-value>org.jbpm.task</param-value>
      </init-param>
      <!-- use org.jbpm.task.service.DefaultUserGroupCallbackImpl to configure sample user group callback for demo purpose-->
      <init-param>
      	<param-name>user.group.callback.class</param-name>
      	<param-value>org.jbpm.task.service.DefaultUserGroupCallbackImpl</param-value>
      </init-param>
      <init-param>
      	<param-name>escalated.deadline.handler.class</param-name>
      	<param-value></param-value>
      </init-param>
      <init-param>
      	<param-name>user.info.class</param-name>
      	<param-value></param-value>
      </init-param>
      <!-- allows to specify location of a files that will be used to initially populate task server db -->
      <!-- accepts two types of files: MVEL and properties must be suffixed with .mvel and .properties -->
      <!-- location of the files can be either on classpath (with prefix classpath:) or valid URL -->
      <!-- NOTE: that with custom users files Administrator user must always be present!!! -->
      <!-- use classpath:/org/jbpm/task/servlet/SampleUsers.mvel to configure sample users for demo purpose-->
      <!-- DefaultUsers.mvel is used to insert Administrator as it is required for task server to operate -->
      <init-param>
        <param-name>load.users</param-name>
        <param-value>classpath:/org/jbpm/task/servlet/DefaultUsers.mvel</param-value>
      </init-param>
      <!-- use classpath:/org/jbpm/task/servlet/SampleGroups.mvel to configure sample users for demo purpose-->
      <init-param>
        <param-name>load.groups</param-name>
        <param-value></param-value>
      </init-param>
      
    <load-on-startup>2</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>HumanTaskServiceServlet</servlet-name>
    <url-pattern>/HumanTaskServiceServlet/*</url-pattern>
  </servlet-mapping>
</web-app>

Checkpoint: We have at this point installed required J2EE services to Tomcat, configured JNDI datasource components for JBPM on Tomcat and prepared a configuration of JBPM 5.3 to be installed.
The next step is to perform the JBPM installation to Tomcat.

3: Installation JBPM 5.3

a) Add the following to the end of: jbpm-install\build.properties

# Tomcat Server Version
tomcat.server.version=7
# Database Parameters
# H2
h2.jdbc.driver.version=1.3.161
# Defines MySQL Connect JDBC Driver to Use
mysql.jdbc.driver.version=5.1.20

b) Create the following files in jbpm-install:

ivy.xml

<ivy-module version="2.0">
<info organisation="jbpm" module="btm" />
<dependencies>	
	<dependency org="javassist" name="javassist" rev="3.4.GA">
		<artifact name="javassist" type="jar" />
	</dependency>
	<dependency org="org.jboss.weld.servlet" name="weld-servlet" rev="1.1.8.Final">
		<artifact name="weld-servlet" type="jar" />
	</dependency>
</dependencies>
</ivy-module>

tomcat7build.xml

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns:ivy="antlib:org.apache.ivy.ant" name="jBPM.install">
  <property file="build.properties" />
  <property name="install.home" value="./" />
  <property environment="env"/>
  <property name="tomcat.home" value="${env.CATALINA_HOME}"/>  
  <property name="tomcat.7.server.conf.dir" value="${tomcat.home}/conf" />
  <property name="tomcat.7.server.lib.dir" value="${tomcat.home}/lib" />
  <property name="tomcat.7.server.deploy.dir" value="${tomcat.home}/webapps" />
  <property name="tomcat.bind.address" value="localhost" />
  <property name="h2.jdbc.jar" value="h2-${h2.jdbc.driver.version}.jar" />
  <property name="h2.download.url" value="http://repo1.maven.org/maven2/com/h2database/h2/${h2.jdbc.driver.version}/${h2.jdbc.jar}"/>
  <property name="mysql.jdbc.jar" value="mysql-connector-java-${mysql.jdbc.driver.version}.jar" />
  <property name="mysql.download.url" value="http://repo1.maven.org/maven2/mysql/mysql-connector-java/${mysql.jdbc.driver.version}/${mysql.jdbc.jar}"/>
  <property name="birt.version.as7" value="3_7_0"/>  

<property name="birt.download.url.as7" value="http://www.eclipse.org/downloads/download.php?file=/birt/downloads/drops/R-R1-3_7_0-201106151818/birt-runtime-3_7_0.zip&amp;url=http://download.eclipse.org/birt/downloads/drops/R-R1-3_7_0-201106151818/birt-runtime-3_7_0.zip&amp;mirror_id=1"/>
  
  <!-- ############ TOP LEVEL INSTALLATION ########### -->
  <target name="install.jbpmfull.to.tomcat.7">
    <antcall target="download.dependencies" />
  	<antcall target="install.bitronix.config.into.tomcat.7" /> 
  	<antcall target="install.jBPM.into.tomcat.7" />
	<antcall target="install.guvnor.into.tomcat.7" />
	<antcall target="install.designer.into.tomcat.7" />
	<antcall target="install.form.builder.into.tomcat.7" />
	<antcall target="install.ht.war.into.tomcat.7" />	
  </target>

  <target name="start.demo">
  	<antcall target="install.jBPM.runtime" />
  	<antcall target="start.human.task" />
  </target>
  
  <!-- ############ TOMCAT SUPPORT ########### -->  
  
  <target name="check.tomcat.version">
    <condition property="tomcat.version.is.7">
      <equals arg1="${tomcat.server.version}" arg2="7" />
    </condition>
  </target>
 
  <!-- ############ DOWNLOAD ############ -->

  <!-- Dependencies -->
  <target name="download.dependencies">
    <echo message="Getting Dependencies ..." />
    <mkdir dir="${install.home}/lib"/>
	<ivy:retrieve />  
  </target>
  
  <!-- Databases -->
  <!-- Download H2 -->
  <target name="download.h2.check">
    <echo message="Checking H2 download ..." />
    <condition property="h2.not.available">
      <not>
        <available file="${install.home}/db/driver/${h2.jdbc.jar}" />
      </not>
    </condition>
  </target>
  <target name="download.h2" depends="download.h2.check" if="h2.not.available">
    <echo message="Getting H2..." />
    <mkdir dir="${install.home}/db/driver"/>
    <get src="${h2.download.url}" dest="${install.home}/db/driver/${h2.jdbc.jar}"  />
  </target>
  
  <!-- Download MySQL -->
  <target name="download.mysql.check">
    <echo message="Checking MySql download..." />
    <condition property="mysql.not.available">
      <not>
        <available file="${install.home}/db/driver/${mysql.jdbc.jar}" />
      </not>
    </condition>
  </target>
  <target name="download.mysql" depends="download.mysql.check" if="mysql.not.available">
    <echo message="Getting MySql ..." />
    <mkdir dir="${install.home}/db/driver"/>
    <get src="${mysql.download.url}" dest="${install.home}/db/driver/${mysql.jdbc.jar}"  />
  </target>
  
  <!-- Download jBPM binaries -->
  <target name="download.jBPM.bin.check">
    <echo message="Checking jBPM binaries download ..." />
    <condition property="jBPM.bin.not.available">
      <not>
        <available file="${install.home}/lib/jbpm-${jBPM.version}-bin.zip" />
      </not>
    </condition>
  </target>
  <target name="download.jBPM.bin" depends="download.jBPM.bin.check" if="jBPM.bin.not.available">
    <echo message="Getting jBPM binaries ..." />
    <mkdir dir="${install.home}/lib"/>
    <get src="${jBPM.url}/jbpm-${jBPM.version}-bin.zip" dest="${install.home}/lib/jbpm-${jBPM.version}-bin.zip"  />
  </target>

  <!-- Download Drools Guvnor -->
  <target name="download.drools.guvnor.check">
    <echo message="Checking Drools Guvnor download ..." />
    <condition property="drools.guvnor.not.available">
      <not>
        <available file="${install.home}/lib/guvnor-distribution-wars-${drools.guvnor.version}.war" />
      </not>
    </condition>
  </target>  
  <target name="download.drools.guvnor" depends="download.drools.guvnor.check" if="drools.guvnor.not.available">
    <echo message="Getting Drools Guvnor ..." />
    <mkdir dir="${install.home}/lib"/>
    <get src="${drools.guvnor.url}" dest="${install.home}/lib/guvnor-distribution-wars-${drools.guvnor.version}.war"/>
  </target>

  <!-- Download Designer -->
  <target name="download.designer.check">
    <echo message="Checking Designer download ..." />
    <condition property="designer.not.available">
      <not>
        <available file="${install.home}/lib/designer-${designer.version}.war" />
      </not>
    </condition>
  </target>  
  <target name="download.designer" depends="download.designer.check" if="designer.not.available">
    <echo message="Getting Designer ..." />
    <mkdir dir="${install.home}/lib"/>
    <get src="${designer.url}/designer-${designer.version}.war" dest="${install.home}/lib/designer-${designer.version}.war" />
  </target>

  <!-- Download form builder -->
  <target name="download.form.builder.check">
  	<echo message="Checking Form Builder download ..." />
  	<condition property="form.builder.not.available">
  	  <not>
  		<available file="${install.home}/lib/jbpm-${jBPM.version}-form-builder.war" />
  	  </not>
    </condition>
  </target>
  <target name="download.form.builder" depends="download.form.builder.check" if="form.builder.not.available">
  	<echo message="Getting Form Builder ..." />
  	<mkdir dir="${install.home}/lib"/>
  	<get src="${form.builder.url}" dest="${install.home}/lib/jbpm-${jBPM.version}-form-builder.war" />
  </target>  
  
  <!-- Download jBPM human task server war -->
  <target name="download.jBPM.ht-war.check">
    <echo message="Checking jBPM human task war download ..." />
    <condition property="jBPM.ht-war.not.available">
      <not>
        <available file="${install.home}/lib/jbpm-${jBPM.version}-human-task-war.zip" />
      </not>
    </condition>
  </target>
  <target name="download.jBPM-ht.war" depends="download.jBPM.ht-war.check" if="jBPM.ht-war.not.available">
    <echo message="Getting jBPM human task war ..." />
    <mkdir dir="${install.home}/lib"/>
    <get src="${jBPM.url}/jbpm-${jBPM.version}-human-task-war.zip" dest="${install.home}/lib/jbpm-${jBPM.version}-human-task-war.zip"  />
  </target>  
  
  <!-- Download jBPM gwt-console -->
  <target name="download.jBPM.gwt-console.check">
    <echo message="Checking jBPM gwt-console download ..." />
    <condition property="jBPM.gwt-console.not.available">
      <not>
        <available file="${install.home}/lib/jbpm-${jBPM.version}-gwt-console.zip" />
      </not>
    </condition>
  </target>
  <target name="download.jBPM.gwt-console" depends="download.jBPM.gwt-console.check" if="jBPM.gwt-console.not.available">
    <echo message="Getting jBPM gwt-console ..." />
    <mkdir dir="${install.home}/lib"/>
    <get src="${jBPM.url}/jbpm-${jBPM.version}-gwt-console.zip" dest="${install.home}/lib/jbpm-${jBPM.version}-gwt-console.zip"  />
  </target>

  <!-- Download BIRT engine for AS7 -->
  <target name="check.birt.as7">
    <condition property="birt.download">
      <equals arg1="${jBPM.birt.download}" arg2="true" />
    </condition>
  </target>
  <target name="download.birt.check.as7" depends="check.birt.as7" if="birt.download">
    <echo message="Checking birt reporting engine download for as7 ..." />
    <condition property="birt.not.available">
      <not>
        <available file="${install.home}/lib/birt-runtime-${birt.version.as7}.zip" />
      </not>
    </condition>
  </target>
  <target name="download.birt.as7" depends="download.birt.check.as7" if="birt.not.available">
    <echo message="Getting birt reporting engine for AS7 ..." />
    <mkdir dir="${install.home}/lib"/>
    <get src="${birt.download.url.as7}" dest="${install.home}/lib/birt-runtime-${birt.version.as7}.zip" />
  </target>  
  
  <!-- ############ INSTALL ############ -->

  <!-- Install Bitronix -->
  <target name="install.bitronix.config.into.tomcat.7">
    <copy todir="${tomcat.7.server.conf.dir}"
		  file="${install.home}/db/resources.properties"
		  overwrite="true" />
  </target>

  <!-- Install JDBC -->
  <target name="install.h2.into.tomcat.7" depends="download.h2,check.tomcat.version">
    <copy todir="${tomcat.7.server.lib.dir}"
		  file="${install.home}/db/driver/${h2.jdbc.jar}"
		  overwrite="true" />
  </target>
  
  <target name="install.mysql.into.tomcat.7" depends="download.mysql,check.tomcat.version">
    <copy todir="${tomcat.7.server.lib.dir}"
		  file="${install.home}/db/driver/${mysql.jdbc.jar}"
		  overwrite="true" />  
  </target>
  
  <!-- Install guvnor -->
  <target name="install.guvnor.into.tomcat.7" depends="download.drools.guvnor,check.tomcat.version">
    <mkdir dir="${install.home}/target"/>
	<mkdir dir="${install.home}/target/jbpm-drools-guvnor-war"/>

    <unzip src="${install.home}/lib/guvnor-distribution-wars-${drools.guvnor.version}.war" 
	       dest="${install.home}/target/jbpm-drools-guvnor-war" />
     
	<!-- Fixes for Tomcat... -->
    <delete file="${install.home}/target/jbpm-drools-guvnor-war/WEB-INF/lib/servlet-api-2.5.jar"/>

    <copy file="${install.home}/lib/weld-servlet-1.1.8.Final.jar"
          tofile="${install.home}/target/jbpm-drools-guvnor-war/WEB-INF/lib/weld-servlet-1.1.8.Final.jar"
          overwrite="true" />
		
  	<antcall target="removeJavaxServletFromJar" >
		<param name="jarpath" value="${install.home}/target/jbpm-drools-guvnor-war/WEB-INF/lib" />
		<param name="jarname" value="jboss-servlet-api_3.0_spec-1.0.0.Final.jar" />
	</antcall>

  	<antcall target="removeJavaxServletFromJar" >
		<param name="jarpath" value="${install.home}/target/jbpm-drools-guvnor-war/WEB-INF/lib" />
		<param name="jarname" value="gwt-user-2.3.0.jar" />
	</antcall>

    <zip basedir="${install.home}/target/jbpm-drools-guvnor-war"
         destfile="${install.home}/target/guvnor-distribution-wars-${drools.guvnor.version}.war" />

	<copy file="${install.home}/target/guvnor-distribution-wars-${drools.guvnor.version}.war"
          tofile="${tomcat.7.server.deploy.dir}/drools-guvnor.war"
          overwrite="true" />
		  
	<delete dir="${install.home}/target"/> 

  </target>  	

  <target name="removeJavaxServletFromJar">
    <mkdir dir="${jarpath}/${jarname}.tmp" />
    <unzip src="${jarpath}/${jarname}"
	       dest="${jarpath}/${jarname}.tmp" />
	<move file="${jarpath}/${jarname}" toFile="${jarpath}/${jarname}.orig" />
    <delete dir="${jarpath}/${jarname}.tmp/javax/servlet" />
    <zip basedir="${jarpath}/${jarname}.tmp"
         destfile="${jarpath}/${jarname}" />
    <delete dir="${jarpath}/${jarname}.tmp" />
  </target>
  
  <!-- Install designer -->
  <target name="install.designer.into.tomcat.7" depends="download.designer,check.tomcat.version">
    <copy file="${install.home}/lib/designer-${designer.version}.war"
          tofile="${tomcat.7.server.deploy.dir}/designer.war"
          overwrite="true" />
  </target>

  <!-- Install form builder -->
  <target name="install.form.builder.into.tomcat.7" depends="download.form.builder">
    <mkdir dir="${install.home}/target"/>
    <mkdir dir="${install.home}/target/jbpm-form-builder-war"/>
    <unzip src="${install.home}/lib/jbpm-${jBPM.version}-form-builder.war" dest="${install.home}/target/jbpm-form-builder-war" />

    <copy file="${install.home}/auth/users.properties"
          tofile="${install.home}/target/jbpm-form-builder-war/WEB-INF/classes/users.properties" 
          overwrite="true" />
    <copy file="${install.home}/auth/roles.properties"
          tofile="${install.home}/target/jbpm-form-builder-war/WEB-INF/classes/roles.properties" 
          overwrite="true" />
    <copy file="${install.home}/auth/users.properties"
          tofile="${jboss.server.conf.dir}/users.properties" 
          overwrite="true" />
    <copy file="${install.home}/auth/roles.properties"
          tofile="${jboss.server.conf.dir}/roles.properties" 
          overwrite="true" />
		  
    <zip basedir="${install.home}/target/jbpm-form-builder-war"
         destfile="${install.home}/target/jbpm-${jBPM.version}-form-builder.war" />
		 
    <copy file="${install.home}/target/jbpm-${jBPM.version}-form-builder.war" 
          tofile="${tomcat.7.server.deploy.dir}/jbpm-form-builder.war" 
          overwrite="true" />
		  
    <delete dir="${install.home}/target" />
  </target>
  
  <!-- Install jbpm human task war -->
  <target name="install.ht.war.into.tomcat.7" depends="download.jBPM-ht.war">
    <unzip src="${install.home}/lib/jbpm-${jBPM.version}-human-task-war.zip" dest="${install.home}/lib" />
    <mkdir dir="${install.home}/target"/>
    <mkdir dir="${install.home}/target/jbpm-human-task-war"/>
    <unzip src="${install.home}/lib/jbpm-human-task-war-${jBPM.version}.war" dest="${install.home}/target/jbpm-human-task-war" />

	<!-- Abstraction for Tomcat Install -->
  	<copy file="${install.home}/conf/web.humantaskwar.xml" 
  	          tofile="${install.home}/task-service/resources/war/web.xml" 
  	          overwrite="true" />
  	<copy file="${install.home}/db/persistence-human-task-war.xml" 
  	          tofile="${install.home}/task-service/resources/war/persistence.xml" 
  	          overwrite="true" />
	<!-- Now Proceed To patch the WAR... -->	
  	<copy file="${install.home}/task-service/resources/war/web.xml" 
  	          tofile="${install.home}/target/jbpm-human-task-war/WEB-INF/web.xml" 
  	          overwrite="true" />
  	<copy file="${install.home}/task-service/resources/war/persistence.xml" 
  	              tofile="${install.home}/target/jbpm-human-task-war/WEB-INF/classes/META-INF/persistence.xml" 
  	              overwrite="true" />
  	<copy file="${install.home}/jbpm-tm.jar"
  	          tofile="${install.home}/target/jbpm-human-task-war/WEB-INF/lib/jbpm-tm.jar"
  	          overwrite="true" />
	<!-- Fix for Tomcat -->
    <delete file="${install.home}/target/jbpm-human-task-war/WEB-INF/lib/jta-1.1.jar"/>
	<delete file="${install.home}/target/jbpm-human-task-war/WEB-INF/lib/javassist-3.14.0-GA.jar" />

	<copy todir="${install.home}/target/jbpm-human-task-war/WEB-INF/lib/"
	      file="${install.home}/lib/javassist-3.4.GA.jar"
		  overwrite="true" />

	<!-- Rebuild the WAR and deploy -->
    <zip basedir="${install.home}/target/jbpm-human-task-war"
         destfile="${install.home}/target/jbpm-${jBPM.version}-human-task-war.war" />

	<copy file="${install.home}/target/jbpm-${jBPM.version}-human-task-war.war" 
          tofile="${tomcat.7.server.deploy.dir}/jbpm-human-task-war.war" 
          overwrite="true" />
		  
    <delete dir="${install.home}/target" /> 
  </target>
  
  <!-- Install gwt-console -->
  <target name="install.jBPM.into.tomcat.7" depends="download.mysql,download.h2,download.jBPM.gwt-console" >
  	<antcall target="install.mysql.into.tomcat.7" />
  	<antcall target="install.h2.into.tomcat.7" />	
    <mkdir dir="${install.home}/target"/>
    <unzip src="${install.home}/lib/jbpm-${jBPM.version}-gwt-console.zip" 
	       dest="${install.home}/target/" />
    <antcall target="install.jBPM-gwt-console.into.tomcat.7" /> 
    <antcall target="install.jBPM-gwt-console-server.into.tomcat.7" /> 	
    <delete dir="${install.home}/target"/> 
  </target>
    
  <target name="install.jBPM-gwt-console.into.tomcat.7" depends="check.tomcat.version" if="tomcat.version.is.7">
    <!-- gwt-console -->
	<unzip src="${install.home}/target/jbpm-gwt-console-${jBPM.version}.war"
           dest="${install.home}/target/jbpm-gwt-console-war"/>
	   
    <!-- Tomcat Fix -->
	<copy todir="${install.home}/target/jbpm-gwt-console-war/WEB-INF/lib"
	      file="${install.home}/lib/javassist-3.4.GA.jar"
		  overwrite="true" />
	
	<!-- Repackage WAR and deploy -->
	<zip basedir="${install.home}/target/jbpm-gwt-console-war"
         destfile="${install.home}/target/jbpm-gwt-console-${jBPM.version}.war"/>
	
    <copy file="${install.home}/target/jbpm-gwt-console-${jBPM.version}.war"
          tofile="${tomcat.7.server.deploy.dir}/jbpm-gwt-console.war"
          overwrite="true" />
  </target>

  <!-- Install gwt-console-server -->
  <target name="install.jBPM-gwt-console-server.into.tomcat.7" depends="check.tomcat.version" if="tomcat.version.is.7">
    <!-- reporting -->
    <antcall target="download.birt.as7" />  
    <!-- gwt-console-server -->
    <unzip src="${install.home}/target/jbpm-gwt-console-server-${jBPM.version}.war"
           dest="${install.home}/target/jbpm-gwt-console-server-war"/>
    <copy file="${install.home}/db/persistence.xml"
          tofile="${install.home}/target/jbpm-gwt-console-server-war/WEB-INF/classes/META-INF/persistence.xml"
          overwrite="true" />
    <copy file="${install.home}/db/ProcessInstanceInfo.hbm.xml"
          tofile="${install.home}/target/jbpm-gwt-console-server-war/WEB-INF/classes/META-INF/ProcessInstanceInfo.hbm.xml"
          overwrite="true" />
    <copy file="${install.home}/auth/users.properties"
          tofile="${install.home}/target/jbpm-gwt-console-server-war/WEB-INF/classes/users.properties"
          overwrite="true" />
    <copy file="${install.home}/auth/roles.properties"
          tofile="${install.home}/target/jbpm-gwt-console-server-war/WEB-INF/classes/roles.properties"
          overwrite="true" />
    <copy file="${install.home}/jbpm-tm.jar"
          tofile="${install.home}/target/jbpm-gwt-console-server-war/WEB-INF/lib/jbpm-tm.jar"
          overwrite="true" />

    <!-- Fix for conflicting javassist jar -->
    <delete file="${install.home}/target/jbpm-gwt-console-server-war/WEB-INF/lib/javassist-3.6.0.GA.jar"/>
	<delete file="${install.home}/target/jbpm-gwt-console-server-war/WEB-INF/lib/javassist-3.14.0-GA.jar" />
	
	<copy todir="${install.home}/target/jbpm-gwt-console-server-war/WEB-INF/lib"
	      file="${install.home}/lib/javassist-3.4.GA.jar"
		  overwrite="true" />
		  
	<!-- Further fixes for Tomcat... -->
    <delete file="${install.home}/target/jbpm-gwt-console-server-war/WEB-INF/lib/el-api-1.2.jar"/>
    <delete file="${install.home}/target/jbpm-gwt-console-server-war/WEB-INF/lib/dom4j-1.6.jar"/>
		
    <!-- Other configuration like work item handlers -->
	<!--
    <copy todir="${install.home}/target/jbpm-gwt-console-server-war/WEB-INF/classes" overwrite="true">
      <fileset dir="${install.home}/conf"/>
    </copy>
	-->
	
    <!-- reporting -->
    <antcall target="install.reporting.into.tomcat.7" /> 
	
    <zip basedir="${install.home}/target/jbpm-gwt-console-server-war"
         destfile="${install.home}/target/jbpm-gwt-console-server-${jBPM.version}.war"/>

	<copy file="${install.home}/target/jbpm-gwt-console-server-${jBPM.version}.war"
          tofile="${tomcat.7.server.deploy.dir}/gwt-console-server.war"
          overwrite="true" />
  </target>
  
  <!-- Install reporting Tomcat7  -->
  <target name="install.reporting.into.tomcat.7" depends="check.birt.as7" if="birt.download" >
    <mkdir dir="${install.home}/birt"/>
    <unzip src="${install.home}/lib/birt-runtime-${birt.version.as7}.zip"
           dest="${install.home}/birt"/>
    <copy todir="${install.home}/target/jbpm-gwt-console-server-war/WEB-INF/lib">
      <fileset dir="${install.home}/birt/birt-runtime-${birt.version.as7}/ReportEngine/lib">
         <include name="**/*.jar"/>
      </fileset>
   </copy>
   <mkdir dir="${install.home}/target/jbpm-gwt-console-server-war/WEB-INF/output"/>
   <mkdir dir="${install.home}/target/jbpm-gwt-console-server-war/WEB-INF/output/image"/>   
   <mkdir dir="${install.home}/target/jbpm-gwt-console-server-war/WEB-INF/reports"/>
   <copy file="${install.home}/report/${birt.version.as7}/overall_activity.rptdesign"
          tofile="${install.home}/target/jbpm-gwt-console-server-war/WEB-INF/reports/overall_activity.rptdesign"
          overwrite="true"/>
   <delete dir="${install.home}/birt"/>
  </target>

  <!-- Install Demo -->

  <!-- create runtime -->
  <target name="install.jBPM.runtime" depends="download.jBPM.bin">
    <mkdir dir="${install.home}/runtime"/>
    <unzip src="${install.home}/lib/jbpm-${jBPM.version}-bin.zip" dest="${install.home}/runtime" />
  </target>

  <path id="classpath.human.task">
    <fileset dir="${install.home}/runtime" includes="**/*.jar"/>
    <fileset dir="${install.home}/db/driver" includes="**/*.jar"/>
  </path>
  <target name="start.human.task">
    <mkdir dir="${install.home}/task-service/target"/>
    <javac includeantruntime="false" srcdir="${install.home}/task-service/src" destdir="${install.home}/task-service/target" classpathref="classpath.human.task">
      <compilerarg value="-Xlint:unchecked"/>
    </javac>
    <copy tofile="${install.home}/task-service/resources/META-INF/persistence.xml"
	      file="${install.home}/db/persistence-human-task-service.xml"
		  overwrite="true" />
    <copy todir="${install.home}/task-service/target">
      <fileset dir="${install.home}/task-service/resources"/>
    </copy>
    <java classname="org.jbpm.DemoTaskService" fork="true">  
      <classpath>
        <pathelement path="${install.home}/task-service/target"/>
        <path refid="classpath.human.task" />
      </classpath>
    </java>
  </target>
</project>

c) Perform the installation: In jbpm-install execute:

ant -buildfile tomcat7build.xml install.jbpmfull.to.tomcat.7

d) Add the following parameters to $CATALINA_OPTS and passed to JVM when Tomcat started:

-Xms256m
-Xmx1024m
-XX:PermSize=128m
-XX:MaxPermSize=256m
-Dreporting.needcontext=true

NB: On windows do this through the configuration tool – do not set environment variable unless you understand the implications.

Checkpoint: We have at this point installed JBPM 5.3 to Tomcat.
Before proceeding to run the ‘demo’ below it should be noted that there is an error in the 5.3 distribution which prevents the console
from running whilst drools-guvnor is running. In order to see the demo – stop drools-guvnor.

In the above configuration – reporting will work – however – see here for implications of moving away from H2 backend, and <a href="https://ironclaws.wordpress.com/2012/06/23/jbpm-reporting-birt-tomcat-7-pure-jndi-without-tomcat-correction-2/"here if you want to configure the report engines initial JNDI context.

4: Running the Demo

a) Update report definition: ${CATALINA_HOME}/webapps/gwt-console-server/WEB-INF/reports/overall_activity.rptdesign

i) Add following to ‘oda-data-source’ section:

<property name="odaJndiName">java:comp/env/jdbc/testDS1
</property>

b) Add following to Tomcat startup parameter:

-Djbpm.console.directory=$lt;path-to-jbpm-install>\sample\evaluation\src\main\resources

c) Reconfigure ${CATALINA_HOME}/tomcat-users.xml, add:

<role rolename="manager" />
<role rolename="admin" />
<role rolename="user" />
<role rolename="PM" />
<role rolename="HR" />
<role rolename="webdesigner" />
<role rolename="functionalanalyst" />
<role rolename="sales" />
<user username="krisv" password="krisv" roles="manager,admin,user" />
<user username="john" password="john" roles="admin,manager,user,PM" />
<user username="mary" password="mary" roles="admin,manager,user,HR" />
<user username="sales-rep" password="sales-rep" roles="admin,manager,user,sales" />
<user username="admin" password="admin" roles="admin,manager,user,webdesigner,functionalanalyst" />

e) Start H2: In jbpm-install execute:

ant start.h2

f) Start Tomcat

g) Stop drools-guvnor and restart gwt-console-server (to be on the safe side)

h) Naviate to: http://localhost:8080/jbpm-gwt-console

JBPM 5.3 Reporting (BIRT) / Tomcat 7 : Pure JNDI (without Tomcat Correction)

JBPM Reporting can make use of JNDI datasources.

Once a JNDI datasource (say jdbc/testDS1) has been defined on Tomcat, the following needs to be added to the report definition as a datasource:

<property name="odaJndiName">java:comp/env/jdbc/testDS1</property>

There is a problem with this though.

Since Tomcat is not EE compliant with respect to JNDI, our report is no longer portable to a real J2EE application server without modification of the JNDI reference.

With BIRT on Tomcat we appear to be locked into using the Tomcat JNDI context – which forces the non standard JNDI URL above.

It would be ideal to be able to use a different JNDI context – bypassing Tomcat completely. In the context of this post series, it would be optimal to use the bitronix.tm.jndi.BitronixInitialContextFactory.

Our target configuration for the report is to have the following JNDI specification work:

<property name="odaJndiName">jdbc/testDS1</property>

In order to do this – some functionality within BIRT may be leveraged – with a minor fix as follows.

Required software / tools:


i) Create the file:

${CATALINA_HOME}/webapps/gwt-console-server/WEB-INF/classes/jndi.properties

With contents:

java.naming.factory.initial = bitronix.tm.jndi.BitronixInitialContextFactory

ii) Now patch the following jar:

${CATALINA_HOME}\webapps\gwt-console-server\WEB-INF\lib\org.eclipse.birt.runtime_3.7.0.v20110615-1818.jar

a) Create a copy of org.eclipse.birt.runtime_3.7.0.v20110615-1818.jar in workspace area, rename to org.eclipse.birt.runtime_3.7.0.v20110615-1818.zip and unzip.

b) Remove the jar signing (you are encouraged to resign following the fix below – but this is not necessary):

Delete files:

org.eclipse.birt.runtime_3.7.0.v20110615-1818/META-INF/ECLIPSEF.RSA org.eclipse.birt.runtime_3.7.0.v20110615-1818/META-INF/ECLIPSEF.SF

Replace contents of MANIFEST.MF with the following:

Manifest-Version: 1.0  
Bundle-Vendor: Eclipse.org  
Bundle-Name: BIRT Runtime SDK 
Bundle-SymbolicName: org.eclipse.birt.runtime 
Bundle-Version: 3.7.0.v20110615-1818 

We are going to patch the following class: JndiDataSource.class

c) In Eclipse create a new Java Project, add all jars included in ${CATALINA_HOME}\webapps\gwt-console-server\WEB-INF\lib to the buildpath (classpath).

Create the following package under src:

org.eclipse.birt.report.data.oda.jdbc

Create new class: JndiDataSource

d) In the unzipped jar, locate JndiDataSource.class and decompile.

Copy the decompiled code to Eclipse / JndiDataSource

e) Add:

import java.io.InputStream;

f) Replace the method getDriverJndiProperties() with the following:

 
protected Properties getDriverJndiProperties() 
{ 
/* File jndiPropFile = getDriverJndiPropertyFile(); 
   if (jndiPropFile == null) { return null; } 
*/ 
   Properties jndiProps = new Properties(); 
// FileInputStream inputStream = null; 
   InputStream inputStream = null; 
   if (sm_logger.isLoggable(Level.INFO)) 
      sm_logger.info("getDriverJndiProperties(): Loading " + JNDI_PROPERTIES + " from classpath"); 
   try { 
 // inputStream = new FileInputStream(jndiPropFile); 
    inputStream = this.getClass().getClassLoader().getResourceAsStream(JNDI_PROPERTIES); 
    jndiProps.load(inputStream); 
   } 
   catch (Exception ex) 
   { 
      if (sm_logger.isLoggable(Level.INFO)) 
         sm_logger.info("getDriverJndiProperties(): " + ex.toString()); jndiProps = null; 
   } 
   if (inputStream != null) 
   { 
      try { 
         inputStream.close(); 
      } 
      catch (IOException e) 
      { 
         if (sm_logger.isLoggable(Level.INFO)) 
            sm_logger.info("getDriverJndiProperties(): " + e.toString()); 
         inputStream = null; 
      } 
   }

   if (sm_logger.isLoggable(Level.CONFIG))
   {
      int propertyCount = jndiProps == null ? 0 : jndiProps.size();
      sm_logger.config("Driver JNDI property count: " + propertyCount);
   }

   return jndiProps;
}

This fixes the BIRT functionality for loading jndi.properties. Once in place, when a JNDI datasource is specified, BIRT will check the classpath for a jndi.properties file, and will load if found.

g) Build the project.

h) Replace the JndiDataSource.class in the unzipped jar with the Eclipse output.

i) Rebuild the jar with name:

org.eclipse.birt.runtime_3.7.0.v20110615-1818.patched.jar

j) Replace:

 ${CATALINA_HOME}\webapps\gwt-console-server\WEB-INF\lib\org.eclipse.birt.runtime_3.7.0.v20110615-1818.patched.jar 

With:

 org.eclipse.birt.runtime_3.7.0.v20110615-1818.patched.jar 

k) Restart Tomcat.

With the above configuration, BIRT will now use the java naming factory specified in jndi.properties – if jndi.properties is present, and if a naming factory is specified.

In the context of this series, the following JNDI can be used:

<property name="odaJndiName">jdbc/testDS1</property>

JBPM 5.3 / Tomcat 7 / MySQL : Ant Script

An Ant script for direct deploying jBPM 5.3 using MySQL as back end has been implemented.

NB: Apache-Ivy is required in addition to Ant.

The script with instructions have been published at 4Share, and can be downloaded here.

H2 / MySQL configuration templates are included.

For further details on the reporting, check here.


To summarise the key observations of Tomcat / jBPM 5.3 installer which precipitated development of the above installer (Please see unresolved errata below though):

Tomcat 7

i) It should be recognised that Tomcat is not a J2EE application server, but is technically a servlet container.

(The implementation of JNDI on Tomcat which differs slightly from EE standard – ie. java:comp/env/… rather than java:comp/…, lack of any J2EE services in standard installation etc. are significant hints at this)

JBPM requires a J2EE application server – eg. JBoss AS / GlassFish / WebLogic / WebSphere etc.

ii) Tomcat can be made to behave like a J2EE server with careful configuration. A good demarcation point though is when application complexity reaches the point where a service bus is required.

iii) Tomcat is arguably the most popular servlet container on the market at moment – however – its success and strengths have clouded the important point that it is strictly not a J2EE application server.

Installation issues of JBPM into Tomcat are mainly rooted in this issue.

In order to configure Tomcat as a J2EE compliant container which can host JBPM – some J2EE services need to be set up on Tomcat. In particular a JTA: A good choice here is the transaction manager from Bitronix.

The above Ant installer will install Bitronix at the Tomcat Server level.

Bitronix only may be deployed by:

a) Configure Bitronix template files btm-config.properties, resources.properties (See the README file)

b) Run: ant install.bitronix.into.tomcat.7

Bitronix can be replaced with a transaction / pool manager of your choice – Bitronix is arguably the best choice in most cases though.

JBPM 5.3 Installer / Distribution – Tomcat

Now on to the issues with the jbpm installer and distribution from the Tomcat perspective:

i) Some dependency issues relating to javassist are still present, and these are corrected. Where appropriate, incorrect versions are removed and replaced with 3.4GA

ii) There are 3 jars included in the drools-guvnor 5.4 distribution which include bad version of javax.servlet for Tomcat 7.

The two key jars (gwt-user-2.3.0.jar, jboss-servlet-api_3.0_spec-1.0.0.Final.jar) are patched by this script to remove the bad javax.servlet – servlet-api-2.5.jar is removed.

iii) Again for drools-guvnor 5.4 – a required JBoss jar is missing: weld-servlet-1.1.8.Final.jar is added.

iv) There is a web hosted version of the human-task server included in this distribution: jta-1.1.jar is removed from that applications lib (This jar should only be present in ${CATALINA_HOME}/lib).

NB: For the demo, with the human task war – the following should work when using MySQL back end:

a) Stop drools-guvnor
b) Restart gwt-console-server
c) Go to: http://localhost/jbpm-human-task-war
(Ignore the error – it should have started: check for a listener on port 9132)
d) Go to: http://localhost/jpbm-gwt-console – and all should be good.

Errata
There is one unresolved issue:

  1. The gwt-console-server has some issues when drools-guvnor is running. With H2 backend – all is fine – with MySQL drools-guvnor will need to be disabled. (See above)

– NB: I can confirm that this is caused by slight issue in gwt-console-server / jbpm-gwt-core-5.3.0.Final.jar

There is currently an open Jira on this: JBPM-3647

JBPM 5.2 / Tomcat 7 / MySQL : Ant Script

An Ant script for direct deploying jBPM 5.2 using MySQL as back end has been implemented.

NB: Apache-Ivy is required in addition to Ant.

The script with instructions have been published at 4Share, and can be downloaded here.


To summarise the key observations of Tomcat / jBPM 5.2 installer which precipitated development of the above installer:

Tomcat 7

i) It should be recognised that Tomcat is not a J2EE application server, but is technically a servlet container.

(The implementation of JNDI on Tomcat which differs slightly from EE standard – ie. java:comp/env/… rather than java:comp/…, lack of any J2EE services in standard installation etc. are significant hints at this)

JBPM requires a J2EE application server – eg. JBoss AS / GlassFish / WebLogic / WebSphere etc.

ii) Tomcat can be made to behave like a J2EE server with careful configuration. A good demarcation point though is when application complexity reaches the point where a service bus is required.

iii) Tomcat is arguably the most popular servlet container on the market at moment – however – its success and strengths have clouded the important point that it is strictly not a J2EE application server.

Installation issues of JBPM into Tomcat are mainly rooted in this issue.

In order to configure Tomcat as a J2EE compliant container which can host JBPM – some J2EE services need to be set up on Tomcat. In particular a JTA: A good choice here is the transaction manager from Bitronix.

The above Ant installer will install Bitronix at the Tomcat Server level.

Bitronix only may be deployed by:

a) Configure Bitronix template files btm-config.properties, resources.properties (See the README file)

b) Run: ant install.bitronix.into.tomcat.7

Bitronix can be replaced with a transaction / pool manager of your choice – Bitronix is arguably the best choice in most cases though.

JBPM 5.2 Installer / Distribution – Tomcat

Now on to the issues with the jbpm installer and distribution from the Tomcat perspective:

i) The jBPM distribution is designed for JBoss AS server and the console / console-server packages include EL (expression language) libraries. These will conflict with those which are installed with Tomcat – the Tomcat EL should be preserved.

For Tomcat installation these should be removed from the WAR deployments.

ii) There is some confusion with respect to javassist jar in the config / config-server distributions.

The included jars should be dropped – and included into both config / config-server javassist-3.4.GA

The reason for this dependency is that Hibernate 3.4 is implicitly deployed as persistence layer in this distribution.

iii) There is a conflicting dom4j library – dom4j-1.6.jar deployed with the console / console-server packages. This should also be removed.

iv) It is not mentioned clearly that the parameter:

-Dreporting.needcontext=true

needs to be passed to the Tomcat JVM in order to allow the gtw-server to correctly instantiate the report module loader.

v) For the ‘Demo’ it is important to configure the human-server persistence correctly, and additionally address the includeantruntime issue during starting of this service.

JBPM 5.2 / Tomcat 7 / Oracle 11g Express / Demo

The following details how to configure JBPM 5.2 running under Tomcat 7 to run the Demo application using Oracle 11g Express backend vs. the default H2.

It is assumed that:

JBPM 5.2 is running under Tomcat 7 / H2 Demo running.
(See JBPM 5.2 / Tomcat 7 / H2 / Demo)

An Oracle 11g XE instance has been installed and configured with TNS listening on the default port (1521)

NB: Tomcat should be stopped prior to installation.

I have specified Oracle connection parameters to use the ‘dpbmtest‘ user – this user should either be independently created or changed to a user of your choice with appropriate rights within the Oracle instance (eg. Create table etc.).

System is not suggested as other than the obvious issues, Oracle XE works to a single instance database with schema set by user model. This is a break from regular Oracle also.

It is further assumed below that the Oracle express instance is identified as ‘XE’

1: Download required software:

Oracle JDBC Driver (Select latest version)

2: Install Oracle JDBC Driver

Copy downloaded ojdbc6.jar to:

${CATALINA_HOME}/lib

jbpm-installer/db/driver

NB: The second step is required for the demo human-task-service only.

3: Update Tomcat Configuration

a) Update Bitronix configuration.

i) Modify file: ${CATALINA_HOME}/conf/resources.properties to contain following:

resource.ds1.className=bitronix.tm.resource.jdbc.lrc.LrcXADataSource
resource.ds1.uniqueName=jdbc/testDS1
resource.ds1.minPoolSize=0
resource.ds1.maxPoolSize=5
resource.ds1.driverProperties.driverClassName=oracle.jdbc.OracleDriver
resource.ds1.driverProperties.user=dbpmtest
resource.ds1.driverProperties.password=
resource.ds1.driverProperties.url=jdbc:oracle:thin:@localhost:1521:XE
resource.ds1.allowLocalTransactions=true

ii) Update ${CATALINA_HOME}/conf/context.xml

Add following resource declaration – replacing previous H2 entry:

<Resource name="jdbc/testDS1" auth="Container" type="javax.sql.DataSource" maxActive="15" maxIdle="2" maxWait="10000" logAbandoned="true" username="dbpmtest"password="" driverClassName="oracle.jdbc.OracleDriver" url="jdbc:oracle:thin:@localhost:1521:XE"/>

iii) If exists, delete folder: ${CATALINA_HOME}/work

4: Update hibernate configuration for the web console interface

a) Update jpbm-console

i) Update file:

${CATALINA_HOME}/webapps/jbpm-console/WEB-INF/classes/hibernate.cfg.xml

Set configuration to:

<hibernate-configuration>
<session-factory>
<!– Database connection settings –>
<property name=”connection.driver_class”>oracle.jdbc.OracleDriver</property>
<property name=”connection.url”>jdbc:oracle:thin:@localhost:1521:XE</property>
<property name=”connection.username”>dbpmtest</property>
<property name=”connection.password”></property>
<!– JDBC connection pool (use the built-in) –>
<property name=”connection.pool_size”>1</property>
<!– SQL dialect –>
<property name=”dialect”>org.hibernate.dialect.OracleDialect</property>
<!– Enable Hibernate’s automatic session context management –>
<property name=”current_session_context_class”>thread</property>
<!– Disable the second-level cache –>
<property name=”cache.provider_class”>org.hibernate.cache.NoCacheProvider</property>
<!– Echo all executed SQL to stdout –>
<property name=”show_sql”>false</property>
<!– Drop and re-create the database schema on startup –>
<property name=”hbm2ddl.auto”>create</property>
<mapping resource=”AuditLog.hbm.xml”/>
</session-factory>
</hibernate-configuration>

b) Update gwt-console-server

i) Update file:

${CATALINA_HOME}/webapps/gwt-console-server/WEB-INF/classes/hibernate.cfg.xml

Set configuration to:

<hibernate-configuration>
<session-factory>
<!– Database connection settings –>
<property name=”connection.driver_class”>oracle.jdbc.OracleDriver</property>
<property name=”connection.url”>jdbc:oracle:thin:@localhost:1521:XE</property>
<property name=”connection.username”>dbpmtest</property>
<property name=”connection.password”></property>
<!– JDBC connection pool (use the built-in) –>
<property name=”connection.pool_size”>1</property>
<!– SQL dialect –>
<property name=”dialect”>org.hibernate.dialect.OracleDialect</property>
<!– Enable Hibernate’s automatic session context management –>
<property name=”current_session_context_class”>thread</property>
<!– Disable the second-level cache –>
<property name=”cache.provider_class”>org.hibernate.cache.NoCacheProvider</property>
<!– Echo all executed SQL to stdout –>
<property name=”show_sql”>false</property>
<!– Drop and re-create the database schema on startup –>
<property name=”hbm2ddl.auto”>create</property>
<mapping resource=”AuditLog.hbm.xml”/>
</session-factory>
</hibernate-configuration>

ii) Update file:

${CATALINA_HOME}/webapps/gwt-console-server/WEB-INF/classes/META-INF/persistence.xml

Set content to:

<persistence-unit name="org.jbpm.persistence.jpa" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<mapping-file>META-INF/JBPMorm.xml</mapping-file>
<class>org.jbpm.persistence.processinstance.ProcessInstanceInfo</class>
<class>org.drools.persistence.info.WorkItemInfo</class>
<class>org.drools.persistence.info.SessionInfo</class>
<properties>
<property name="hibernate.connection.url" value="jdbc:oracle:thin:@localhost:1521:XE"/>
<property name="hibernate.connection.driver_class" value="oracle.jdbc.OracleDriver"/>
<property name="hibernate.connection.username" value="dbpmtest"/>
<property name="hibernate.connection.password" value=""/>
<property name="hibernate.dialect" value="org.hibernate.dialect.OracleDialect"/>
<property name="hibernate.max_fetch_depth" value="3"/>
<property name="hibernate.hbm2ddl.auto" value="create" />
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.connection.autocommit" value="true" />
<property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.BTMTransactionManagerLookup" />
</properties>
</persistence-unit>
</persistence>

5: Update configuration of demo ‘human-task-service’

NB: The human-task-service is responsible for creating the ‘test’ demo database objects within the XE / dbpmtest schema – this and following step represents a partial test of the Oracle connectivity and above configurations.

a) Update persistence configuration file:
jbpm-installer/task-service/target/META-INF/persistence.xml

Set ‘properties’ contents to:

<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.OracleDialect"/>
<property name="hibernate.connection.driver_class" value="oracle.jdbc.OracleDriver"/>
<property name="hibernate.connection.url" value="jdbc:oracle:thin:@localhost:1521:XE" />
<property name="hibernate.connection.username" value="dbpmtest"/>
<property name="hibernate.connection.password" value=""/>
<property name="hibernate.connection.autocommit" value="false" />
<property name="hibernate.max_fetch_depth" value="3"/>
<property name="hibernate.hbm2ddl.auto" value="create" />
<property name="hibernate.show_sql" value="false" />
</properties>

6: First test of the new setup: Start the evaluation human task server.

Change to jpbm-installer folder and execute: ant start.human.task

NB:You will receive errors relating to JDBC connection if there is a problem with either the persistence settings configured in Step 5, or your Oracle setup.

If your local persistence required tweaking be sure to cross check the console persistence file settings updated in Step 4/b/ii above.If the human task service has started successfully it is safe to proceed.

7:  Test console

a) Start Tomcat

b) Navigate to:

http://localhost:8080/jpbm-console


Trouble Shooting

If errors are reported in the console which appear to be connected with database connectivity, verify that the test database has been created within Oracle, and check carefully the hibernate settings mentioned above.


Additional Links / Resources

Hibernate Dialect Cross Reference

JBPM 5.2 / Tomcat 7 / MySQL / Demo

The following details how to configure JBPM 5.2 running under Tomcat 7 to run the Demo application using MySQL backend vs. the default H2.

It is assumed that:

JBPM 5.2 is running under Tomcat 7 / H2 Demo running.
(See JBPM 5.2 / Tomcat 7 / H2 / Demo)

A MySQL instance has been installed and configured on the default port.

NB: Tomcat should be stopped prior to installation.

I have specified MySQL connection parameters to use the ‘root’ user id below – this should be changed to a user of your choice with appropriate rights within the MySQL instance. Root is used below to mirror the sa pattern from the demo example – that is my disclaimer for the obvious security hole here.

If using this user – the mysql root password should be updated in the credential configurations below.

1: Download required software:

MySQL JDBC Driver (Select latest version)

2: Install JDBC Driver

Copy downloaded mysql-connector-java-xxx-bin.jar to:

${CATALINA_HOME}/lib

jbpm-installer/db/driver

NB: The second step is required for the demo human-task-service only.

3: Update Tomcat Configuration

a) Update Bitronix configuration.

i) Modify file: ${CATALINA_HOME}/conf/resources.properties to contain following:

resource.ds1.className=bitronix.tm.resource.jdbc.lrc.LrcXADataSource
resource.ds1.uniqueName=jdbc/testDS1
resource.ds1.minPoolSize=0
resource.ds1.maxPoolSize=5
resource.ds1.driverProperties.driverClassName=com.mysql.jdbc.Driver
resource.ds1.driverProperties.user=root
resource.ds1.driverProperties.password=
resource.ds1.driverProperties.url=jdbc:mysql://localhost/test
resource.ds1.allowLocalTransactions=true

ii) Update ${CATALINA_HOME}/conf/context.xml

Add following resource declaration – replacing previous H2 entry:

<Resource name="jdbc/testDS1" auth="Container" type="javax.sql.DataSource" maxActive="15" maxIdle="2" maxWait="10000" logAbandoned="true" username="root"password="" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost/test"/>

iii) If exists, delete folder: ${CATALINA_HOME}/work

4: Update hibernate configuration for the web console interface

a) Update jpbm-console

i) Update file:

${CATALINA_HOME}/webapps/jbpm-console/WEB-INF/classes/hibernate.cfg.xml

Set configuration to:

<hibernate-configuration>
<session-factory>
<!– Database connection settings –>
<property name=”connection.driver_class”>com.mysql.jdbc.Driver</property>
<property name=”connection.url”>jdbc:mysql://localhost/test</property>
<property name=”connection.username”>root</property>
<property name=”connection.password”></property>
<!– JDBC connection pool (use the built-in) –>
<property name=”connection.pool_size”>1</property>
<!– SQL dialect –>
<property name=”dialect”>org.hibernate.dialect.MySQLDialect</property>
<!– Enable Hibernate’s automatic session context management –>
<property name=”current_session_context_class”>thread</property>
<!– Disable the second-level cache –>
<property name=”cache.provider_class”>org.hibernate.cache.NoCacheProvider</property>
<!– Echo all executed SQL to stdout –>
<property name=”show_sql”>false</property>
<!– Drop and re-create the database schema on startup –>
<property name=”hbm2ddl.auto”>create</property>
<mapping resource=”AuditLog.hbm.xml”/>
</session-factory>
</hibernate-configuration>

b) Update gwt-console-server

i) Update file:

${CATALINA_HOME}/webapps/gwt-console-server/WEB-INF/classes/hibernate.cfg.xml

Set configuration to:

<hibernate-configuration>
<session-factory>
<!– Database connection settings –>
<property name=”connection.driver_class”>com.mysql.jdbc.Driver</property>
<property name=”connection.url”>jdbc:mysql://localhost/test</property>
<property name=”connection.username”>root</property>
<property name=”connection.password”></property>
<!– JDBC connection pool (use the built-in) –>
<property name=”connection.pool_size”>1</property>
<!– SQL dialect –>
<property name=”dialect”>org.hibernate.dialect.MySQLDialect</property>
<!– Enable Hibernate’s automatic session context management –>
<property name=”current_session_context_class”>thread</property>
<!– Disable the second-level cache –>
<property name=”cache.provider_class”>org.hibernate.cache.NoCacheProvider</property>
<!– Echo all executed SQL to stdout –>
<property name=”show_sql”>false</property>
<!– Drop and re-create the database schema on startup –>
<property name=”hbm2ddl.auto”>create</property>
<mapping resource=”AuditLog.hbm.xml”/>
</session-factory>
</hibernate-configuration>

ii) Update file:

${CATALINA_HOME}/webapps/gwt-console-server/WEB-INF/classes/META-INF/persistence.xml

Set content to:

<persistence-unit name="org.jbpm.persistence.jpa" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<mapping-file>META-INF/JBPMorm.xml</mapping-file>
<class>org.jbpm.persistence.processinstance.ProcessInstanceInfo</class>
<class>org.drools.persistence.info.WorkItemInfo</class>
<class>org.drools.persistence.info.SessionInfo</class>
<properties>
<property name="hibernate.connection.url" value="jdbc:mysql://localhost/test"/>
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
<property name="hibernate.connection.username" value="root"/>
<property name="hibernate.connection.password" value=""/>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
<property name="hibernate.max_fetch_depth" value="3"/>
<property name="hibernate.hbm2ddl.auto" value="create" />
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.connection.autocommit" value="true" />
<property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.BTMTransactionManagerLookup" />
</properties>
</persistence-unit>
</persistence>

5: Update configuration of demo ‘human-task-service’

NB: The human-task-service is responsible for creating the ‘test’ demo database – this and following step represents a partial test of the MySQL connectivity and above configurations.

a) Update persistence configuration file:
jbpm-installer/task-service/target/META-INF/persistence.xml

Set ‘properties’ contents to:

<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
<property name="hibernate.connection.url" value="jdbc:mysql://localhost/test" />
<property name="hibernate.connection.username" value="root"/>
<property name="hibernate.connection.password" value=""/>
<property name="hibernate.connection.autocommit" value="false" />
<property name="hibernate.max_fetch_depth" value="3"/>
<property name="hibernate.hbm2ddl.auto" value="create" />
<property name="hibernate.show_sql" value="false" />
</properties>

6: First test of the new configuration: Start the evaluation human task server.

Change to jpbm-installer folder and execute: ant start.human.task

NB:You will receive errors relating to JDBC connection if there is a problem with either the persistence settings configured in Step 5, or your MySQL setup.

If your local persistence required tweaking be sure to cross check the console persistence file settings updated in Step 4/b/ii above.If the human task service has started successfully it is safe to proceed.

7:  Test console

a) Start Tomcat

b) Navigate to:

http://localhost:8080/jpbm-console


Trouble Shooting

If errors are reported in the console which appear to be connected with database connectivity, verify that the test database has been created within MySQL, and check carefully the hibernate settings mentioned above.


Additional Links / Resources

Hibernate Dialect Cross Reference

JBPM 5.2 / Tomcat 7 / H2 / Demo

The following details how to install jBPM 5.2 onto Tomcat 7, configured to run the provided ‘Demo’. A H2 database instance shall be used – which is reflected in the JTA / Hibernate configuration specified below. The following are assumed installed and relatively clean:

NB: Tomcat should be stopped prior to installation.

0: Download required software:

JBPM : Select 5.2.0 – Final Installer Full

Once downloaded, unzip to a staging area separate from Tomcat – subsequent actions below will take place within the ‘jbpm-install’ folder.

1: Pre-Installation Configuration of Tomcat: Prepare for J2EE

It should be understood that Tomcat is not a J2EE application server – but rather a servlet container.

However – Tomcat can be made to behave like a J2EE application server.

In order to make this so, J2EE components need to be installed and configured on Tomcat.

For JBPM this is an apriori requirement. The steps below shall add the following J2EE services to Tomcat:

  • JTA (Java Transaction API)
  • Bitronix 2.1.3 Transaction Manager
  • JMS
  • JACC

a) In jbpm-install create folder: tomcat2j2ee \

b) In jbpm-install\tomcat2j2ee create the following files:

ivy.xml

<ivy-module version="2.0">
<info organisation="jbpm" module="btm" />
<dependencies>
    <dependency org="org.codehaus.btm" name="btm-dist" rev="2.1.3" />
     <dependency org="org.codehaus.btm" name="btm" rev="2.1.3">
          <artifact name="btm" type="jar" />
     </dependency>

     <dependency org="javax.transaction" name="jta" rev="1.1">
          <artifact name="jta" type="jar" />
     </dependency>
     
    <dependency org="org.apache.geronimo.specs" name="geronimo-jacc_1.1_spec" rev="1.0.2" >
          <artifact name="geronimo-jacc_1.1_spec" type="jar" />
     </dependency>
    </dependencies>
</ivy-module>

build.xml

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns:ivy="antlib:org.apache.ivy.ant" name="J2EE.install">

  <property name="install.home" value="./" />

  <property environment="env"/>
  <property name="tomcat.home" value="${env.CATALINA_HOME}"/>  
  <property name="tomcat.7.server.lib.dir" value="${tomcat.home}/lib" />

  <!-- ############ TOP LEVEL INSTALLATION ########### -->
  <target name="install.j2ee.to.tomcat.7" depends="download.j2ee">
     <copy todir="${tomcat.7.server.lib.dir}/">
         <fileset dir="${install.home}/lib" includes="*.jar" />
    </copy>
  </target>

  <target name="download.j2ee.check">
    <echo message="Checking J2EE Download..." />
     <condition property="btm.not.available">
       <not>
         <available file="${install.home}/lib/btm-2.1.3.jar" />
       </not>
     </condition>
  </target>
  <target name="download.j2ee" depends="download.j2ee.check" if="btm.not.available">
    <echo message="Getting J2EE..." />
     <mkdir dir="${install.home}/lib"/>
     <ivy:retrieve />  
  </target>
  
</project>

c) In jbpm-install\tomcat2j2ee execute:

ant install.j2ee.to.tomcat.7

d) Create the following file in ${CATALINA_HOME}\conf

btm-config.properties

bitronix.tm.serverId=tomcat-btm-node0
bitronix.tm.journal.disk.logPart1Filename=${btm.root}/work/btm1.tlog
bitronix.tm.journal.disk.logPart2Filename=${btm.root}/work/btm2.tlog
bitronix.tm.resource.configuration=${btm.root}/conf/resources.properties

NB: The following option may also be of use for test / dev purposes:

bitronix.tm.2pc.debugZeroResourceTransactions=true

e) Add the following parameters to $CATALINA_OPTS – such that they are passed to JVM when Tomcat starts:

-Dbtm.root=${CATALINA_HOME}
-Dbitronix.tm.configuration=${CATALINA_HOME}/conf/btm-config.properties

NB: On windows do this through the configuration tool – do not set environment variable unless you understand the implications.

You will need to specify ${CATALINA_HOME} in full rather than using environment variable.

You should now have a Tomcat 7 installation with J2EE services required for JBPM present.

2: Installation JBPM 5.3 : Pre-Configuration

The installation process for JBPM 5.3 shall be presented in script form below.

Before that step though it is required to create and perform some initial configuration of both JBPM and Tomcat.

a) Configuration of Tomcat

i) Reconfigure ${CATALINA_HOME}/server.xml

Add following entries to ${CATALINA_HOME}/server.xml after the server entry for: org.apache.catalina.core.JreMemoryLeakPreventionListener

<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Listener className="bitronix.tm.integration.tomcat55.BTMLifecycleListener" />

Add the following entries to the section: <GlobalNamingResources>

<Resource name="jdbc/testDS1" uniqueName="jdbc/testDS1" auth="Container" removeAbandoned="true" factory="bitronix.tm.resource.ResourceObjectFactory" type="javax.sql.DataSource" /> <Resource name="jta/UserTransaction" auth="Container" type="javax.transaction.UserTransaction" factory="bitronix.tm.BitronixUserTransactionObjectFactory" /> <Resource name="TransactionManager" auth="Container" type="javax.transaction.TransactionManager" factory="bitronix.tm.BitronixTransactionManagerObjectFactory" /> <Resource name="TransactionSynchronizationRegistry" auth="Container" type="javax.transaction.TransactionSynchronizationRegistry" factory="bitronix.tm.BitronixTransactionSynchronizationRegistryObjectFactory" /> <Resource name="jdbc/testDS1NonBTM"

uniqueName="jdbc/testDS1NonBTM"

auth="Container"

removeAbandoned="true"

type="javax.sql.DataSource"

scope="Shareable"

maxActive="100"

maxIdle="30"

username="sa"

password=""

driverClassName="org.h2.driver"

url="jdbc:h2:tcp://localhost/~/test"/>

ii) Reconfigure ${CATALINA_HOME}/context.xml

Add the following entries to context.xml after ‘WatchedResource’:

<Transaction factory="bitronix.tm.BitronixUserTransactionObjectFactory" /> <!-- To make java:comp/env/testDS1 available for reports - via jdbc/testDS1 --> <ResourceLink global="jdbc/testDS1" name="jdbc/testDS1" type="javax.sql.DataSource" />

<!-- To make java:comp/env/testDS1NonBTM available for the console - Non Transactional --> <ResourceLink global="jdbc/testDS1NonBTM" name="jdbc/testDS1NonBTM" type="javax.sql.DataSource" />

NB: The Birt reporting by default will use Tomcat JNDI to look up resources.

The global resources defined in server.xml in terms of Bitronix JNDI are aliased to Tomcat’s JNDI using resourcelink’s above.

The hibernate configuration (below…) uses a mix of Bitronix and non Bitronix. The Console uses a non transaction managed connection, the console-server does though.

b) Configuration of JBPM

i) Create the following files in: jbpm-install\db

resources.properties

resource.ds1.className=bitronix.tm.resource.jdbc.lrc.LrcXADataSource resource.ds1.uniqueName=jdbc/testDS1 resource.ds1.minPoolSize=0 resource.ds1.maxPoolSize=5 resource.ds1.driverProperties.driverClassName=org.h2.Driver resource.ds1.driverProperties.url=jdbc:h2:tcp://localhost/~/test resource.ds1.driverProperties.user=sa resource.ds1.driverProperties.password=

resource.ds1.allowLocalTransactions=true resource.ds1.testQuery=SELECT 1+1

persistence.xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<persistence version="1.0" xsi:schemaLocation= "http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_1_0.xsd" xmlns:orm="http://java.sun.com/xml/ns/persistence/orm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/persistence">

<persistence-unit name="org.jbpm.persistence.jpa" transaction-type="JTA">

<provider>org.hibernate.ejb.HibernatePersistence</provider>

<jta-data-source>java:comp/env/jdbc/testDS1</jta-data-source> <mapping-file>META-INF/JBPMorm.xml</mapping-file>

<class>org.jbpm.persistence.processinstance.ProcessInstanceInfo</class>

<class>org.drools.persistence.info.WorkItemInfo</class>

<class>org.drools.persistence.info.SessionInfo</class> <class>org.jbpm.process.audit.ProcessInstanceLog</class>

<class>org.jbpm.process.audit.NodeInstanceLog</class>

<class>org.jbpm.process.audit.VariableInstanceLog</class>

<properties>

<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>

<property name="hibernate.current_session_context_class" value="jta" />

<property name="hibernate.transaction.fatory_class" value="org.hibernate.transaction.JTATransactionFactory" />

<property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.BTMTransactionManagerLookup" />

<property name="hibernate.cache.provider_class" value="org.hibernate.cache.NoCacheProvider" />

<property name="hibernate.cache.use_second_level_cache" value="false" />

<property name="hibernate.max_fetch_depth" value="3"/>

<property name="hibernate.hbm2ddl.auto" value="update" />

<property name="hibernate.show_sql" value="false" />

</properties>

</persistence-unit>

</persistence>

hibernate.cfg.xml

<?xml version='1.0' encoding='utf-8'?>

<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

<session-factory>

<!-- The following is explicitly not using JTA -->

<!-- Direct - JNDI - Not BTM -->

<property name="connection.datasource">java:comp/env/jdbc/testDS1NonBTM</property>

<property name="current_session_context_class">thread</property>

<!-- Direct - Non JNDI -->

<!--

<property name="connection.driver_class">org.h2.Driver</property>

<property name="connection.url">jdbc:h2:tcp://localhost/~/test</property>

<property name="connection.username">sa</property>

<property name="connection.password"></property>

<property name="current_session_context_class">thread</property>

-->

<!-- The following is JTA version using Bitronix jndi / pool / transaction management -->

<!--

<property name="jndi.class" value="bitronix.tm.jndi.BitronixInitialContextFactory"/> <property name="hibernate.jndi.java.naming.factory.initial" value="bitronix.tm.jndi.BitronixInitialContextFactory" />

<property name="transaction.factory_class" value="org.hibernate.transaction.JTATransactionFactory" />

<property name="current_session_context_class">jta</property>

<property name="jta.userTransaction">java:comp/UserTransaction</property>

<property name="transaction.manager_lookup_class" value="org.hibernate.transaction.BTMTransactionManagerLookup" />

<property name="connection.datasource" value="jdbc/testDS1" />

-->

<property name="dialect">org.hibernate.dialect.H2Dialect</property>

<property name="max_fetch_depth">3</property>

<!-- JDBC connection pool (use the built-in) -->

<property name="connection.pool_size">1</property>

<!-- Disable the second-level cache -->

<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>

<property name="show_sql">false</property>

<property name="hbm2ddl.auto">update</property>

<mapping resource="AuditLog.hbm.xml"/>

</session-factory>

</hibernate-configuration>

persistence-human-task-service.xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<persistence version="1.0"

xsi:schemaLocation="http://java.sun.com/xml/ns/persistence

http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd

http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_1_0.xsd"

xmlns:orm="http://java.sun.com/xml/ns/persistence/orm"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns="http://java.sun.com/xml/ns/persistence">

<persistence-unit name="org.jbpm.task">

<provider>org.hibernate.ejb.HibernatePersistence</provider>

<mapping-file>META-INF/Taskorm.xml</mapping-file>

<class>org.jbpm.task.Attachment</class>

<class>org.jbpm.task.Content</class>

<class>org.jbpm.task.BooleanExpression</class>

<class>org.jbpm.task.Comment</class>

<class>org.jbpm.task.Deadline</class>

<class>org.jbpm.task.Comment</class>

<class>org.jbpm.task.Deadline</class>

<class>org.jbpm.task.Delegation</class>

<class>org.jbpm.task.Escalation</class>

<class>org.jbpm.task.Group</class>

<class>org.jbpm.task.I18NText</class>

<class>org.jbpm.task.Notification</class>

<class>org.jbpm.task.EmailNotification</class>

<class>org.jbpm.task.EmailNotificationHeader</class>

<class>org.jbpm.task.PeopleAssignments</class>

<class>org.jbpm.task.Reassignment</class>

<class>org.jbpm.task.Status</class>

<class>org.jbpm.task.Task</class>

<class>org.jbpm.task.TaskData</class>

<class>org.jbpm.task.SubTasksStrategy</class>

<class>org.jbpm.task.OnParentAbortAllSubTasksEndStrategy</class>

<class>org.jbpm.task.OnAllSubTasksEndParentEndStrategy</class>

<class>org.jbpm.task.User</class>

<properties>

<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>

<property name="hibernate.connection.driver_class" value="org.h2.Driver"/>

<property name="hibernate.connection.url" value="jdbc:h2:tcp://localhost/~/test" />

<property name="hibernate.connection.username" value="sa"/>

<property name="hibernate.connection.password" value=""/>

<property name="hibernate.connection.autocommit" value="true" />

<property name="hibernate.max_fetch_depth" value="3"/>

<property name="hibernate.hbm2ddl.auto" value="create" />

<property name="hibernate.show_sql" value="false" />

</properties>

</persistence-unit>

</persistence>

NB: The above configurations will make use of H2 backend database – data sources are configured through JNDI using Bitronix as initial context.

Bitronix / JTA is not used in the hibernate.cfg.xml above: This configuration is used during interaction between the console and console- server.

Checkpoint: We have at this point installed required J2EE services to Tomcat, configured JNDI datasource components for JPBM on Tomcat and prepared a configuration of JPBM 5.2 to be installed.

The next step is to perform the JBPM installation to Tomcat.

3: Installation JBPM 5.2

a) Add the following to the end of: jbpm-install\build.properties

# Tomcat Server Version
tomcat.server.version=7
# Database Parameters
# H2
h2.jdbc.driver.version=1.2.124
# Defines MySQL Connect JDBC Driver to Use
mysql.jdbc.driver.version=5.1.20

b) Create the following files in jbpm-install:

ivy.xml

<ivy-module version="2.0">
<info organisation="jbpm" module="btm" />
<dependencies>     
     <dependency org="javassist" name="javassist" rev="3.4.GA">
          <artifact name="javassist" type="jar" />
     </dependency>
</dependencies>
</ivy-module>

tomcat7build.xml

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns:ivy="antlib:org.apache.ivy.ant" name="jBPM.install">

<property file="build.properties" />

<property name="install.home" value="./" />

<property environment="env"/>

<property name="tomcat.home" value="${env.CATALINA_HOME}"/>

<property name="tomcat.7.server.conf.dir" value="${tomcat.home}/conf" />

<property name="tomcat.7.server.lib.dir" value="${tomcat.home}/lib" />

<property name="tomcat.7.server.deploy.dir" value="${tomcat.home}/webapps" />

<property name="tomcat.bind.address" value="localhost" />

<property name="h2.jdbc.jar" value="h2-${h2.jdbc.driver.version}.jar" />

<property name="h2.download.url" value="http://repo1.maven.org/maven2/com/h2database/h2/${h2.jdbc.driver.version}/${h2.jdbc.jar}"/>

<property name="mysql.jdbc.jar" value="mysql-connector-java-${mysql.jdbc.driver.version}.jar" />

<property name="mysql.download.url" value="http://repo1.maven.org/maven2/mysql/mysql-connector-java/${mysql.jdbc.driver.version}/${mysql.jdbc.jar}"/>

<property name="birt.version.as7" value="3_7_0"/>

<property name="birt.download.url.as7" value="http://www.eclipse.org/downloads/download.php?file=/birt/downloads/drops/R-R1-3_7_0-201106151818/birt-runtime-3_7_0.zip&amp;url=http://download.eclipse.org/birt/downloads/drops/R-R1-3_7_0-201106151818/birt-runtime-3_7_0.zip&amp;mirror_id=1"/>

<!-- ############ TOP LEVEL INSTALLATION ########### -->

<target name="install.jbpmfull.to.tomcat.7">

<antcall target="download.dependencies" />

<antcall target="install.bitronix.config.into.tomcat.7" />

<antcall target="install.jBPM.into.tomcat.7" />

<antcall target="install.guvnor.into.tomcat.7" />

<antcall target="install.designer.into.tomcat.7" />

</target>

<target name="start.demo">

<antcall target="install.jBPM.runtime" />

<antcall target="start.human.task" />

</target>

<target name="install.jbpmfull.config.only.to.tomcat.7" >

<antcall target="install.bitronix.config.into.tomcat.7" />

<antcall target="install.gwtconsoleserver.config.into.tomcat.7" />

</target>

<!-- ############ TOMCAT SUPPORT ########### -->

<target name="check.tomcat.version">

<condition property="tomcat.version.is.7">

<equals arg1="${tomcat.server.version}" arg2="7" />

</condition>

</target>

<!-- ############ DOWNLOAD ############ -->

<!-- Dependencies -->

<target name="download.dependencies">

<echo message="Getting Dependencies ..." />

<mkdir dir="${install.home}/lib"/>

<ivy:retrieve />

</target>

<!-- Databases -->

<!-- Download H2 -->

<target name="download.h2.check">

<echo message="Checking H2 download ..." />

<condition property="h2.not.available">

<not>

<available file="${install.home}/db/driver/${h2.jdbc.jar}" />

</not>

</condition>

</target>

<target name="download.h2" depends="download.h2.check" if="h2.not.available">

<echo message="Getting H2..." />

<mkdir dir="${install.home}/db/driver"/>

<get src="${h2.download.url}" dest="${install.home}/db/driver/${h2.jdbc.jar}" />

</target>

<!-- Download MySQL -->

<target name="download.mysql.check">

<echo message="Checking MySql download..." />

<condition property="mysql.not.available">

<not>

<available file="${install.home}/db/driver/${mysql.jdbc.jar}" />

</not>

</condition>

</target>

<target name="download.mysql" depends="download.mysql.check" if="mysql.not.available">

<echo message="Getting MySql ..." />

<mkdir dir="${install.home}/db/driver"/>

<get src="${mysql.download.url}" dest="${install.home}/db/driver/${mysql.jdbc.jar}" />

</target>

<!-- Download jBPM binaries -->

<target name="download.jBPM.bin.check">

<echo message="Checking jBPM binaries download ..." />

<condition property="jBPM.bin.not.available">

<not>

<available file="${install.home}/lib/jbpm-${jBPM.version}-bin.zip" />

</not>

</condition>

</target>

<target name="download.jBPM.bin" depends="download.jBPM.bin.check" if="jBPM.bin.not.available">

<echo message="Getting jBPM binaries ..." />

<mkdir dir="${install.home}/lib"/>

<get src="${jBPM.url}/jbpm-${jBPM.version}-bin.zip" dest="${install.home}/lib/jbpm-${jBPM.version}-bin.zip" />

</target>

<!-- Download Drools Guvnor -->

<target name="download.drools.guvnor.check">

<echo message="Checking Drools Guvnor download ..." />

<condition property="drools.guvnor.not.available">

<not>

<available file="${install.home}/lib/guvnor-distribution-wars-${drools.guvnor.version}.war" />

</not>

</condition>

</target>

<target name="download.drools.guvnor" depends="download.drools.guvnor.check" if="drools.guvnor.not.available">

<echo message="Getting Drools Guvnor ..." />

<mkdir dir="${install.home}/lib"/>

<get src="${drools.guvnor.url}" dest="${install.home}/lib/guvnor-distribution-wars-${drools.guvnor.version}.war"/>

</target>

<!-- Download Designer -->

<target name="download.designer.check">

<echo message="Checking Designer download ..." />

<condition property="designer.not.available">

<not>

<available file="${install.home}/lib/designer-${designer.version}.war" />

</not>

</condition>

</target>

<target name="download.designer" depends="download.designer.check" if="designer.not.available">

<echo message="Getting Designer ..." />

<mkdir dir="${install.home}/lib"/>

<get src="${designer.url}/designer-${designer.version}.war" dest="${install.home}/lib/designer-${designer.version}.war" />

</target>

<!-- Download form builder -->

<target name="download.form.builder.check">

<echo message="Checking Form Builder download ..." />

<condition property="form.builder.not.available">

<not>

<available file="${install.home}/lib/jbpm-${jBPM.version}-form-builder.war" />

</not>

</condition>

</target>

<target name="download.form.builder" depends="download.form.builder.check" if="form.builder.not.available">

<echo message="Getting Form Builder ..." />

<mkdir dir="${install.home}/lib"/>

<get src="${form.builder.url}" dest="${install.home}/lib/jbpm-${jBPM.version}-form-builder.war" />

</target>

<!-- Download jBPM gwt-console -->

<target name="download.jBPM.gwt-console.check">

<echo message="Checking jBPM gwt-console download ..." />

<condition property="jBPM.gwt-console.not.available">

<not>

<available file="${install.home}/lib/jbpm-${jBPM.version}-gwt-console.zip" />

</not>

</condition>

</target>

<target name="download.jBPM.gwt-console" depends="download.jBPM.gwt-console.check" if="jBPM.gwt-console.not.available">

<echo message="Getting jBPM gwt-console ..." />

<mkdir dir="${install.home}/lib"/>

<get src="${jBPM.url}/jbpm-${jBPM.version}-gwt-console.zip" dest="${install.home}/lib/jbpm-${jBPM.version}-gwt-console.zip" />

</target>

<!-- Download BIRT engine for AS7 -->

<target name="check.birt.as7">

<condition property="birt.download">

<equals arg1="${jBPM.birt.download}" arg2="true" />

</condition>

</target>

<target name="download.birt.check.as7" depends="check.birt.as7" if="birt.download">

<echo message="Checking birt reporting engine download for as7 ..." />

<condition property="birt.not.available">

<not>

<available file="${install.home}/lib/birt-runtime-${birt.version.as7}.zip" />

</not>

</condition>

</target>

<target name="download.birt.as7" depends="download.birt.check.as7" if="birt.not.available">

<echo message="Getting birt reporting engine for AS7 ..." />

<mkdir dir="${install.home}/lib"/>

<get src="${birt.download.url.as7}" dest="${install.home}/lib/birt-runtime-${birt.version.as7}.zip" />

</target>

<!-- ############ INSTALL ############ -->

<!-- Install Bitronix -->

<target name="install.bitronix.config.into.tomcat.7">

<copy todir="${tomcat.7.server.conf.dir}"

file="${install.home}/db/resources.properties"

overwrite="true" />

</target>

<!-- Install gtw-console-server config -->

<target name="install.gwtconsoleserver.config.into.tomcat.7">

<copy todir="${tomcat.7.server.deploy.dir}/gwt-console-server/WEB-INF/classes"

file="${install.home}/db/hibernate.cfg.xml"

overwrite="true" />

<copy todir="${tomcat.7.server.deploy.dir}/gwt-console-server/WEB-INF/classes/META-INF"

file="${install.home}/db/persistence.xml"

overwrite="true" />

</target>

<!-- Install JDBC -->

<target name="install.h2.into.tomcat.7" depends="download.h2,check.tomcat.version">

<copy todir="${tomcat.7.server.lib.dir}"

file="${install.home}/db/driver/${h2.jdbc.jar}"

overwrite="true" />

</target>

<target name="install.mysql.into.tomcat.7" depends="download.mysql,check.tomcat.version">

<copy todir="${tomcat.7.server.lib.dir}"

file="${install.home}/db/driver/${mysql.jdbc.jar}"

overwrite="true" />

</target>

<!-- Install guvnor -->

<target name="install.guvnor.into.tomcat.7" depends="download.drools.guvnor,check.tomcat.version">

<mkdir dir="${install.home}/target"/>

<mkdir dir="${install.home}/target/jbpm-drools-guvnor-war"/>

<unzip src="${install.home}/lib/guvnor-distribution-wars-${drools.guvnor.version}.war"

dest="${install.home}/target/jbpm-drools-guvnor-war" />

<!-- Fixes for Tomcat... -->

<delete file="${install.home}/target/jbpm-drools-guvnor-war/WEB-INF/lib/servlet-api-2.5.jar"/>

<zip basedir="${install.home}/target/jbpm-drools-guvnor-war"

destfile="${install.home}/target/guvnor-distribution-wars-${drools.guvnor.version}.war" />

<copy file="${install.home}/target/guvnor-distribution-wars-${drools.guvnor.version}.war"

tofile="${tomcat.7.server.deploy.dir}/drools-guvnor.war"

overwrite="true" />

<delete dir="${install.home}/target"/>

</target>

<!-- Install designer -->

<target name="install.designer.into.tomcat.7" depends="download.designer,check.tomcat.version">

<copy file="${install.home}/lib/designer-${designer.version}.war"

tofile="${tomcat.7.server.deploy.dir}/designer.war"

overwrite="true" />

</target>

<!-- Install gwt-console -->

<target name="install.jBPM.into.tomcat.7" depends="download.mysql,download.h2,download.jBPM.gwt-console" >

<antcall target="install.mysql.into.tomcat.7" />

<antcall target="install.h2.into.tomcat.7" />

<mkdir dir="${install.home}/target"/>

<unzip src="${install.home}/lib/jbpm-${jBPM.version}-gwt-console.zip"

dest="${install.home}/target/" />

<antcall target="install.jBPM-gwt-console.into.tomcat.7" />

<antcall target="install.jBPM-gwt-console-server.into.tomcat.7" />

<delete dir="${install.home}/target"/>

</target>


<target name="install.jBPM-gwt-console.into.tomcat.7" depends="check.tomcat.version" if="tomcat.version.is.7">

<!-- gwt-console -->

<unzip src="${install.home}/target/jbpm-gwt-console-${jBPM.version}.war"

dest="${install.home}/target/jbpm-gwt-console-war"/>



<!-- Fix for conflicting javassist jar -->

<delete file="${install.home}/target/jbpm-gwt-console-war/WEB-INF/lib/javassist-3.6.0.GA.jar"/>

<!-- Further fixes for Tomcat... -->

<delete file="${install.home}/target/jbpm-gwt-console-war/WEB-INF/lib/jta-1.1.jar"/>

<delete file="${install.home}/target/jbpm-gwt-console-war/WEB-INF/lib/dom4j-1.6.jar"/>

<copy todir="${install.home}/target/jbpm-gwt-console-war/WEB-INF/lib"

file="${install.home}/lib/javassist-3.4.GA.jar"

overwrite="true" />

<!-- Repackage WAR and deploy -->

<zip basedir="${install.home}/target/jbpm-gwt-console-war"

destfile="${install.home}/target/jbpm-gwt-console-${jBPM.version}.war"/>

<copy file="${install.home}/target/jbpm-gwt-console-${jBPM.version}.war"

tofile="${tomcat.7.server.deploy.dir}/jbpm-console.war"

overwrite="true" />

</target>


<!-- Install gwt-console-server -->

<target name="install.jBPM-gwt-console-server.into.tomcat.7" depends="check.tomcat.version" if="tomcat.version.is.7">

<!-- reporting -->

<antcall target="download.birt.as7" />

<!-- gwt-console-server -->

<unzip src="${install.home}/target/jbpm-gwt-console-server-${jBPM.version}.war"

dest="${install.home}/target/jbpm-gwt-console-server-war"/>

<copy file="${install.home}/db/hibernate.cfg.xml"

tofile="${install.home}/target/jbpm-gwt-console-server-war/WEB-INF/classes/hibernate.cfg.xml"

overwrite="true" />

<copy file="${install.home}/db/persistence.xml"

tofile="${install.home}/target/jbpm-gwt-console-server-war/WEB-INF/classes/META-INF/persistence.xml"

overwrite="true" />

<copy file="${install.home}/auth/users.properties"

tofile="${install.home}/target/jbpm-gwt-console-server-war/WEB-INF/classes/users.properties"

overwrite="true" />

<copy file="${install.home}/auth/roles.properties"

tofile="${install.home}/target/jbpm-gwt-console-server-war/WEB-INF/classes/roles.properties"

overwrite="true" />

<copy file="${install.home}/jbpm-tm.jar"

tofile="${install.home}/target/jbpm-gwt-console-server-war/WEB-INF/lib/jbpm-tm.jar"

overwrite="true" />

<!-- Fix for conflicting javassist jar -->

<delete file="${install.home}/target/jbpm-gwt-console-server-war/WEB-INF/lib/javassist-3.6.0.GA.jar"/>

<delete file="${install.home}/target/jbpm-gwt-console-server-war/WEB-INF/lib/javassist-3.14.0-GA.jar" />

<copy todir="${install.home}/target/jbpm-gwt-console-server-war/WEB-INF/lib"

file="${install.home}/lib/javassist-3.4.GA.jar"

overwrite="true" />

<!-- Further fixes for Tomcat... -->

<delete file="${install.home}/target/jbpm-gwt-console-server-war/WEB-INF/lib/el-api-1.2.jar"/>

<delete file="${install.home}/target/jbpm-gwt-console-server-war/WEB-INF/lib/dom4j-1.6.jar"/>

<!-- Other configuration like work item handlers -->

<copy todir="${install.home}/target/jbpm-gwt-console-server-war/WEB-INF/classes" overwrite="true">

<fileset dir="${install.home}/conf"/>

</copy>

<!-- reporting -->

<antcall target="install.reporting.into.tomcat.7" />

<zip basedir="${install.home}/target/jbpm-gwt-console-server-war"

destfile="${install.home}/target/jbpm-gwt-console-server-${jBPM.version}.war"/>

<copy file="${install.home}/target/jbpm-gwt-console-server-${jBPM.version}.war"

tofile="${tomcat.7.server.deploy.dir}/gwt-console-server.war"

overwrite="true" />

</target>

<!-- Install reporting Tomcat7 -->

<target name="install.reporting.into.tomcat.7" depends="check.birt.as7" if="birt.download" >

<mkdir dir="${install.home}/birt"/>

<unzip src="${install.home}/lib/birt-runtime-${birt.version.as7}.zip"

dest="${install.home}/birt"/>

<copy todir="${install.home}/target/jbpm-gwt-console-server-war/WEB-INF/lib">

<fileset dir="${install.home}/birt/birt-runtime-${birt.version.as7}/ReportEngine/lib">

<include name="**/*.jar"/>

</fileset>

</copy>

<mkdir dir="${install.home}/target/jbpm-gwt-console-server-war/WEB-INF/output"/>

<mkdir dir="${install.home}/target/jbpm-gwt-console-server-war/WEB-INF/output/image"/>

<mkdir dir="${install.home}/target/jbpm-gwt-console-server-war/WEB-INF/reports"/>

<copy file="${install.home}/report/${birt.version.as7}/overall_activity.rptdesign"

tofile="${install.home}/target/jbpm-gwt-console-server-war/WEB-INF/reports/overall_activity.rptdesign"

overwrite="true"/>

<delete dir="${install.home}/birt"/>

</target>


<!-- Install Demo -->


<!-- create runtime -->

<target name="install.jBPM.runtime" depends="download.jBPM.bin">

<mkdir dir="${install.home}/runtime"/>

<unzip src="${install.home}/lib/jbpm-${jBPM.version}-bin.zip" dest="${install.home}/runtime" />

</target>



<path id="classpath.human.task">

<fileset dir="${install.home}/runtime" includes="**/*.jar"/>

<fileset dir="${install.home}/db/driver" includes="**/*.jar"/>

</path>

<target name="start.human.task">

<mkdir dir="${install.home}/task-service/target"/>

<javac includeantruntime="false" srcdir="${install.home}/task-service/src" destdir="${install.home}/task-service/target" classpathref="classpath.human.task">

<compilerarg value="-Xlint:unchecked"/>

</javac>

<copy tofile="${install.home}/task-service/resources/META-INF/persistence.xml"

file="${install.home}/db/persistence-human-task-service.xml"

overwrite="true" />

<copy todir="${install.home}/task-service/target">

<fileset dir="${install.home}/task-service/resources"/>

</copy>

<java classname="org.jbpm.DemoTaskService" fork="true">

<classpath>

<pathelement path="${install.home}/task-service/target"/>

<path refid="classpath.human.task" />

</classpath>

</java>

</target>

</project>

c) Perform the installation: In jbpm-install execute:

ant -buildfile tomcat7build.xml install.jbpmfull.to.tomcat.7

d) Add the following parameters to $CATALINA_OPTS and passed to JVM when Tomcat started:

-Xms256m
-Xmx1024m
-XX:PermSize=128m
-XX:MaxPermSize=256m
-Dreporting.needcontext=true

NB: On windows do this through the configuration tool – do not set environment variable unless you understand the implications.

Checkpoint: We have at this point installed JBPM 5.2 to Tomcat.

4: Running the Demo

a) Update report definition: ${CATALINA_HOME}/webapps/gwt-console-server/WEB-INF/reports/overall_activity.rptdesign

Add following to ‘oda-data-source’ section:

<property name="odaJndiName">java:comp/env/jdbc/testDS1</property>

b) Add following to Tomcat startup parameter:

-Djbpm.console.directory=\sample\evaluation\src\main\resources

c) Reconfigure ${CATALINA_HOME}/tomcat-users.xml, add:

<role rolename="manager" />
<role rolename="admin" />
<role rolename="user" />
<role rolename="PM" />
<role rolename="HR" />
<role rolename="webdesigner" />
<role rolename="functionalanalyst" />
<role rolename="sales" />
<user username="krisv" password="krisv" roles="manager,admin,user" />
<user username="john" password="john" roles="admin,manager,user,PM" />
<user username="mary" password="mary" roles="admin,manager,user,HR" />
<user username="sales-rep" password="sales-rep" roles="admin,manager,user,sales" />
<user username="admin" password="admin" roles="admin,manager,user,webdesigner,functionalanalyst" />

e) Start H2: In jbpm-install execute:

ant start.h2

f) Start The Human Task Service: In jbpm-install execute:

ant -tomcat7demo start.demo

g) Start Tomcat

h) Naviate to: http://localhost:8080/jbpm-console

Trouble Shooting

  • Ant warning when launching human task: ‘warning: ‘includeantruntime’ was not set’

Edit jbpm-installer/build.xml and add following attribute to the start.human.task target javac directive:

includeantruntime=”false”

For more details see: http://stackoverflow.com/questions/5103384/ant-warning-includeantruntime-was-not-set

  • Confirm H2 database initialized

The H2 database should be initialized with demo user details once the human task engine has been started (assuming H2 is running).

H2 default port is: 9092

Connect using SQL interface (eg. Squirrel) and check that schema TEST exists. There should be several tables, ORGANIZATIONALENTITY should have entries.

  • Error is received in jbpm-console indicating EOFException has occurred

This is most likely due to corruption of the persistence work files.

To repair, stop Tomcat and delete ${CATALINA_HOME}/work

  • Report Engine fails indicating IllegalAccessException – report server not initialized

Assuming step 7 above has been completed, ensure that the reporting.needcontext parameter has been passed to Tomcat runtime at startup – see 7E above.

Additional Links / Resources

BIRT Homepage

http://www.eclipse.org/birt/phoenix/ Hibernate