How to Run jbpm on SJSAS/Glassfish with Derby



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

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.

Configure SJSAS/Glassfish

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

$SJSAS_HOME/domains/domain1/config/domain.xml:

<jvm-options>-Djava.security.policy=${com.sun.aas.instanceRoot}/config/server.policy</jvm-options>
<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:
<jvm-options>-Dcom.sun.enterprise.taglibs=appserv-jstl.jar,myfaces-impl.jar</jvm-options>
<jvm-options>-Dcom.sun.enterprise.taglisteners=myfaces-impl.jar</jvm-options>


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



Configure jbpm


Back up and edit $JBPM_HOME/src/config.files/hibernate.cfg.xml. 

You only need to modify jdbc connection section:
    <!-- jdbc connection properties -->
  <property name="hibernate.dialect">org.hibernate.dialect.DerbyDialect</property>
  <property name="hibernate.connection.driver_class">org.apache.derby.jdbc.ClientDriver</property>
  <property name="hibernate.connection.url">jdbc:derby://localhost:1527/sun-appserv-samples;create=true</property>
  <property name="hibernate.connection.username">APP</property>
  <property name="hibernate.connection.password">APP</property>


Create a new directory for derby, used when creating database schemas and populating tables:

      mkdir $JBPM_HOME/src/resources/derby/
   cp $JBPM_HOME/src/resources/hsqldb/\*  $JBPM_HOME/src/resources/derby/


Edit $JBPM_HOME/src/resources/derby/create.db.hibernate.properties, as follows:

      hibernate.dialect=org.hibernate.dialect.DerbyDialect
   hibernate.connection.driver_class=org.apache.derby.jdbc.ClientDriver
   hibernate.connection.url=jdbc:derby://localhost:1527/sun-appserv-samples;create=true
   hibernate.connection.username=APP
   hibernate.connection.password=APP
   hibernate.show_sql=true


Add derby jars to jbpm/lib/derby so that they can be included in build classpath:

       mkdir $JBPM_HOME/lib/derby
   cp $SJSAS_HOME/derby/lib/\*jar $JBPM_HOME/lib/derby/
  (You don't need Derby localization jars)

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 -->
      ...
  </target>


  <!-- ================= -->
  <!-- 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">
    <jbpmschema actions="create"
                cfg="${basedir}/src/config.files/hibernate.cfg.xml"
                properties="${basedir}/src/resources/derby/create.db.hibernate.properties"/>
    <loadidentities file="${basedir}/src/resources/derby/identity.db.xml"
                cfg="${basedir}/src/config.files/hibernate.cfg.xml"
                properties="${basedir}/src/resources/derby/create.db.hibernate.properties"/>
    <ant antfile="build.xml" target="build.processes" inheritall="false" />
    <deployprocess cfg="${basedir}/src/config.files/hibernate.cfg.xml"
                   properties="${basedir}/src/resources/derby/create.db.hibernate.properties">
      <fileset dir="build" includes="\*.process" />
    </deployprocess>
  </target>

  <property file="${basedir}/src/resources/derby/create.db.hibernate.properties"/>
  <target name="execute.derby.sql" description="execute a derby sql script with -Dderby.script=path-to-script.">
    <sql driver="${hibernate.connection.driver_class}"
             url="${hibernate.connection.url}"
             userid="${hibernate.connection.username}"
             password="${hibernate.connection.password}"
             delimiter=";"
             autocommit="true"
             onerror="continue" >
             <classpath refid="classpath.ant"/>
             <transaction src="${derby.script}"/>
    </sql>
  </target>


Build jbpm project

cd $JBPM_HOME
ant build
ant -f build.deploy.xml build.webapp

Relevant files have been copied to $JBPM_HOME/build/jbpm.war.dir, and jarred up into a war file $JBPM_HOME/build/jbpm.war. 

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.

$SJSAS_HOME/bin/asadmin start-database;
OR
cd $SJSAS_HOME/derby/frameworks/NetworkServer/bin; ksh startNetworkServer.ksh

To shutdown Derby with asadmin stop-database, or stopNetworkServer.ksh.

Generate schemas and populate tables with create.db.derby target

cd $JBPM_HOME
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 /starters-kit/jbpm-db/build/derby/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;
NAME_                                                                     
---------------------------------------
cookie monster                                                            
ernie                                                                     
bert                                                                      
grover                                                                    

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 $SJSAS_HOME/domains/domain1/autodeploy

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!

technorati tags: , , , ,

Comments:

Congrats :-) The jBPM runtime engine is designed to be highly embeddable in any java environment. But for the webapplication, we didn't yet focus too much on portability. regards, tom.

