Custom tasks

From jBPM documentation:

jBPM provides the ability to create and use domain-specific task nodes in your business processes. This simplifies development when you’re creating business processes that contain tasks dealing with other technical systems.

When using jBPM, we call these domain-specific task nodes `custom work items'' or (custom) `service nodes. There are two separate aspects to creating and using custom work items:

  • Adding a node with a custom work item to a process definition using the Eclipse editor or jBPM designer.

  • Creating a custom work item handler that the jBPM engine will use when executing the custom work item in a running process.

Custom tasks are also called as domain specific tasks. The technical term is work item and its work item handler.

A work item is an XML node inside your process definition. The respective work item handler is a Java class that implements the org.kie.api.runtime.process.WorkItemHandler interface. This document explains how to integrate and configure a work item handler and how to use the handler to execute a work item.

Work item handler registry

The mapping between a work item and its handler is based on the work item name. The name has to be added to the jBPM Environment when starting the engine. In Magnolia we use an observed registry for work item handlers. The registry is under the workItemHandlers node in module configuration. Custom handlers can be configured in any module using YAML or JCR.

Here are the default work item handlers registered in Magnolia:

Default work item handlers

The expanded rejectNotification handler shows the properties needed to register a handler:

  • class: The definition class of a work item is similar to any other definition class in Magnolia. The fields you make accessible using getters and setters on the definition are accessible to the implementation by injecting the definition into it. This is one possibility to access data from within your handler in the process. Another option is passing a parameter map when launching the process.

  • implementationClass: An implementation class executes the work item.

Decorators

Do not re-implement similar mechanisms over and over again. Introduce decorators for your handlers when you need some common functionality in handlers. A decorator allows you to wrap an existing work item handler implementation into another handler. Both handlers must implement the same WorkItemHandler interface.

Decorator configuration is similar to handler configuration. A decorator needs a definition and an implementation configured. When the handler is loaded into Magnolia during system startup, it looks for a decorator node in the configuration. If the node is found the original handler is wrapped into the decorator by passing the original handler as parameter. Also passed are the decorator definition and any other objects accessible through injection.

Error handling is an example of decoration. A technical error during execution throws an exception:

Exception because of an technical error

Error handling

Error handling in process execution is not a trivial topic. Start implementing error handling the moment you start modeling your process. You have to know what can go wrong and you need to decide what to do in case of errors. As a rule of thumb, exception and error handling should be handled inside your process and be isolated from the rest of the system.

Error handling using a decorator

As described in jBPM Technical Exceptions, you can use decorators for handling errors in custom tasks where an error is an exception thrown during the execution of a task. ThrowExceptionHandlerDecorator is a sample implementation of a decorator for wrapping any kind of task. The decorator catches any kind of exception thrown during execute and abort phase of the handler and wraps the exception into a WorkItemHandlerRuntimeException.

The exception can then be caught as part of the process using an Error Boundary Event, letting the process take care of error handling. The advantage of this approach is that you clearly see where errors can happen and the associated handling is evident at process level. You can re-use the pattern for other custom tasks that may fail.

Error handling diagram

Apart from using Magnolia’s own exception decorator you can also use the decorators provided by jBPM such as SignallingTaskHandlerDecorator or LoggingTaskHandlerDecorator. Set the HandlerDecoratorDefinition in the class property and the decorator implementation in the implementationClass property in your configuration.

Error handler decorator configuration

Error handler decorator configuration

ThrowExceptionHandlerDecorator properties:

  • class

  • implementationClass: The actual implementation of the decorator

  • log: Whether the caught exception should be logged. Default is false.

Modeling an error

Define the error at the process level in the BPMN2 editor:

BPMN2 Editor

Reference the error from the Error Boundary Event:

Error Boundary Event

Asynchronous execution

As process execution runs synchronously you will run into problems executing long-running tasks as part of the process. There are different solutions to approach this problem. See jBPM: Concurrency and asynchronous execution before proceeding.

Executing your work item handler asynchronously

Instead of spawning a thread manually inside your work item handler as outlined in jBPM: Asynchronous execution, you can extend Magnolia’s AsyncWorkItemHandler which takes advantage of the asynchronous Quartz scheduler for launching long running tasks. The benefit of extending this abstract handler is that you can model the error handling the same way as in Modeling an error using an _Error Boundary Event.

Implementation

In your implementer class, extend AsyncWorkItemHandler and implement the abstract methods that take care of creating Quartz related objects such as Trigger and JobDetail. See Quartz documentation for details. (Magnolia currently bundles Quartz 1.8)

info.magnolia.module.workflow.jbpm.workitem.handler.AsyncWorkItemHandler

public abstract class AsyncWorkItemHandler implements WorkItemHandler {

    @Inject
    public AsyncWorkItemHandler(...) {
        ...
    }

    protected abstract String getJobName(WorkItem workItem);
    protected abstract String getHandlerName();
    protected abstract JobDetail createJobDetail(String jobName, WorkItem workItem);
    protected abstract Trigger createTrigger(String jobName, WorkItem workItem);
}

Error handling in asynchronous execution

Error handling during asynchronous execution is done by registering a Quartz JobListener to the scheduler. The listener handles a failed job in the same way an error decorator handles errors. In case you need to change the default behavior, override the AsyncWorkItemHandler#getListener(String jobName) method in your implementation.

Tutorial

We have put together a step-by-step tutorial on how to model, implement and load custom work item handlers.

Feedback

DX Core

×

Location

This widget lets you know where you are on the docs site.

You are currently perusing through the DX Core docs.

Main doc sections

DX Core Headless PaaS Legacy Cloud Incubator modules