sábado, 4 de abril de 2015

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:



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:


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:



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

17 comentários:

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

    ResponderExcluir
    Respostas
    1. have you manage to add the dependency?

      Excluir
  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