In my previous post I described an example implementation of a web application, which demonstrates usage of jBPM business process suite as an embedded workflow library. The focus was on CDI services provided by jBPM libraries and their integration with producers and consumers in the web application itself.
The latest version jBPM 6.2 contains services, which are better designed, provide completely new API and significantly simpler usage. They also provide basic kie-services implementation, which is framework agnostic (now they do not use CDI internally) and other specific services for a particular bean framework – EJB 3.1 or CDI 1.0.
This article is going to describe the current state of jbpm-6-examples demos and the upgrade from version 6.0 to 6.2. The article will be separated to two parts, because both examples are slightly different. The new jbpm-6-examples can be found on current master branch on the github.
rewards-basic web example migration to jBPM 6.2 EJB services
This example application combines jBPM 6.2 EJB services together with servlets and Java Server Pages (JSP). Here is the list of new services used in the example. All of them extend the core service and are already annotated with EJB @Local annotation.
- DeploymentServiceEJBLocal – used to deploy/undeploy kjar artifacts to/from runtime
- ProcessServiceEJBLocal – used to start/signal/abort process instance and get their process instance data
- RuntimeDataServiceEJBLocal – provides information about runtime data, process instances, user tasks, process variables, etc.
- UserTaskServiceEJBLocal – provides operation to work on a user task
So what has changed? Many things! First of all rewards process with two human tasks is not loaded from the application classpath, but is part of a kjar artifact with maven GAV “org.jbpm.examples:rewards:1.0”. That means that the maven client inside jBPM 6.2 has to be able to resolve this artifact from maven repositories. For this purpose you can just clone and build the rewards project from jbpm-6-examples-assets:
git clone https://github.com/jsvitak/jbpm-6-examples-assets.git cd jbpm-6-examples-assets/rewards mvn clean install
Also you do not have to care of session strategy and runtime manager now. Session strategy can be defined in a deployment descriptor file inside the kjar, or it can be decided at the deployment time.
EJB annotation @Startup marks this bean for eager initialization, so before the application is ready, we register here our custom UserGroupCallback class and also we use injected deploymentService to deploy a kjar artifact from maven, which contains a business process definition that we want to use.
This is a simple servlet that handles requests coming to /process context. It gets a recipient variable from a POST request and uses injected processService to start a process instance.
TaskServlet is bound to handle /task context. It overrides doGet() method to handle GET requests. Based on the command it does two different operations.
- The first one uses runtimeDataService to retrieve all tasks for a particular user. The rewards process has two human tasks, the first one is for user jiri and the second one for user mary.
- The second operation is to approve a user task. Operation approve does not exist in the jBPM context, or in userTaskService API in particular, so it is implemented as a single composite operation, consisting of a StartTaskCommand and a CompleteTaskCommand. So the human task is started and immediately completed.
UserGroupCallback is necessary not only for mapping between task service users and their membership in groups, but also to just register users in runtime TaskService.
That’s all! Only four classes are now necessary for rewards-basic example, which uses provided jBPM 6.2 EJB services.
rewards-cdi-jsf web example with jBPM 6.2 CDI services
This example combines jBPM 6.2 services together with Context Dependency Injection (CDI) and Java Server Faces (JSF) frameworks. The services share the same API, so the description of the services and their purpose is the same as in the previous example.
CDI is a powerful and very flexible framework how to build Java EE 6 applications, however in the contrary to EJB framework, it does not provide transactions and may have other limitations. In our example, the CDI requires a bit more code to get it properly working using jBPM 6.2 services.
The purpose is the same as in the previous example, it uses CDI mechanisms to run the initialization code on the application startup.
ProcessBean and TaskBean classes
Again, the purpose is the same as in previous example. Both classes are annotated with a CDI stereotype @Model, which means they are both instantiated for one request (@RequestScoped annotation) and their public methods can be used in the expression language (EL) of the JSF frontend (@Named).
This class is necessary, because it contains several important producers.
- The first one produces EntityManagerFactory, which is consumed inside jBPM library and used to setup persistence.
- The second one produces a deploymentService. The producer class already consumes a qualified injection (using @Kjar qualifier), but it is important also to produce it for StartupBean to be consumed as a default injection.
- The last instance to produce is a TaskLifeCycleEventListener, which is necessary, because when a human task is completed, it is used to trigger again the process engine and so advance in the process flow.
Since the example does not implement authentication, this is just a placeholder class. However it is necessary for it to be there.
This class is not that important, it serves more as a CDI demonstration, that you can initialize Logger and FacesContext instances in a single place.
Ok, that’s everything for now! In this article you have seen new jBPM 6.2 services in action. These services can reduce much of the code, which was necessary before, like working with RuntimeEnvironment, RuntimeManager, RuntimeEngine and other stuff. Clone the jbpm-6-examples, read the README.md instructions and try the examples. I am looking forward to your comments and feedback!