Enterprise Integration Zone is brought to you in partnership with:

Nicolas Frankel is an IT consultant with 10 years experience in Java / JEE environments. He likes his job so much he writes technical articles on his blog and reviews technical books in his spare time. He also tries to find other geeks like him in universities, as a part-time lecturer. Nicolas is a DZone MVB and is not an employee of DZone and has posted 224 posts at DZone. You can read more from them at their website. View Full User Profile

Lessons learned from integrating jBPM 4 with Spring

09.10.2012
| 8135 views |
  • submit to reddit

When I was tasked with integrating a process engine into one of my projects, I quickly decided in favor of Activiti. Activiti is the next version of jBPM 4, is compatible with BPMN 2.0, is well documented and has an out-of-the-box module to integrate with Spring. Unfortunately, in a cruel stroke of fate, I was overruled by my hierarchy (because of some petty reason I dare not write here) and I had to use jBPM. This articles tries to list all lessons I learned in this rather epic journey.

Lesson 1: jBPM documentation is not enough

Although jBPM 4 has plenty of available documentation, when you’re faced with the task of starting from scratch, it’s not enough, especially when compared to Activiti’s own documentation. For example, there’s no hint on how to bootstrap jBPM in a Spring context.

Lession 2: it’s not because there’s no documentation that it’s not there

jBPM 4 wraps all needed components to bootstrap jBPM through Spring, even though it stays strangely silent on how to do so. Google is no helper here since everybody seems to have infered its own solution.For the curious, here’s how I finally ended doing it:
For example, here’s how I found some declared the jBPM configuration bean:

<bean id="jbpmConfiguration" class="org.jbpm.pvm.internal.processengine.SpringHelper">
    <property name="jbpmCfg">
        <value>jbpm.cfg.xml</value>
    </property>
</bean>

At first, I was afraid to use a class in a package which contained the dreaded “internal” word but it seems the only way to do so…

Lesson 3: Google is not really your friend here

… Was it? In fact, I also found this configuration snippet:

<bean id="jbpmConfiguration" class="org.jbpm.pvm.internal.cfg.SpringConfiguration">
    <constructor-arg value="jbpm.cfg.xml" />
</bean>

And I think if you search long enough, you’ll find many other ways to achieve engine configuration. That’s the problem when documentation is lacking: we developers are smart people, so we’ll find a way to make it work, no matter what.

Lesson 4: don’t forget to configure the logging framework

This one is not jBPM specific, but it’s important nonetheless. I lost much (really much) time because I foolishly ignored the message warning me about Log4J not finding its configuration file. After having created the damned thing, I finally could read an important piece of information I receveid when programmatically deploying a new jPDL file:

WARNING: no objects were deployed! Check if you have configured a correct deployer in your jbpm.cfg.xml file for the type of deployment you want to do.

Lesson 5: the truth is in the code

This lesson is a direct consequences of the previous one: since I already had double-checked my file had the jbpm.xml extension and that the jBPM deployer was correctly set in my configuration, I had to understand what the code really did. In the end, this meant I had to get the sources and debug in my IDE to watch what happened under the cover. The culprit was the following line:

repositoryService.createDeployment().addResourceFromInputStream("test", new FileInputStream(file));

Since I used a stream on the file, and not the stream itself, I had to supply a fictitious resource name (“test”). The latter was checked for a jpdl.xml file extension and of course, failed miserably. This was however not readily apparent by reading the error message… The fix was the following:

repositoryService.createDeployment().addResourceFromFile(file);

Of course, the referenced file had the correct jbpm.xml extension and it worked like a charm.

Lesson 6: don’t reinvent the wheel

Tightly coupled with lesson 2 and 3, I found many snippets fully describing the jbpm.cfg.xml configuration file. Albeit working (well, I hope so since I didn’t test it), it’s overkill, error-prone and a perhaps sign of too much Google use (vs brain use). For example, the jbpm4-spring-demo project published on Google Code provides a full-fledged configuration file. With a lenghty trial-and-error process, I managed to achieve success with a much shorter configuration file that reused existing configuration snippets:

<?xml version="1.0" encoding="UTF-8"?>
<jbpm-configuration xmlns="http://jbpm.org/xsd/cfg">
 
    <import resource="jbpm.default.cfg.xml" /><!-- Default configuration -->
    <import resource="jbpm.tx.spring.cfg.xml" /><!-- Use Spring transaction management -->
    <import resource="jbpm.jpdl.cfg.xml" /><!-- Can deploy jPDL files -->
 
</jbpm-configuration>

Lesson 7: jPBM can access the Spring context

jBPM offers the java activity to call some arbitrary Java code: it can be EJB but we can also wire the Spring context to jBPM so as to make the former accessible by the latter. It’s easily done by modifying the former configuration:

<jbpm-configuration xmlns="http://jbpm.org/xsd/cfg">
 
    <import resource="jbpm.default.cfg.xml" />
    <import resource="jbpm.tx.spring.cfg.xml" />
    <import resource="jbpm.jpdl.cfg.xml" />
 
    <process-engine-context>
        <script-manager default-expression-language="juel"
            default-script-language="juel"
            read-contexts="execution, environment, process-engine, spring"
            write-context="">
            <script-language name="juel" factory="org.jbpm.pvm.internal.script.JuelScriptEngineFactory" />
        </script-manager>
    </process-engine-context>
</jbpm-configuration>

Note that I haven’t found an already existing snippet for this one, feedback welcome.

Lesson 8: use the JTA transaction manager if needed

You’ll probably end having a business database along your jBPM database. In most companies, you’ll be gently asked to put them in different schemas by the DBAs. In this case, don’t forget to use a JTA transaction manager along some XA datasources to use 2-phase commit. In your tests, you’d better use the same schema and a simple transaction manager based on the data source will be enough.

For those of you that need yet another way to configure their jBPM/Spring integration, here are the sources I used in Maven/Eclipse format. I hope my approach is a lot more pragmatic. In all cases, remember I’m a newbie in this product.

Published at DZone with permission of Nicolas Frankel, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Tags:

Comments

Peter Butkovic replied on Mon, 2012/09/10 - 2:24am

I like this type of posts, as you can save quite some time someone else would otherwise loose, so thanks for your time.

However to your lesson no 2 and 3, I believe the way to help the project itself would be to fill a bug report and ask for a clear description in the documentation or even an example demonstrating the intented way of configuration in a spring way.

Nicolas Frankel replied on Mon, 2012/09/10 - 2:55am

Hi Peter,

You're right but jBPM 4 is no longer the main version, it has been superceded by version 5, which is now based on Drools. jBPM4 lead developer has gone to activiti, so that's a moot point.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.