Building a BPMS Web Application Part 2: Remote Java API

(This article assumes some basic knowledge of the JBoss BPM Suite including using Business Central.)

In Part 1, I described how to make use of the BPMS form metadata, run it through a code generator to produce JSPs for the UI and Java ActionBeans to handle these JSPs (for process instantiation and manual task interaction). Although the code to integrate with BPMS eg, to kick off a process instance and interact with the human tasks can be found partially in the generated ActionBeans, how exactly it works is still shrouded in mystery. This article will solve the mystery.


BPMS has a number of APIs:

KIE API the KIE (Knowledge is Everything) API provides functionality to deploy and manage the runtime environment of business processes. Whatever you want to do with a process, you will probably find a methods in this API that do it for you. The only limitation is that this is a local API meaning that you can use it to create and deploy a KIE project (business process) on the local machine and interact with it.

REST API- this uses Representational State Transfer (REST) in which requests and responses are built around the transfer of representations of resources. Several favours of the REST API allow you to access the data store or Artifact Repository, performs actions on or retrieve information from deployments, and do runtime calls to the Execution Server. You can use either REST , JMS or the Remote Java API to interact with remotely executing business processes. The Remote Java API mimics a limited set of the KIE APIs and users can select whether the REST or JMS API be used as its implementation under the covers. It makes it appear as if you are using the local KIE API to interact with remotely executing processes. I am using the Remote Java API in my application because it is easy to use and it is a Java API.

Using a Convenience Wrapper

I am implementing another layer on top of the Remote Java API to make the job of interacting with a remotely executing business process even simpler. Here is a JUnit test that uses my convenience wrapper:

	public void setUp() throws Exception {
		deploymentId = "com.redhat.bpms.examples:mortgage:1";
		//deploymentId = "";

		deploymentUrl = new URL("http://localhost:8080/business-central");
		userId = "user";
		password = "Pasword|23";
		processId = "";

	    //process variables pass to mortgage process at start-up
		Applicant applicant = new Applicant();
		Property property = new Property();
		property.setAddress("1 miller st");
		Application application = new Application();
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("application", application);

	    processControl = new BpmsRestRemoteProcessControl(deploymentId, deploymentUrl, userId, password);

        // start process
        processInstance = processControl.startProcess(processId, params);
        System.out.println("Started process instance: " + processInstance + " " + (processInstance == null ? "" : processInstance.getId()));
	public void taskListTest() {
        String taskUserId = userId;

        // get task list for user
        List taskSummaries = processControl.getTasksAssignedAsPotentialOwner(taskUserId);
        System.out.println("retrieve Task List for " + taskUserId + " task count=" + taskSummaries.size());
        for (TaskSummary summary : taskSummaries) {
//        	assertNotNull(summary.getActualOwner());
            System.out.println(" taskId=" + summary.getId() + " taskName=" + summary.getName() + " processInstanceId=" +
            		summary.getProcessInstanceId() + " processId=" + summary.getProcessId());
//            		summary.getProcessInstanceId() + " owner=" + summary.getActualOwner().getId());
        assertTrue(taskSummaries.size() != 0);
        // locate the process we created
        long taskId = findTaskId(processInstance.getId(), taskSummaries);
        assertTrue(taskId >= 0);
    protected long findTaskId(long procInstId, List taskSumList) {
        long taskId = -1;
        for (TaskSummary task : taskSumList) {
            if (task.getProcessInstanceId() == procInstId) {
                taskId = task.getId();
                return taskId;
        throw new RuntimeException("findTaskId() no tasks found for pInstanceId = " + procInstId);

	public void tearDown() throws Exception {

The setup method creates the Application object needed for kicking off an instance of the “” process. The required Application object fields include an Application object and a Property object together with other information such as down payment, amortization, etc. The Application object is put is a map. It then creates my wrapper “BpmsRestRemoteProcessControl” object to kick off an instance of the mortgage process by calling startProcess. Note the parameters used in the BpmsRestRemoteProcessControl object creation and startProcess calls. Although I have not included the Application, Applicant and Property classes in the listing, you should get the picture. These classes are simple POJOs. They are the business process’ data model (created using Business Central’s Data Modeler) and are obtained by doing a GIT clone operation from GIT repository on the BPMS server running Business Central.

The taskListTest method is performing a JUnit test in which it retrieves a task list from the BPMS server for the logged in user and checks that the process instance we created during setup is among them.

Note that it aborts the process instance created during setup when tearDown is executed. Only one test is shown.

Implementing the Convenience Wrapper

I created a base class BpmsRemoteProcessControl  which implements all the methods that integrate with remotely executing business processes., This allows a subclass to provide a constructor which uses either the REST API or the JMS API for its implementation. Here is the implementation for the base class:

package com.redhat.bpms.integration;

import java.util.List;
import java.util.Map;

import org.kie.api.runtime.KieSession;
import org.kie.api.runtime.process.ProcessInstance;
import org.kie.api.task.TaskService;
import org.kie.api.task.model.Content;
import org.kie.api.task.model.Task;
import org.kie.api.task.model.TaskSummary;
import org.kie.api.runtime.manager.RuntimeEngine;

// TODO Add methods to it as required
// This is a simple Facade for the Remote Java API. It provides convenience methods to
// control the remote execution of BPMS processes and tasks
public class BpmsRemoteProcessControl {
	private final String LANGUAGE = "en-UK";

    protected RuntimeEngine engine;
    protected KieSession ksession;
    protected TaskService taskService;

    public BpmsRemoteProcessControl() {
    public void setRuntimeEngine(RuntimeEngine engine)  
        // setup Remote Java API services
        this.engine = engine;
        ksession = engine.getKieSession();
        taskService = engine.getTaskService();
    public ProcessInstance startProcess(String processId, Map<String, Object> params) {
    	return ksession.startProcess(processId, params);
    public void abortProcess(long processInstanceId) {
    public List getTasksAssignedAsPotentialOwner(String taskUserId) {
    	return taskService.getTasksAssignedAsPotentialOwner(taskUserId, LANGUAGE);
    public List getTasksAssignedAsBusinessAdministrator(String taskUserId) {
    	return taskService.getTasksAssignedAsBusinessAdministrator(taskUserId, LANGUAGE);
    public Task getTaskById(long taskId) {
    	return taskService.getTaskById(taskId);
    public void claim(long taskId, String taskUserId) {
    	taskService.claim(taskId, taskUserId);
    public Map<String, Object> start(long taskId, String taskUserId) {
    	taskService.start(taskId, taskUserId);
    	Content content = taskService.getContentById(getTaskById(taskId).getTaskData().getDocumentContentId());
    	return (Map<String, Object>) ContentMarshallerHelper.unmarshall(content.getContent(), null);
    public void complete(long taskId, String taskUserId, Map<String, Object>params) {
    	taskService.complete(taskId, taskUserId, params);
    public void release(long taskId, String taskUserId) {
    	taskService.release(taskId, taskUserId);


And here is the subclass BpmsRestRemoteProcessControl that uses the REST API:

package com.redhat.bpms.integration;



public class BpmsRestRemoteProcessControl extends BpmsRemoteProcessControl {

	public BpmsRestRemoteProcessControl(String deploymentId, URL deploymentUrl, String userId, String password) {





In this article, I described how I implemented a convenience wrapper for the Remote Java API to make interacting and controlling remotely executing business process possible and simplifying the coding in the process. There may be cases where you need to use the REST or JMS API directly eg, if you are using non-Java technologies such as the .NET framework, node.js, etc. If you are using Java, I recommend using the Remote Java API. Better still, use my convenience wrapper which makes the integration even simpler.