Pular para o conteúdo principal

Creating custom Work Item Handler in BPM Suite/jBPM 6

Hi all! In this post I am going to share my experience creating a work item handler for BPM Suite 6.0.3 (which is very similar to jbpm as explained in a previous post).

The Hello World Work Item Handler


Let's create a really simple WorkItemHandler just to print "Hello World" in the console. Of course you can implement more feature and make it receive parameters, access database, web services, etc. But in this post we will keep it simple. Really simple.

First thing to do is to create a maven project for my WorkItemHandler. Here's the pom.xml of my Maven project:


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.jugvale.jbpm.workitemhandler</groupId>
<artifactId>hello-workitemhandler</artifactId>
<version>1.0</version>
<name>Hello WorlItemHandler</name>
<description>The simples WorkItemHandler for jbpm 6</description>
<dependencies>
<dependency>
<groupId>org.jbpm</groupId>
<artifactId>jbpm-flow</artifactId>
<version>6.0.1.Final</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
view raw pom.xml hosted with ❤ by GitHub

Notice that we are importing jbpm dependency so we can find the java interface that is used to create work item handlers.

Now we can start coding. Let's create a class name HelloWorkItemHandler in package org.jugvale.jbpm, here is the simple code:

import org.drools.core.process.instance.WorkItemHandler;
import org.kie.api.runtime.process.WorkItem;
import org.kie.api.runtime.process.WorkItemManager;
public class HelloWorkItemHandler implements WorkItemHandler {
public void abortWorkItem(WorkItem wi, WorkItemManager wim) {
System.out.println("Oh no, my item aborted..");
}
public void executeWorkItem(WorkItem wi, WorkItemManager wim) {
System.out.println("Hello World!");
wim.completeWorkItem(wi.getId(), null);
}
}

Now we can build our project and go to BPM Suite to configure it so we can use this workitem.


Registering the WorkItemHandler


UPDATE: Starting on jBPM 6.2, you can register custom work items using kie-deployment-descriptor.xml


UPDATE2: Starting on jBPM 6.5, a new feature makes even easier to add new service tasks. It is described in the documentation, however we will talk about this on this blog.

The first thing to do is to make our artifact visible to BPM Suite. We can either import it in the maven used by BPM Suite or we can upload the JAR using the web application. In any case, the common step is to build our project.

After building it, decide if you want to install it in your maven repository so you can use it in the BPM Suite project as a dependency or you can upload the JAR to BPM Suite and make it a dependency of the BPM Suite project. That's what we are going to do.
  • So, after starting BPM Suite, and logging into business central, we can go to Authoring -> Artifact Repository  and upload the JAR with our Work Item Handler:




Now we create a simple project in BPM Suite. You can do this by going to Authoring -> Project Authoring and then New Item -> Project. Notice that I am considering that you have already a repository created.

Now that you have your project created, let's add the artifact we uploaded as a dependency of it. To do this, select the project and go to Tools -> Project Editor and on the Project Settings drop down menu, select Dependencies. Now you can specify the uploaded artifact as a dependency of your project using the Add from repository button and choose our artifact from the list that will show up and then we are done with this part. Don't forget the save the changes.



Remember that WorkItemHandlers are registered in the file META-INF/kmodule.xml of your project. However, we can do this visually! Go to Project Editor  and from the Project Settings dropdown button, choose Knowledge base and sessions. Add a new knowledge base, make it default and add a new ksession, make it default, edit it and add the work item handler. Here are some useful screenshots:

 Adding the kbase and the ksession:



Editing the ksession to add the work item handler:




Save it and now the project is already configured with a kbase and a ksession with our work item handler! See how our kmodule.xml looks like:


<kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<kbase name="mykbase" default="true" eventProcessingMode="stream" equalsBehavior="identity">
<ksession name="mykasession" type="stateful" default="true" clockType="realtime">
<workItemHandlers>
<workItemHandler type="org.jugvale.jbpm.workitemhandler.HelloWorkItemHandler" name="HelloWorkItemHandler"/>
</workItemHandlers>
</ksession>
</kbase>
</kmodule>
view raw kmodule.xml hosted with ❤ by GitHub

We are almost done.  Let's create a process to test the WorkItemHandler we created, use the menu New Item -> Business Process and do nothing for now, just close the process editor.Now let's simple edit the file WorkDefinitions.wid of our project to include metadata about the WorkItemHandler. Here we can set the icon and the name that will appears in the process editor. We simple only set a display name:

  [
   "name" : "HelloWorkItemHandler",
    "displayName" : "Hello World!",
    "icon" : "defaultemailicon.gif"
  ]



