After a long time, let’s see new technology in action. jBPM 6 was released in the end of the last year, so it’s quite fresh and still lacks good examples to easily start with. I’ll focus on my recent example projects, which demonstrate jBPM 6 in use as a workflow engine embedded inside a web application.
So far the git repo contains just two projects. The first one is called rewards-basic. It was developed by Toshiya Kobayashi, who created the original application using jBPM 5 and Java Enterprise Editon (EE) 5. I’ve rewritten his application to work with new jBPM 6 and also later standard Java EE 6. There are many useful improvements in the new engine. For example now you can use runtime managers with advanced session strategies to better separate process contexts or to gain a better performance, especially in concurrent environment. Seamless integration with Java EE world is done by Context and Dependency Injection (CDI). Many people still don’t like CDI, but once you learn it, you may realize its advantages. You may even continue to use jBPM without CDI and initialize your environment using ordinary Java constructors or factories.
Both applications are build around one simple business process. After start it creates a task for user John and after he approves his task, the process creates a second task for user Mary. After she approves her task, the process finishes. Example applications provide web interfaces to these operations – in particular to start a business process, to list human tasks available and to approve them. More information including steps how to run the programs can be found on Github link above.
This article focuses on internal structure suitable to software developers. Let’s start and take a look on a code snippet from a process service Enterprise Java Bean (EJB):
private RuntimeManager singletonManager;
This demostrates CDI and how it can be used. You can just inject an object of defined class to your bean and you don’t have to care about how and where it is initialized. Don’t worry, we’ll get to that! The second annotation is interesting as well. You may choose also others for advanced session strategies like @PerProcessInstance and @PerRequest. Their names are self-explanatory, just to be sure – the first one keeps session (context) for a process instance and the second one is just stateless, no state is kept. What can be done with the runtime manager then?
RuntimeEngine runtime = singletonManager.getRuntimeEngine(EmptyContext.get());
KieSession ksession = runtime.getKieSession();
ProcessInstance processInstance = ksession.startProcess("com.sample.rewards-basic", params);
Keep in mind that runtime manager usually follows singleton design pattern in your application. For each request you should get an instance of runtime engine from it based on the context. Note that runtime engine is just an encapsulation of a kie session and a task service. The session can be used to start a process instance. The task service is automatically linked to this session and can be used for human task related queries and commands. The last command just starts a process instance, so the business process is finally running.
The last thing that can be noted are user transactions. You don’t have to use user transactions, but they are useful in many cases. For example you may want to save some information into a corporate database at the same time with the execution of the process engine. This way you ensure that all operations are either committed or rolled back together.
Similarly you can just simply inject a task service. Do you remember jBPM 5? The task service was decoupled from the process engine and had to be connected to the engine for each process run in order to support human tasks. jBPM 6 integrated the task service back to the engine.
List list = taskService.getTasksAssignedAsPotentialOwner(actorId, "en-UK");
As you can see in TaskBean, you can easily run an arbitrary task service method.
CDI producer classes
In order to get CDI working you have to provide producers for injected class instance where necessary. One of the CDI advantages is the loose coupling. For example you may use a service in your beans, which functionality is dependent on running application server. This is ok, but how to easily unit test your application without setting up awkward application server? For example you can easily write a mock service for unit testing and don’t even have to modify a Java code. All you would have to do is just to change an alternative class in CDI configuration file beans.xml.
On the other hand debugging a CDI application may be difficult as the errors of unsatisfied dependencies are thrown mostly during run time, which slows the development process. If you know how to cope with this, please leave me a comment, thanks!
Application scoped producers
These producers can be found in ApplicationScopedProducer class. @ApplicationScoped annotation tells the application server (or more precisely the CDI container), that instances produced here should be instantiated for the whole life cycle of this web application deployment. It’s logical – for example the persistence unit (database connection) won’t change during the runtime of the web application.
Very important is also the RuntimeEnvironment producer, which provides whole setup for runtime manager, for example including our “com.sample.rewards-basic” process definition to be used. Runtime manager is injected from a jBPM library, but this same library also internally injects RuntimeEnvironment instance to get our environment that it doesn’t know.
You may also notice RewardsUserGroupCallback class. It is a simple user group callback and is defined as an alternative. This demonstrates that by using alternatives you may use your own classes, if you are not satisfied with prepared implementations coming from jBPM libraries.
Web presentation layer is really simple. It uses Java Server Pages (JSP) technology and Java Servlets to handle presentation logic. Web user interface is just plain HTML, because the focus was put on demonstrating the internal service logic.
The second example application stays internally mostly the same, based on the same concepts. However Java Server Faces (JSF) technology including CDI is used for presentation layer.
I have described briefly two simple web applications demonstrating together jBPM 6 and Java EE 6. Please write a comment if you’ve liked them or if you have some feedback, I would be happy to hear your opinion. Thanks.