JBPM best practices

User Rating: 0 / 5

Star InactiveStar InactiveStar InactiveStar InactiveStar Inactive
 

There's no perfect rule to model your workflow, it depends on the needs of your process, on the actors involved, and so on. Anyway I wanted to share with you some rules of thumb on which developers usually agree. Give me your feedback if you agree or you want to propose alternatives.  

1) Keep your JBPM executionContext tidy

In the very first JBPM projects I have seen, I realized dwevelopers sometimes use the executionContext to feed lots of variables to the process. Adding variables to the execution Context is fundamental in order to control execution flow, anyway don't be tempted to put everything inside it !

For example: supposing you are designing a trouble ticketing system : you probably would need to store some additional information about the Actor, for example: name, surname, email. So you're mixing in the execution context both Model variables and Process variables !

Model this fields in an EJB and simply keep an ticketid in your executionContext. This is a sample EJB which used Seam to communicate with the biz process:

@Stateful
@Name("TicketingSystem")

public class TicketBean implements TicketBeanItf {

@PersistenceContext(type=PersistenceContextType.EXTENDED)
EntityManager em;

@In(create = true)
@Out
private Ticket ticket;

// We make this available to the business process
@Out(scope=ScopeType.BUSINESS_PROCESS, required=false)
long ticketId;

 @CreateProcess(definition="TroubleTicketing")
 public void createTicket() {
   em.persist(ticket);
   // Keep a reference to the ticketId in your biz process
   ticketId = ticket.getTicketId();
 }
 
}

Remember that adding domain variables in the execution Context besides being a bad design choice, it will badly ontribute to slow down your process.

2) Use Exception handler only to set variables or to notify errors

JBPM has a built-in exception handler which can be applied to single nodes or to the overall process

<exception-handler exception-class="java.lang.Exception">
   <action class="com.sample.handlers.BPMExceptionHandler"></action>      
</exception-handler>

You may be tempted to use exception handling in JBPM to decide execution flow: don't try it !

The mechanism of jBPM is not completely similar to the java exception handling. In java, a caught exception can have an influence on the control flow. In the case of jBPM, control flow cannot be changed by the jBPM exception handling mechanism. The exception is either caught or uncaught. Uncaught exceptions are thrown to the client (e.g. the client that called the token.signal()) or the exception is caught by a jBPM exception-handler. For caught exceptions, the graph execution continues as if no exception has occurred.

The best practice to use them is to perform some corrective action (set variables, send email, jms message etc.) and then either continue the graph execution (the behaviour you observe) or else rethrow an exception for the transaction to fail and the token to end up in the node it started from.

 
It is also a good design to catch business exceptions within your Actions and set some process variables, dependent on what exception is thrown.Then you can model a Decision in your process, which takes a special path of execution.

3) Want JBPM failover ? Wrap JBPM calls in a clustered SLSB !

jBPM is a state machine: process descriptions and runtime status are persisted to a database but in a cluster they are not automatically failed-over. If a cluster node fails while executing some external trigger (ui, timer, jms, whatever) execution will stop and have to be started again. Depending on the transaction context you're in this could be done automatically (redelivered jms, re-executed timer) or require ui interaction (error message for user if cluster node goes down requesting repeat).

Therefore, while the process description is persistent, workflow failover must be performed manually. jBPM can be used to build a fully failsafe, clusterable hotfailover worklfow solution, but it doesn't come out of the box.

So what's the easiest way to add these features to your workflow ? for most cases the best solution would be to encapsulate the jBPM API calls that you need in your application in a stateless session bean and cluster this last one.
Adding clustering capabilities to your EJB is not at all complicated, refer to this article:
http://www.mastertheboss.com/jboss-application-server/49-jboss-ejb3-in-a-cluster.html
 

4) Use superstates wherever possible

A Superstate is a group of nodes: its' a convenient way to group nodes into related sets, denoting for instance phases in a process. For example, one application could be to group all the nodes of a process in phases. Actions can be associated with superstate events. A consequence is that a token can be in multiple nested nodes at a given time. This can be convenient to check wether a process execution is e.g. in the start-up phase.

So it's a good design choice to split your process into superstates when every state represents a phase of the process, but there's one more reason why I advocate the use of superstates: JBPM is a state machine and as such doesn't deliver a built-in graphical environment. There's actually an Eclipse plugin which let you write graphically your process but it's not the best BPM front-end on the market: icons are too large, too ugly and you can't define custom icons for different type of nodes (at least as it comes out of the Box). If you have ever drawn a 100 nodes process with JBPM you probably did what I did: I designed by myself a new front-end layer from JBPM, because the picture of the process was huge and completely a mess.

If you are not willing to design a new front-end for JBPM then use extensively superstates wherever possible, it will keep your process (jpg) more readable and your boss won't faint when you show a 5 pages process picture!

5) Extend JBPM Api rather then messing with complex process modelling

Sometimes developers (me too!) don't look for the simpler solution: maybe modelling your process with jbpm built-in nodes leads to an unnecessarily  complex process.
Think Simple.... jBPM is very extensible (actionhandlers, custom node types ) and sometimes easier then  doing plain modeling with existing nodes which can make things unnecessarily  complex.

For example: supposing that you have the requirement to assign a task within a particular swimlane depending on the geographic location. (if a task takes place in New York it's assigned to user A, if it takes place in Chicago then it's assigned to user B)