Posted by Tom Baeyens on March 22, 2006 at 06:41 AM EST #

Is MyFaces a required dependency or will this work with the JSF included with GlassFish?

Posted by Ryan Lubke on March 31, 2006 at 04:57 AM EST #

I've updated the instructions for running jbpm on Glassfish (aka SJSAS 9.0). I successfully tested it with Glassfish build 43 on 3/31/2006.

Posted by chengfang on March 31, 2006 at 11:07 AM EST #

hi, i was trying to fallow this steps with glassfish and i got stuck when im trying to do this.. cd $JBPM_HOME ant build ant -f build.deploy.xml build.webapp i get this error compile.jbpm.test: [javac] Compiling 54 source files to C:\\jBPM\\jbpm\\build\\classes.jbpm.test [javac] C:\\jBPM\\jbpm\\src\\java.jbpm.test\\org\\jbpm\\persistence\\db\\MockConnection.java:13: org.jbpm.persistence.db.MockConnection is not abstract and does not override abstract method createStruct(java.lang.String,java.lang.Object[]) in java.sql.Connection [javac] public class MockConnection implements Connection { [javac] \^ [javac] Note: C:\\jBPM\\jbpm\\src\\java.jbpm.test\\org\\jbpm\\persistence\\db\\MockSession.java uses or overrides a deprecated API. [javac] Note: Recompile with -Xlint:deprecation for details. [javac] 1 error BUILD FAILED C:\\jBPM\\jbpm\\build.deploy.xml:115: The following error occurred while executing this line: C:\\jBPM\\jbpm\\build.xml:58: Compile failed; see the compiler error output for details. i deleted the target from the build.xml file but i still got the same error, could you help me with this? thanks,

Posted by Gabriel Gutierrez on April 25, 2007 at 03:49 PM EDT #

It seems you are using JDK 6. createStruct method is new in JDK 6. If you use JDK 5, it should work fine.

See JDK 6 java.sql.Connection javadoc: JDK 6 Connection class

JDK 5 java.sql.Connection javadoc: JDK 5 Connection class

Posted by chengfang on April 26, 2007 at 04:14 AM EDT #

yes i do, thanks chengfang, i gonna try it, but do you have any documentation or where i can find some, about using glassfish and bpm using jdk 6 ?

Posted by Gabriel Gutierrez on April 26, 2007 at 04:26 AM EDT #

Hi, do you have any documentation or know where i can find any about running jBPM with Glassfish using jdk 6.0 ? Thanks,

Posted by Gabriel Gutierrez on May 08, 2007 at 04:34 AM EDT #

I haven't seen any docs on jbpm + glassfish + JDK 6. But using JDK 6 shouldn't make much of a difference than using JDK 5, I guess.

However, glassfish can be fully built and run with JDK 6. You can look in glassfish.dev.java.net, or glassfishwiki.org for some docs.

Posted by chengfang on May 09, 2007 at 01:47 AM EDT #

Hi chengfang,
i'm trying to use this manual to integrate JBPM in glassfish v2, but i can't. You know if i can do it???
my BIG problem is i want to integrate alfresco in glassfish, but i can't!
then, i try to install JBPM but when you say
"JSF API classes are in javaee.jar." and i try to modify this jar, then Glassfish broke down..

please, can you help me? i'm so lost...
Thanks, and regards
Rocio

Posted by rocio on March 05, 2008 at 04:48 AM EST #

Hi Rocio,

You can post your questions at glassfish forum (glassfish.org), for jsf-specific questions, at jsf forum (https://javaserverfaces.dev.java.net/)

-cheng

Posted by chengfang on March 09, 2008 at 10:32 AM EDT #

Post a Comment:
  • HTML Syntax: NOT allowed
About

Cheng Fang

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today