Chapter 5. Deployment

jPDL is an embeddable BPM engine, which means that you can take the jPDL libraries and embed it into your own Java project, rather then installing a separate product and integrate with it. One of the key aspects that make this possible is minimizing the dependencies. This chapter discusses the jbpm libraries and their dependencies.

5.1. jBPM libraries

jbpm-jpdl.jar is the library with the core jpdl functionality.

jbpm-identity.jar is the (optional) library containing an identity component as described in Section 11.11, “The identity component”.

5.2. Java runtime environment

jBPM 3 requires J2SE 1.4.2+

5.3. Third party libraries

All the libraries on which jPDL might have a dependency, are located in the lib directory.

In a minimal deployment, you can create and run processes with jBPM by putting only the commons-logging and dom4j library in your classpath. Beware that persisting processes to a database is not supported. The dom4j library can be removed if you don't use the process xml parsing, but instead build your object graph programatically.

Table 5.1. 

commons-logging.jarlogging in jbpm and hibernateThe jBPM code logs to commons logging. The commons logging library can be configured to dispatch the logs to e.g. java 1.4 logging, log4j, ... See the apache commons user guide for more information on how to configure commons logging. if you're used to log4j, the easiest way is to put the log4j lib and a in the classpath. commons logging will automatically detect this and use that configuration.
dom4j.jarprocess definitions and hibernate persistencexml parsing

A typical deployment for jBPM will include persistent storage of process definitions and process executions. In that case, jBPM does not have any dependencies outside hibernate and its dependent libraries.

Of course, hibernate's required libraries depend on the environment and what features you use. For details refer to the hibernate documentation. The next table gives an indication for a plain standalone POJO development environment.

Table 5.2. 

hibernate3.jarhibernate persistencethe best O/R mapper
antlr-2.7.6rc1.jarused in query parsing by hibernate persistenceparser library
cglib.jarhibernate persistencereflection library used for hibernate proxies
commons-collections.jarhibernate persistence 
asm.jarhibernate persistenceasm byte code library

The beanshell library is optional. If you don't include it, you won't be able to use the beanshell integration in the jBPM process language and you'll get a log message saying that jbpm couldn't load the Script class and hence, the script element won't be available.

Table 5.3. 

bsh.jarbeanshell script interpreterOnly used in the script's and decision's. When you don't use these process elements, the beanshell lib can be removed, but then you have to comment out the Script.hbm.xml mapping line in the hibernate.cfg.xml

5.4. Web application

In the deploy directory of the downloads, you can find jbpm-console.war. That web console contains the jPDL libraries, configuration files and the required libraries to run this web application on JBoss.

This war file does NOT include the hibernate libraries. That is because JBoss already includes the hibernate libraries. To run this webapplication on other servers like Tomcat, all you have to do is get the hibernate libraries in the WEB-INF/lib directory in the war file. Simplest way to do that is to use the ant build script in this directory.

Also, this war file can give you a good indication of how you could deploy jbpm libraries and configuration files into your own web application.

In the web.xml of this web application, the JobExecutorServlet is configured. This will start the JobExecutor when the jbpm-console.war is deployed. The JobExecutor serves as the basis for executing timers and asynchronous messages on the standard java platform.

5.5. Enterprise archive

In the deploy directory of the downloads, you can find jbpm-enterprise.ear. That J2EE 1.4 compliant enterprise archive includes: jPDL libraries, jBPM configuration files, the jBPM web console, and a couple of enterprise beans. In this package, jBPM is configured for usage in an application server like e.g. JBoss. Asynchronous messaging service is here bound to JMS and the scheduler service is bound to the EJB Timer Service. So here in this .ear file, there is no JobExecutor started. Also the hibernate session that jBPM uses is configured to participate in the overall JTA transaction.

Within jbpm-enterprise.ear there are the following files:

  • jbpm-console.war - the jbpm console web application
  • jbpm-enterprise.jar - several jBPM EJB compnents
  • lib/jbpm-configs.jar - jBPM configuration files
  • lib/jbpm-identity.jar - jBPM identity component classes
  • lib/jbpm-jpdl.jar - jBPM jpdl classes
  • meta-inf/application.xml

jbpm-enterprise.jar contains the following EJB components:

  • CommandListenerBean - a Message Driven Bean that listens on the jbpmCommandQueue for jBPM command messages.
  • CommandServiceBean - a Stateless Session Bean that executes jBPM Commands.
  • JobListenerBean - a Message Driven Bean that listeners on the jbpmJobQueue for jBPM job messages to support asynchronous continuations.
  • TimerServiceBean - a TimerBean that implements the jBPM timer service.

These beans are J2EE 1.4 / EJB 2.1 compliant, to allow them to be deployed on a variety of application servers. Note however that jBPM only provide deployment descriptors for JBoss Application Servers. All beans are deployed without specifying transaction-attribure, therefore by default they have transaction-attribure "Required".

