How to quick start Activiti – a Java BPM Engine with SpringBoot

In software development, digitizing a business process is one of the toughest challenges. It’s because most processes are sophisticated and maintaining them is difficult. In that circumstance, integrating a workflow engine in application is a good solution.

Java open source Activiti comes to us as a light-weight workflow and Business Process Management (BPM) solution. In this tutorial, we’re gonna take a look at Activiti – a BPM Engine.

Related Articles:
How to start Activiti + Spring JPA with Spring Boot
Activiti REST API with Spring Boot Example
Activiti Parallel Tasks + JPA with Spring Boot Example


It was a longtime when BPM vendors have no consensus. There were some standards and specifications but none of them can gather enough traction to become an global standard for doing BPM. Then, BPM vendors together create a standard that unifies the BPM landscape called BPMN, which stands for ‘Business Process Model and Notation‘.

BPMN 1.x focused on graphical notation only. It defines how concepts such as a human task, an executable script, automated decisions… are visualized in a vendor-neutral standardized way.

This is a simple process diagram in BPMN:

Business users and developers can understand business activities’ flow and process easily with 4 basic element categories including set of graphical elements.
– Flow objects: events, activities, gateways.
– Connecting objects: sequence flow, message flow, association.
– Swim lanes: pool, lane.
– Artifacts: data object, group, annotation.

For details, please visit: BPMN Quick Guide.

BPMN 2.0 extends BPMN 1.x with execution semantics and a common exchange format. Now definition models are not only exchangeable between graphical editors but also be executed as-is on any BPMN 2.0 compliant engine such as Activiti.

II. Activiti

1. Overview

Activiti is a BPM engine with core goal:
– take a process definition including human tasks, service calls, then execute them in a certain order.
– expose API to start, manage and query data about process instances for that definition.

Activiti is lightweight and integrates easily with any Java technology or project, and works at any scale (from just a few dozen to millions of process executions).

It can integrate with:
– Standalone JDBC
– Spring

2. Activiti API

2.1 Process Engine API and services

The most common way to interact with Activiti is using ProcessEngine object.

ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

ProcessEngines.getDefaultProcessEngine() will initialize and build a process engine in first time it is called and it is a singleton. From this object, we can obtain useful service objects that contain the workflow/BPM methods (all objects are thread safe).

RepositoryService repositoryService = processEngine.getRepositoryService();
RuntimeService runtimeService = processEngine.getRuntimeService();
TaskService taskService = processEngine.getTaskService();
IdentityService identityService = processEngine.getIdentityService();
FormService formService = processEngine.getFormService();
HistoryService historyService = processEngine.getHistoryService();
ManagementService managementService = processEngine.getManagementService();

RepositoryService offers operations for managing and manipulating deployments and process definitions. Everything that is related to static data (such as process definitions) can be accessed using RepositoryService.

For example, to deploy a process (defined by myProcess.bpmn20.xml in src/test/resources/com/javasampleapproach/test folder) to make it known by Activiti engine, xml file will be parsed to something executable:


To suspend a process definition (new process instance cannot be created):


RuntimeService deals with starting new process instances of process definitions (retrieve and store process variables, query on process instances and executions, signal the instance that the external trigger is received and the process instance can be continued when it’s in certain wait state).

For example, to start a process instance (each process definition could has one or many process instances) with some variables:

Map variables = new HashMap();
variables.put("author", "JavaSampleApproach");
variables.put("field", "Java Technology");

ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("publishBook", variables);

TaskService: manages everything about tasks, like querying tasks assigned to users/groups, creating new standalone task, claiming or completing a task.

For example, to fetch all tasks that assigned to John and complete the first task:

List tasks = taskService.createTaskQuery().taskAssignee("John").list();
Task task = tasks.get(0);

Map taskVariables = new HashMap();
taskVariables.put("confirmation", "true");
taskVariables.put("note", "Should be checked again on next Monday!");
taskService.complete(task.getId(), taskVariables);

Native queries (with ManagementService):

List tasks = taskService.createNativeTaskQuery()
  .sql("SELECT count(*) FROM " + managementService.getTableName(Task.class) + " T WHERE T.NAME_ = #{taskName}")
  .parameter("taskName", "gonzoTask")

IdentityService allows management (creation, update, deletion, querying, …​) of users and groups.

For example, to set the authenticated user:

try {
} finally {

To get list of users who can initiate the given process:

List authorizedUsers =  identityService().createUserQuery().potentialStarter("processId").list();

FormService (optional) exposes a start form (shown to the user before the process instance is started) and a task form (displayed when a user wants to complete a form).

HistoryService exposes historical data such as process instance start times, who did which tasks, how long it took to complete the tasks, which path was followed in each process instance…

For example, to get 5 HistoricTaskInstances which took the most time to finish (the longest duration) of all tasks:

  .listPage(0, 5);

To get 5 HistoricTaskInstances which are deleted by the reason that contains “bug”, which were last assigned to “David”.

  .listPage(0, 5);

ManagementService gives information about database tables and table metadata. It also provides query capabilities and management operations for jobs (that used for timers, asynchronous continuations, delayed suspension/activation).

2.2 Expression

There are 2 types:
– value-expression: all process variables or Spring beans are available to use.


– method-expression:


2.3 Unit testing

Just like regular unit tests, writing unit tests for business processes is simple.
– use org.activiti.engine.test.ActivitiRule object (annotated with @Rule) to get process engine and services
– annotate test methods with org.activiti.engine.test.Deployment

public class BPTest {

  public ActivitiRule activitiRule = new ActivitiRule();

  public void testBP() {
    RuntimeService runtimeService = activitiRule.getRuntimeService();

    TaskService taskService = activitiRule.getTaskService();
    Task task = taskService.createTaskQuery().singleResult();
    assertEquals("My Task", task.getName());

    assertEquals(0, runtimeService.createProcessInstanceQuery().count());

By grokonez | May 11, 2017.

Last updated on April 29, 2021.

Related Posts

6 thoughts on “How to quick start Activiti – a Java BPM Engine with SpringBoot”

  1. Hi

    I’m new in Activiti, Can you assist me to automate sample business process, using both activiti and spring boot?


  2. bonsoir
    je suis nouveau dans Activiti, pouvez-vous m’aider à automatiser les processus d’affaires exemple, en utilisant à la fois activiti avec tomcat et eclipse ?


Got Something To Say:

Your email address will not be published. Required fields are marked *