Chapter 5.  Java EE Application Server Facilities

Read this chapter to learn about the facilities offered by the jBPM to that can be used to leverage the Java EE infrastructure.

5.1.  Enterprise Beans

The CommandServiceBean is a stateless session bean that runs Business Process Manager commands by calling its execute method within a separate jBPM context. The available environment entries and customizable resources are summarized in the following table:
Table 5.1. Command Service Bean Environment
Name Type Description
JbpmCfgResource Environment Entry This the classpath resource from which the jBPM configuration is read. Optional, defaults to jbpm.cfg.xml.
ejb/TimerEntityBean EJB Reference This is a link to the local entity bean that implements the scheduler service. Required for processes that contain timers.
jdbc/JbpmDataSource Resource Manager Reference This is the logical name of the data source that provides JDBC connections to the jBPM persistence service. Must match the hibernate.connection.datasource property in the Hibernate configuration file.
jms/JbpmConnectionFactory Resource Manager Reference This is the logical name of the factory that provides JMS connections to the jBPM message service. Required for processes that contain asynchronous continuations.
jms/JobQueue Message Destination Reference The jBPM message service sends job messages to this queue. To ensure this is the same queue from which the job listener bean receives messages, the message-destination-link points to a common logical destination, JobQueue.
jms/CommandQueue Message Destination Reference The command listener bean receives messages from this queue. To ensure this is the same queue to which command messages can be sent, the message-destination-link element points to a common logical destination, CommandQueue.
The CommandListenerBean is a message-driven bean that listens to the CommandQueue for command messages. It delegates command execution to the CommandServiceBean.
The body of the message must be a Java object that can implement the org.jbpm.Command interface. (The message properties, if any, are ignored.) If the message is not of the expected format, it is forwarded to the DeadLetterQueue and will not be processed any further. The message will also be rejected if the destination reference is absent.
If a received message specifies a replyTo destination, the command execution result will be wrapped in an object message and sent there.
The command connection factory environment reference points to the resource manager being used to supply Java Message Service connections.
Conversely, JobListenerBean is a message-driven bean that listens to the JbpmJobQueue for job messages, in order to support asynchronous continuations.

Note

Be aware that the message must have a property called jobId of type long. This property must contain references to a pending Job in the database. The message body, if it exists, is ignored.
This bean extends the CommandListenerBean. It inherits the latter's environmental entries and those resource references that can be customized.
Table 5.2. Command/Job listener bean environment
Name Type Description
ejb/LocalCommandServiceBean EJB Reference This is a link to the local session bean that executes commands on a separate jBPM context.
jms/JbpmConnectionFactory Resource Manager Reference This is the logical name of the factory that provides Java Message Service connections for producing result messages. Required for command messages that indicate a reply destination.
jms/DeadLetterQueue Message Destination Reference Messages which do not contain a command are sent to the queue referenced here. It is optional. If it is absent, such messages are rejected, which may cause the container to redeliver.
-   
Message Destination Reference Messages which do not contain a command are sent to the queue referenced here. If it is absent, such messages are rejected, which may cause the container to redeliver.  
The TimerEntityBean is used by the Enterprise Java Bean timer service for scheduling. When the bean expires, timer execution is delegated to the command service bean.
The TimerEntityBean requires access to the Business Process Manager's data source. The Enterprise Java Bean deployment descriptor does not define how an entity bean is to map to a database. (This is left to the container provider.) In the JBoss Application Server, the jbosscmp-jdbc.xml descriptor defines the data source's JNDI name and relational mapping data (such as the table and column names).

Note

The JBoss CMP (container-managed persistence) descriptor uses a global JNDI name (java:JbpmDS), as opposed to a resource manager reference (java:comp/env/jdbc/JbpmDataSource).

Note

