How to Run jbpm on SJSAS/Glassfish with Derby
By Cheng Fang on Mar 22, 2006
Jbpm is a workflow and business process engine from Jboss, and is tightly integrated with JBoss appserver. Recently some people asked if jbpm can run on SJSAS/Glassfish. My first response is, absolutely, any J2EE/JavaEE applications can run on SJSAS/Glassfish, with more or less tweaks. So I decided to prove this with jbpm 3.1 on SJSAS 8.2 and Glassfish. Steps in this article have been successfully tested with SJSAS 8.2 final release, and Glassfish build 43 (very close to final release). Before we start, a few noteworthy points:
- jbpm configures some libraries as service archives, \*.sar, and deploy them to Jboss appserver. Service archive is not a J2EE standard component and is not portable in non-Jboss servers. Here we have to treat them as a ordinary library jar and ignore its service configuration.
- jbpm uses Apache myfaces as its JSF implementatioin, while SJSAS uses Sun's JSF implementation. Here I will plug-in myfaces to SJSAS/Glassfish.
- jbpm doesn't package certain jar files into jbpm.war, since these jars are already bundled with Jboss server, such as hibernate, antlr, asm, etc. They are not in SJSAS/Glassfish, and we need to package these jars into jbpm.war. For better separation, we could also install these jars in $SJSAS_HOME/domains/domain1/lib, and make them available to all hosted applications in domain1. For the purpose of illustration, I will just copy all relevant jars to $SJSAS_HOME/lib
- Database connectivity is managed by Hibernate, which talks to Derby directly. It does not use any server-managed DataSource.
- Changes are limited to configuration and build files. So far no need to modify any jbpm java source code.
- There are some slight differences between configuring SJSAS 8.2
and Glassfish. Other steps are all the same.
Download and install SJSAS 8.2, or Glassfish. The install directory will be your SJSAS_HOME for both SJSAS and Glassfish.
Download and unzip jbpm 3.1 Starter's Kit. You can choose either the starters' kit, or the jbpm.zip file. Starters' kit contains extra database scripts, among other things. After unzip, you will have a directory similar to /file/jbpm (if you unzip jbpm zip file), or /file/starters-kit/jbpm (if you unzip starter's kit). They will be the JBPM_HOME hereafter.
Download commons-el.jar, if you see NoClassDefFoundError:org.apache.commons.el.Logger. If you don't know a better place, just download Tomcat 5.5.16, and extract the jar. Tomcat install dir will be referred to as CATALINA_HOME. At one point, this solved my problem. Then later everything works fine even without commons-el.jar.
Turn off SecurityManager, for now.
In Glassfish/SJSAS 9.0 (after mid-March 2006), SecurityManager is off by default. In SJSAS 8.x, SecurityManager is on by default. Hibernate used by jbpm needs some extra permission than allowed by the default server.policy, such as connecting to databases, and loading certain classes. Stop the domain and comment out the two lines in
<jvm-options>-Djava.security.manager</jvm-options>(if this line is present)
In production mode, you should always keep the SecurityManager on and configure the appropriate permissions.
Switch from Sun's JSF implementation to Apache Myfaces, which is used by jbpm 3.1.
Theoretically, you can keep using Sun's JSF implementation. But due to certain JSP minor version mismatch, I couldn't get them work together smoothly. So I decided to use plugin myfaces into SJSAS/Glassfish.
Stop the domain and change jsf-impl.jar to myfaces-impl.jar in $SJSAS_HOME/domains/domain1/config/domain.xml:
Replace jsf api and impl jars. $SJSAS_HOME/lib/\*.jar will be loaded by the server, so we need to rename the unused jars to avoid conflict. Note that there is no jsf-api.jar in Glassfish; JSF API classes are in javaee.jar.
mv $SJSAS_HOME/lib/jsf-api.jar $SJSAS_HOME/lib/jsf-api.jar.bak //For SJSAS 8.2 only
mv $SJSAS_HOME/lib/jsf-impl.jar $SJSAS_HOME/lib/jsf-impl.jar.bak
cp $JBPM_HOME/lib/jsf/myfaces\*.jar $SJSAS_HOME/lib/
Additional Steps for Configuring Glassfish (Not Needed for SJSAS 8.2)
Back up and edit $SJSAS_HOME/lib/processLauncher.xml. You will need to add
"myfaces-api.jar,myfaces-impl.jar,"to the beginning of the value of
<sysproperty key="com.sun.aas.classloader.sharedChainJars". You may also want to remove "
jsf-api.jar, jsf-impl.jar" from the value of this element.
Copy a series of jars to $SJSAS_HOME/lib:
cp $JBPM_HOME/lib/commons/commons-fileupload-1.0.jar $SJSAS_HOME/lib
cp $JBPM_HOME/lib/commons/commons-beanutils-1.6.1.jar $SJSAS_HOME/lib
cp $JBPM_HOME/lib/commons/commons-digester-1.5.jar $SJSAS_HOME/lib
cp $JBPM_HOME/lib/jboss/commons-logging.jar $SJSAS_HOME/lib
cp $JBPM_HOME/lib/jboss/commons-collections.jar $SJSAS_HOME/lib
cp $JBPM_HOME/lib/jboss/log4j.jar $SJSAS_HOME/lib
cp $CATALINA_HOME/common/lib/commons-el.jar $SJSAS_HOME/lib
Back up and edit $JBPM_HOME/src/config.files/hibernate.cfg.xml.
You only need to modify jdbc connection section:
<!-- jdbc connection properties -->
Create a new directory for derby, used when creating database schemas and populating tables:
cp $JBPM_HOME/src/resources/hsqldb/\* $JBPM_HOME/src/resources/derby/
Edit $JBPM_HOME/src/resources/derby/create.db.hibernate.properties, as follows:
Add derby jars to jbpm/lib/derby so that they can be included in build classpath:
mkdir $JBPM_HOME/lib/derby(You don't need Derby localization jars)
cp $SJSAS_HOME/derby/lib/\*jar $JBPM_HOME/lib/derby/
Back up and edit $JBPM_HOME/build.deploy.xml.
appending two new targets, and adding more fileset elements to build.webapp target in build.deploy.xml.
<target name="build.webapp" description="builds jbpm.war">
<ant antfile="build.xml" target="build.webapp" />
<!-- START extra files needed for non-Jboss appservers -->
<fileset dir="build/jbpm.sar.dir" includes="\*.jar"/>
<fileset dir="lib/hibernate" includes="hibernate3.jar"/>
<fileset dir="lib/jboss" includes="cglib-2.1_2jboss.jar, commons-collections.jar, log4j.jar, antlr-2.7.5H3.jar, asm-attrs.jar, asm.jar, commons-logging.jar, jboss-common.jar, bsh-1.3.0.jar, xercesImpl.jar, xml-apis.jar"/>
<!-- END extra files needed for non-Jboss appservers -->
<!-- ================= -->
<!-- TASKS FOR DERBY -->
<!-- ================= -->
<target name="create.db.derby" depends="declare.jbpm.tasks"
description="creates a derby database with the jbpm tables and loads the processes in there. Run this target after starting derby">
<ant antfile="build.xml" target="build.processes" inheritall="false" />
<fileset dir="build" includes="\*.process" />
<target name="execute.derby.sql" description="execute a derby sql script with -Dderby.script=path-to-script.">
Build jbpm project
cd $JBPM_HOMERelevant files have been copied to $JBPM_HOME/build/jbpm.war.dir, and jarred up into a war file $JBPM_HOME/build/jbpm.war.
ant -f build.deploy.xml build.webapp
Start Derby with either asadmin command or Derby scripts
If you use Derby scripts, make sure
JAVA_HOME and DERBY_INSTALL environment variable have been set, for example, to /file/jdk504, and $SJSAS_HOME/derby, respectively.
To shutdown Derby with
cd $SJSAS_HOME/derby/frameworks/NetworkServer/bin; ksh startNetworkServer.ksh
asadmin stop-database, or
stopNetworkServer.ksh.Generate schemas and populate tables with create.db.derby target
ant -f build.deploy.xml create.db.derby
Optionally, you may also want to execute individual Derby sql scripts with execute.derby.sql target. You can find a bunch of Derby sql scripts that were generated by Hibernate at
derby.create.sql, derby.drop.sql, derby.clean.sql, derby.drop.create.sql
You can verify table data with Derby's ij tool. This is a sample output from running ij scripting tool:
/file/as82/derby/frameworks/NetworkServer/bin > ksh ij.ksh
ij version 10.1
ij> connect 'jdbc:derby://localhost:1527/sun-appserv-samples;create=true;user=APP;password=APP';
ij> select NAME_ from JBPM_ID_USER;
4 rows selected
ij> quit;If JBPM_ID_USER table has not been populated, you can do it with execute.derby.sql target. First, create a derby.insert.sql file based on this. Note that you need to remove the single quote around the ID_ value, e.g., '1', '2'.
Deploy jbpm.war to SJSAS
$SJSAS_HOME/bin/asadmin deploy $JBPM_HOME/build/jbpm.war, or you can just use autodeploy by copying the war to
Finally, the show time at http://localhost:8080/jbpm/
Select from available users, cookie monster, ernie, bert, and grove, which we created with create.db.derby target. Check out this web sale task created by Cookie Monster!