Save the file, create a new process and MAGIC! Now you can use your custom work item handler and it will be appear in the process editor library under the Service Tasks pane. See my sample process:



If you build, deploy the project and run the process above, you see the "Hello World!" message in the logs:

00:25:16,904 INFO  [stdout] (http-localhost.localdomain/127.0.0.1:8080-3) Hello World!


That's our Hello World Work Item Handler! Of course you can also declare parameters for the Work Item and do more complex operations, such as access a Web Service, send email, send SMS, update a database....

Download the sources on github

Comentários

  1. [
    "name" : "WorkItemTestHandler",
    "parameters" : [
    "Message" : new StringDataType()
    ],
    "displayName" : "Hello!",
    "icon" : "defaultservicenodeicon.png"
    ]

    ResponderExcluir
  2. hello... i tried your example but when i add the jar as dependency I get the error "Parameter named 'value' cannot be null!!".. can you help me please?

    ResponderExcluir
    Respostas
    1. When exactly you have this error? You can add the dependency in your project pom.xml, in artifacts repository or in jbpm console/business central WEB-INF lib directory

      Excluir
  3. unfortunately not from the installation in my pc... from the pc of my collegue it works fine.so it's ok...Thanx for your reply!

    ResponderExcluir
  4. we have major problem with web service calls... can you give us an example how to use the ws task please....

    ResponderExcluir
    Respostas
    1. Hi alex. search "creating service task" and "using process data in service task" in youtube! you will find it.

      Excluir
  5. it drives me crazy! i am getting always an org.apache.cxf.service.factory.ServiceConstructionException

    ResponderExcluir
  6. Jeeeesus! First normal, doable tutorial on this subject on the web. Did it! Worked! I cannot describe how I am happy. You RedHat guys! What we are able to do further with this approach is very cool. But, don't you think it's very complicated and error prone? Couldn't you make it even more complicated?

    I heard a lot from people searching for a proper BPM tool. After playing with jBPM for a couple of days, they escape to other tools due to its complexities. It's cool to have many features, but not too many. Please work on simplicity.

    BTW, nice job!

    ResponderExcluir
    Respostas
    1. Hello,

      Thanks for your feedback.

      jBPM developers are improving this everyday.

      For example, on last release they added an automated way to import tasks, see Kris post about this:

      http://kverlaen.blogspot.com.br/2016/10/jbpm-650final-available.html

      Excluir
  7. Hi,

    Thanks for the article, I tried creating Custom WorkItemHandler following it but I get below error while trying to save business-process with Custom WorkItemHandler.

    ---------------------
    16:34:14,282 ERROR [org.jbpm.designer.bpmn2.impl.Bpmn2JsonUnmarshaller] (http-/127.0.0.1:8080-7) 0
    16:34:14,315 ERROR [stderr] (http-/127.0.0.1:8080-7) java.lang.NullPointerException
    16:34:14,315 ERROR [stderr] (http-/127.0.0.1:8080-7) at org.eclipse.bpmn2.util.Bpmn2ResourceImpl.setIdEvenIfSet(Bpmn2ResourceImpl.java:157)
    16:34:14,316 ERROR [stderr] (http-/127.0.0.1:8080-7) at org.eclipse.bpmn2.util.Bpmn2ResourceImpl.prepareSave(Bpmn2ResourceImpl.java:126)
    16:34:14,316 ERROR [stderr] (http-/127.0.0.1:8080-7) at org.jbpm.designer.bpmn2.resource.JBPMBpmn2ResourceImpl.createXMLSave(JBPMBpmn2ResourceImpl.ja
    16:34:14,316 ERROR [stderr] (http-/127.0.0.1:8080-7) at org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl.doSave(XMLResourceImpl.java:192)
    16:34:14,317 ERROR [stderr] (http-/127.0.0.1:8080-7) at org.eclipse.emf.ecore.resource.impl.ResourceImpl.save(ResourceImpl.java:1406)
    16:34:14,357 ERROR [stderr] (http-/127.0.0.1:8080-7) at org.jbpm.designer.web.profile.impl.JbpmProfileImpl$1.parseModel(JbpmProfileImpl.java:238)
    16:34:14,358 ERROR [stderr] (http-/127.0.0.1:8080-7) at org.jbpm.designer.repository.servlet.AssetServiceServlet.doPost(AssetServiceServlet.java:121)
    16:34:14,358 ERROR [stderr] (http-/127.0.0.1:8080-7) at javax.servlet.http.HttpServlet.service(HttpServlet.java:754)
    ........................................
    ........................................
    ........................................
    16:34:14,362 ERROR [stderr] (http-/127.0.0.1:8080-7) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:97)
    16:34:14,362 ERROR [stderr] (http-/127.0.0.1:8080-7) at org.apache.catalina.authenticator.SingleSignOn.invoke(SingleSignOn.java:419)
    16:34:14,362 ERROR [stderr] (http-/127.0.0.1:8080-7) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:102)
    16:34:14,362 ERROR [stderr] (http-/127.0.0.1:8080-7) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344)
    16:34:14,362 ERROR [stderr] (http-/127.0.0.1:8080-7) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:854)
    16:34:14,363 ERROR [stderr] (http-/127.0.0.1:8080-7) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:653)
    16:34:14,363 ERROR [stderr] (http-/127.0.0.1:8080-7) at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:926)
    16:34:14,363 ERROR [stderr] (http-/127.0.0.1:8080-7) at java.lang.Thread.run(Thread.java:745)
    16:34:14,363 ERROR [org.jbpm.designer.repository.servlet.AssetServiceServlet] (http-/127.0.0.1:8080-7) Error storing asset: null
    ---------------------------------------------

    ResponderExcluir
  8. Hi,

    I am facing problem, that the new task is in editor available only, when the process in "default" package. In other packages is not available. Can you help me?

    Kind regards,
    Ladislav

    ResponderExcluir
  9. i followed the same steps but im not able to see "service tasks" pane at all. what could be possiblely be wrong? im using 6.4 version of jbpm.

    ResponderExcluir
    Respostas
    1. Could you please post your code on github and share for our review? I am interesting in finding what could be wrong!

      Excluir
    2. Hi Willam, There was syntax error. once rectified it, the problem was gone.

      Excluir
  10. could you please publish example to commands as well? im not able to proceed with that one.

    ResponderExcluir