Earlier versions of the Business Process Manager used a stateless session bean called TimerServiceBean to interact with the Enterprise Java Bean timer service. The session approach had to be abandoned because it caused an unavoidable bottleneck for the cancelation methods. Because session beans have no identity, the timer service was forced to iterate through all the timers to find the ones it had to cancel.
The bean is still available for backwards compatibility purposes. It works in the same environment as the TimerEntityBean, so migration is easy.
Table 5.3. Timer Entity/Service Bean Environment
Name Type Description
ejb/LocalCommandServiceBean EJB Reference This is a link to the local session bean that executes timers on a separate jBPM context.

5.2. jBPM Enterprise Configuration

The following configuration items are included in jbpm.cfg.xml:
<jbpm-context>
  <service name="persistence"
    factory="org.jbpm.persistence.jta.JtaDbPersistenceServiceFactory" />
  <service name="message"
    factory="org.jbpm.msg.jms.JmsMessageServiceFactory" />
  <service name="scheduler"
    factory="org.jbpm.scheduler.ejbtimer.EntitySchedulerServiceFactory" />
</jbpm-context>
The JtaDbPersistenceServiceFactory allows the Business Process Manager to participate in JTA transactions. If an existing transaction is underway, the JTA persistence service "clings" to it; otherwise it starts a new transaction. The Business Process Manager's enterprise beans are configured to delegate transaction management to the container. However, a new one will be started automatically if one creates a JbpmContext in an environment in which no transaction is active (such as a web application.) The JTA persistence service factory contains the configurable fields described below.
isCurrentSessionEnabled
When this is set to true, the Business Process Manager will use the "current" Hibernate session associated with the ongoing JTA transaction. This is the default setting. (See http://www.hibernate.org/hib_docs/v3/reference/en/html/architecture.html#architecture-current-session for more information.)
Use the same session as by jBPM in other parts of the application by taking advantage of the contextual session mechanism. Do so through a call to SessionFactory.getCurrentSession(). Alternatively, supply a Hibernate session to jBPM by setting isCurrentSessionEnabled to false and injecting the session via the JbpmContext.setSession(session) method. This also ensures that jBPM uses the same Hibernate session as other parts of the application.

Note

The Hibernate session can be injected into a stateless session bean (via a persistence context, for example).
isTransactionEnabled
When this is set to true, jBPM will begin a transaction through Hibernate's transaction API, using the JbpmConfiguration.createJbpmContext() method to commit it. (The Hibernate session is closed when JbpmContext.close() is called.)

Warning

This is not the desired behavior when the Business Process Manager is deployed as an EAR and hence isTransactionEnabled is set to false by default. (See http://www.hibernate.org/hib_docs/v3/reference/en/html/transactions.html#transactions-demarcation for more details.)
JmsMessageServiceFactory delivers asynchronous continuation messages to the JobListenerBean by leveraging the reliable communication infrastructure exposed through the Java Message Service interfaces. The JmsMessageServiceFactory exposes the following configurable fields:
connectionFactoryJndiName
This is the name of the JMS connection factory in the JNDI initial context. It defaults to java:comp/env/jms/JbpmConnectionFactory.
destinationJndiName
This is the name of the JMS destination to which job messages will be sent. It must match the destination from which JobListenerBean receives messages. It defaults to java:comp/env/jms/JobQueue.
isCommitEnabled
This specifies whether the Business Process Manager should commit the Java Message Service session upon JbpmContext.close(). Messages produced by the JMS message service are never meant to be received before the current transaction commits; hence the sessions created by the service are always transacted. The default value is false, which is appropriate when the connection factory in use is XA-capable, as the messages produced by the Java Message Service session will be controlled by the overall JTA transaction. This field should be set to true if the JMS connection factory is not XA-capable so that the Business Process Manager explicitly commits the JMS session's local transaction.
The EntitySchedulerServiceFactory is used to schedule business process timers. It does so by building upon on the transactional notification service for timed events provided by the Enterprise Java Bean container. The EJB scheduler service factory has the configurable field described below.
timerEntityHomeJndiName
This is the name of the TimerEntityBean's local home interface in the JNDI initial context. The default value is java:comp/env/ejb/TimerEntityBean.

5.3.  Hibernate Enterprise Configuration

The hibernate.cfg.xml file includes the following configuration items. Modify them to support other databases or application servers.
<!-- sql dialect -->
<property name="hibernate.dialect">
    org.hibernate.dialect.HSQLDialect
</property>

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

<!-- DataSource properties (begin) -->
<property name="hibernate.connection.datasource">
    java:comp/env/jdbc/JbpmDataSource
</property>
<!-- DataSource properties (end) -->

<!-- JTA transaction properties (begin) -->
<property name="hibernate.transaction.factory_class">
  org.hibernate.transaction.JTATransactionFactory
</property>
<property name="hibernate.transaction.manager_lookup_class">
  org.hibernate.transaction.JBossTransactionManagerLookup
</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) -->
Replace the hibernate.dialect setting with that which is appropriate for your database management system. (For more information, read http://www.hibernate.org/hib_docs/v3/reference/en/html/session-configuration.html#configuration-optional-dialects.)
The HashtableCacheProvider can be replaced with other supported cache providers. (Refer to http://www.hibernate.org/hib_docs/v3/reference/en/html/performance.html#performance-cache for more information.)
Out of the box, jBPM is configured to use the JTATransactionFactory. If an existing transaction is underway, the JTA transaction factory uses it; otherwise it creates a new transaction. The jBPM enterprise beans are configured to delegate transaction management to the container. However, if the jBPM APIs are being used in a context in which no transaction is active (such as a web application), one will be started automatically.
To prevent unintended transaction creations when using container-managed transactions, switch to the CMTTransactionFactory. This setting ensures that Hibernate will always look for an existing transaction and will report a problem if none is found.

5.4.  Client Components

Ensure that the appropriate environmental references are in place for deployment descriptors for client components written directly against those Business Process Manager APIs that can leverage the enterprise services. The descriptor below can be regarded as typical for a client session bean:
<session>

  <ejb-name>MyClientBean</ejb-name>
  <home>org.example.RemoteClientHome</home>
  <remote>org.example.RemoteClient</remote>
  <local-home>org.example.LocalClientHome</local-home>
  <local>org.example.LocalClient</local>
  <ejb-class>org.example.ClientBean</ejb-class>
  <session-type>Stateless</session-type>
  <transaction-type>Container</transaction-type>

  <ejb-local-ref>
    <ejb-ref-name>ejb/TimerEntityBean</ejb-ref-name>
    <ejb-ref-type>Entity</ejb-ref-type>
    <local-home>org.jbpm.ejb.LocalTimerEntityHome</local-home>
    <local>org.jbpm.ejb.LocalTimerEntity</local>
  </ejb-local-ref>

  <resource-ref>
    <res-ref-name>jdbc/JbpmDataSource</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
  </resource-ref>

  <resource-ref>
    <res-ref-name>jms/JbpmConnectionFactory</res-ref-name>
    <res-type>javax.jms.ConnnectionFactory</res-type>
    <res-auth>Container</res-auth>
  </resource-ref>

  <message-destination-ref>
    <message-destination-ref-name>
        jms/JobQueue
    </message-destination-ref-name>
    <message-destination-type>javax.jms.Queue</message-destination-type>
    <message-destination-usage>Produces</message-destination-usage>
  </message-destination-ref>

</session>
The environmental references above can be bound to resources in the target operational environment as follows. Note that the JNDI names match the values used by the Business Process Manager enterprise beans.
<session>

  <ejb-name>MyClientBean</ejb-name>
  <jndi-name>ejb/MyClientBean</jndi-name>
  <local-jndi-name>java:ejb/MyClientBean</local-jndi-name>

  <ejb-local-ref>
    <ejb-ref-name>ejb/TimerEntityBean</ejb-ref-name>
    <local-jndi-name>java:ejb/TimerEntityBean</local-jndi-name>
  </ejb-local-ref>

  <resource-ref>
    <res-ref-name>jdbc/JbpmDataSource</res-ref-name>
    <jndi-name>java:JbpmDS</jndi-name>
  </resource-ref>

  <resource-ref>
    <res-ref-name>jms/JbpmConnectionFactory</res-ref-name>
    <jndi-name>java:JmsXA</jndi-name>
  </resource-ref>

  <message-destination-ref>
    <message-destination-ref-name>
        jms/JobQueue
    </message-destination-ref-name>
    <jndi-name>queue/JbpmJobQueue</jndi-name>
  </message-destination-ref>

</session>
If the client component is a web application, as opposed to an enterprise bean, the deployment descriptor will look like this:
<web-app>

  <servlet>
    <servlet-name>MyClientServlet</servlet-name>
    <servlet-class>org.example.ClientServlet</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>MyClientServlet</servlet-name>
    <url-pattern>/client/servlet</url-pattern>
  </servlet-mapping>

  <ejb-local-ref>
    <ejb-ref-name>ejb/TimerEntityBean</ejb-ref-name>
    <ejb-ref-type>Entity</ejb-ref-type>
    <local-home>org.jbpm.ejb.LocalTimerEntityHome</local-home>
    <local>org.jbpm.ejb.LocalTimerEntity</local>
    <ejb-link>TimerEntityBean</ejb-link>
  </ejb-local-ref>

  <resource-ref>
    <res-ref-name>jdbc/JbpmDataSource</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
  </resource-ref>

  <resource-ref>
    <res-ref-name>jms/JbpmConnectionFactory</res-ref-name>
    <res-type>javax.jms.ConnectionFactory</res-type>
    <res-auth>Container</res-auth>
  </resource-ref>

  <message-destination-ref>
    <message-destination-ref-name>
        jms/JobQueue
    </message-destination-ref-name>
    <message-destination-type>javax.jms.Queue</message-destination-type>
    <message-destination-usage>Produces</message-destination-usage>
    <message-destination-link>JobQueue</message-destination-link>
  </message-destination-ref>

</web-app>
The above environmental references can also be bound to resources in the target operational environment, as per this code sample:
<jboss-web>

  <ejb-local-ref>
    <ejb-ref-name>ejb/TimerEntityBean</ejb-ref-name>
    <local-jndi-name>java:ejb/TimerEntityBean</local-jndi-name>
  </ejb-local-ref>

  <resource-ref>
    <res-ref-name>jdbc/JbpmDataSource</res-ref-name>
    <jndi-name>java:JbpmDS</jndi-name>
  </resource-ref>

  <resource-ref>
    <res-ref-name>jms/JbpmConnectionFactory</res-ref-name>
    <jndi-name>java:JmsXA</jndi-name>
  </resource-ref>

  <message-destination-ref>
    <message-destination-ref-name>
        jms/JobQueue
    </message-destination-ref-name>
    <jndi-name>queue/JbpmJobQueue</jndi-name>
  </message-destination-ref>

</jboss-web>

5.5.  Conclusion

Having studied this chapter, you should now have a thorough understanding of the facilities offered by the jBPM that can be used to leverage the Java EE infrastructure and should be comfortable with testing some of these in your corporate environment.
Red Hat logoGithubRedditYoutubeTwitter

Learn

Try, buy, & sell

Communities

About Red Hat Documentation

We help Red Hat users innovate and achieve their goals with our products and services with content they can trust.

Making open source more inclusive

Red Hat is committed to replacing problematic language in our code, documentation, and web properties. For more details, see the Red Hat Blog.

About Red Hat

We deliver hardened solutions that make it easier for enterprises to work across platforms and environments, from the core datacenter to the network edge.

© 2024 Red Hat, Inc.