The CommandListenerBean delegates Command execution to the CommandServiceBean, which in turn delegates to a CommandServiceImpl class that executes the command class by calling it's execute method.

The source for these classes is in: src/enterprise. The javadocs in doc/javadoc-enterprise.

jbpm-enterprise.jar also contains JmsMessageServiceFactoryImpl, which is responsible for sending Jobs as JMS messages to support asynchronous continuations.

jbpm-configs.jar contains the following files:

  • jbpm.cfg.xml
  • jbpm.mail.templates.xml
  • hibernate.cfg.xml includes the following configuration items that may require modification to support other databases or application servers.
    <!-- hibernate dialect -->
        <property name="hibernate.dialect">org.hibernate.dialect.HSQLDialect</property>
        <!-- JDBC connection properties (begin) ===
        <property name="hibernate.connection.driver_class">org.hsqldb.jdbcDriver</property>
        <property name="hibernate.connection.url">jdbc:hsqldb:mem:jbpm</property>
        <property name="hibernate.connection.username">sa</property>
        <property name="hibernate.connection.password"></property>
        ==== JDBC connection properties (end) -->
        <property name="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property>
        <!-- JBoss transaction manager lookup (begin) -->
        <property name="hibernate.transaction.manager_lookup_class">org.hibernate.transaction.JBossTransactionManagerLookup</property>
        <!-- JBoss transaction manager lookup (end) -->
        <!-- DataSource properties (begin) -->
        <property name="hibernate.connection.datasource">java:/JbpmDS</property>
        <!-- DataSource properties (end) -->
        <!-- JTA transaction properties (begin) ===
        <property name="hibernate.transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</property>
        <property name="jta.UserTransaction">java:comp/UserTransaction</property>
        ==== JTA transaction properties (end) -->
        <!-- CMT transaction properties (begin) -->
        <property name="hibernate.transaction.factory_class">org.hibernate.transaction.CMTTransactionFactory</property>
        <property name="hibernate.transaction.manager_lookup_class">org.hibernate.transaction.JBossTransactionManagerLookup</property>
        <!-- CMT transaction properties (end) -->
        <!-- logging properties (begin) ===
        <property name="hibernate.show_sql">true</property>
        <property name="hibernate.format_sql">true</property>
        <property name="hibernate.use_sql_comments">true</property>
        ==== logging properties (end) -->

    You may replace the hibernate.dialect with one that corresponds to your database management system.

    You may replace the HashtableCacheProvider with other Hibernate supported cache providers, such as EhCache.

    The transaction.manager.lookup may be replace with values appropirate to other applications servers, e.g. WebSphereTransactionManagerLookup or WebLogicTransactionManagerLookup when deploying to those application servers.

    Similarly, if deploying on another application server you must change the name of the hibernate.connection.datasource to the jndi name of the datasource on that application server.

    Out-of-the-box jBPM is configured to use CMTTransactionFactory. CMTTransactionFactory always assumes that the container has started a JTA transaction. This will be true if you use the jBPM CommandListener or CommandService beans, or your own EJBs that use container managed transaction. If this is not always the case, then change this configuration to use the JTATransactionFactory. When JTATransactionFactory is configured, Hibenate will use the JTA transaction if it already exists, but will start a JTA transaction if it does not.

  • jbpm.cfg.xml included the following configuration items:

        <service name="persistence">
            <bean class="org.jbpm.persistence.db.DbPersistenceServiceFactory">
              <field name="isCurrentSessionEnabled"><true /></field>
              <field name="isTransactionEnabled"><false /></field>
        <service name="message">
            <bean class="org.jbpm.msg.jms.JmsMessageServiceFactoryImpl">
              <field name="connectionFactoryJndiName"><string value="java:/JmsXA"/></field>
              <field name="destinationJndiName"><string value="queue/JbpmJobQueue"/></field>
        <service name="scheduler" factory="org.jbpm.scheduler.ejbtimer.EjbSchedulerServiceFactory" />

    isCurrentSessionEnabled true means jBPM will request Hibernate to use the current session associated with the current transaction. If there is no current transaction, an exception will be thrown stating no session is active. In this case, you may want to set this isCurrentSessionEnabled to false, and inject the current session into the JbpmContext via the JbpmContext.setSession(session) method. This will also insure that jBPM uses the same Hibernate session as other parts of your application. Note, the Hibenrate session can be injected into a stateless session bean via a persistence context, for example.

    isTransactionEnabled true means jBPM will begin Hibernate transaction upon JbpmConfiguraiton().createJbpmContext and commit Hibernate transactions and close Hibernate sessions upon jbpmContext.close()..This is NOT the desired behaviour when jBPM is deployed as an ear, hence the value of isTransactionEnabled is set to false by default in this configuration.