Postar um comentário

Postagens mais visitadas deste blog

Dancing lights with Arduino - The idea

I have been having fun with Arduino these days! In this article I am going to show how did I use an electret mic with Arduino to create a Dancing Lights circuit. Dancing Lights   I used to be an eletronician before starting the IT college. I had my own electronics maintenance office to fix television, radios, etc. In my free time I used to create electronic projects to sell and I made a few "reais" selling a version of Dancing lights, but it was too limited: it simply animated lamps using a relay in the output of a 4017 CMOS IC. The circuit was a decimal counter  controlled by a 555. 4017 decimal counter. Source in the image When I met Arduino a few years ago, I was skeptical because I said: I can do this with IC, why should I use a microcontroller. I thought that Arduino was for kids. But now my pride is gone and I am having a lot of fun with Arduino :-) The implementation of Dancing Lights with Arduino uses an electret mic to capture the sound and light leds...

Simplest JavaFX ComboBox autocomplete

Based on this Brazilian community post , I've created a sample Combobox auto complete. What it basically does is: When user type with the combobox selected, it will work on a temporary string to store the typed text; Each key typed leads to the combobox to be showed and updated If backspace is type, we update the filter Each key typed shows the combo box items, when the combobox is hidden, the filter is cleaned and the tooltip is hidden:   The class code and a sample application is below. I also added the source to my personal github , sent me PR to improve it and there are a lot of things to improve, like space and accents support.

Creating Fat JARs for JavaFX Applications

A FAT JAR is a type of Java application distribution where a single JAR contains all other dependencies, so no additional file is required to run the JAR besides the Java Virtual Machine. For any Java maven based application, creating a FAR JAR could be solved by using Maven Shade Plugin . However, creating FAT Jars using JavaFX may be a challenge because JavaFX uses modules. Fortunately this subject was intensely discussed in the WEB, and a good explanation and a solution was provided by Jose Pereda in this StackOverflow response. In this post I want to briefly share the steps to make a FAT JAR and post an example on my github so I can point others to check the example. How to create a FAT JAR for a JavaFX application? 1- Create a main class that will run your application. This class must have the main method and call your actual application static launch method; 2- Add the Shade Plugin to your project. For those using Gradle notice that Jose Pereda also provided an answer about it i...