Take the org.jbpm.taskmgmt.def.Task.java and add the following fields/methods:

private String taskLocation;
 
public String getTaskLocation() {
   return taskLocation;
}
public void setTaskLocation(String taskLocation){
   this.taskLocation = taskLocation;
}

Now update the hibernate config file for Task.java which is Task.hbm.xml 

<property name="taskLocation" column="TASKLOCATION_" ></property>

Finally modify JpdlXmlReader.java so that this new property is injected into the Task class when
the process is read from the DB.

String taskLocation = taskElement.attributeValue("taskLocation");

if (taskLocation==null) {
         taskLocation = taskElement.attributeValue("taskLocation");
}
    
if (taskLocation != null){
          task.setLocation(taskLocation);
}

Another example of customization can be applied to your queries: supposing you want to filter your Tasks using lots of criteria : think about a TaskList rendered with JSF and a Task Filter window where you can filter Task on priority, date, Actor, Task name and so on. 

One way to do it, without making things too complex is adding filters to the TaskInstance: simply open TaskInstance hibernate file and add some hibernate filters there:

    <filter name="filterPriority"  condition=":paramPriority = PRIORITY_"/>    
    <filter name="filterDesc"      condition=":paramDesc = DESCRIPTION_"/>        
    <filter name="filterId"        condition="str(ID_) LIKE (:paramId) "/>    
    <filter name="filterCreate"    condition="CREATE_ BETWEEN :paramFrom and :paramTo"/> 

Notice that parameters passed to the filters begin with ":" while other fields (like _ID) belong to the TaskInstance. Then when you're populating your Datatable, enable the filters selected: 

String sql  = "from org.jbpm.taskmgmt.exe.TaskInstance";
session.enableFilter("filterPriority").setParameter("paramPriority","2");

Query queryParent = session.createQuery(sql);   
List list = queryParent.list();

Iterator iter = list.iterator();
 while (iter.hasNext()) {   
  TaskInstance taskInstance = (TaskInstance)iter.next();
 }

  

6) Hire a Drool developer if you have complex rules

A workflow engine (or Graph Oriented Programming in general) is about specifying a graph that represents an execution. The nodes can represent wait states.
A rules engine is about specifying a set of rules and then applying an inference algorithm for a given set of facts.  How could Drools fit with JBPM ? one best practice could be using JBPM to "externalize" all or part of logic contained in the Handlers in a rule engine. In other words JBPM engine could be driven by Drools rules engine.

As with other points, also this approach is not applicable in all situations: ask yourself a few things

How complex are my Java Action Handlers ? if you just need to read some data from a database, but not much more, it is probably best not to use a rule engine. However, where there is even a moderate amount of processing implemented in Java, it is worthwhile to consider the use of Drools when implementing your JBPM Handlers. This is because most applications develop complexity over time, and Drools will let you cope easily with this, especially if the lifetime of your application is medium or long. Furthermore Drools helps you cope with future changes by specifying the business rule in one or more easy-to-configure XML files.

One more score for drools is that Drools "guides" developers to write code correctly do "the right thing." and at the same time rules are much easier to read then code so also your staff will be more comfortable with it.

Furthermore, used correctly, Drools can remember not only the information, but also the results of previous tests using this information, giving the entire application a speed boost. 
 

7) To BPEL or not to BPEL

BPEL is an XML language which describes long running web service interactions. It is used mainly to orchestrate message exchanges centrally and as such is a key ingredient in SOA.
What has BPEL in common with JPDL ?
 

  • Both languages have a procedural notation
  • Interaction with external agents
  • Scheduling of activities
  • Exception handling
  • Error recovery


Even if they have some common points, the concrete expression of these elements leads to distinct audiences: for example talking about procedural notation:

JPDL reflects organizational procedures with simple meaning
BPEL describes structured constructs with complex semantics

Also the interaction with external agents is exploited differentely:
 
BPEL is document oriented and as such is mainly used in company boundaries
JPDL is object oriented and so it's a backbone in company componets

BPEL delegates interaction with people to partner services
jPDL offers integrated task management


So when should I use BPEL ? 

When you need that your processes are portable even outside the Java platform. BPEL processes can be executed on orchestration servers based on Java platform or on any other software platform (for example .NET). This is particularly important in business-to-business interactions where different partners use different platforms

When there's no direct human involvement, rather you need  specific support for long running business processes. 

When you need to achieve transaction compensation in a relatively easy way. Compensation, or undoing steps in the business process that have already completed successfully, is one of the most important concepts in business processes. The goal of compensation is to reverse the effects of previous activities that have been carried out as part of a business process that is being abandoned.

Use JPDL when these criteria are not met.

Related articles available on mastertheboss.com

JBPM tutorial

JBoss jBPM 3 is a flexible, extensible framework for process lang

How do I fire an action every time a JBPM Node enters?

JBoss recipe of the day

JBoss Jbpm superstates

What is a superstate ? a Superstate is a group of nodes. Supersta

Jbpm Mail delivery

Almost every workflow needs a notification of the process activit

How do you embed Java code in your JPDL ?

  You can use a BeanShell expression to add a Java script in you

How to delete/persist your JBPM process after restart ?

JBoss recipe of the day

Follow us on Twitter