The Ultimate Activiti BPM Cheatsheet: Streamlining Your Business Process Management

Introduction to Activiti BPM

Activiti is an open-source Business Process Management (BPM) platform that enables organizations to model, automate, and optimize business processes. It provides a lightweight, Java-based workflow and BPM engine that helps bridge the gap between business analysts and developers. Activiti is crucial for organizations looking to improve efficiency, maintain consistency, and gain visibility into their business processes.

Core Concepts and Components

Key Architecture Components

  • Process Engine: The central component that executes BPMN 2.0 processes
  • Process Definition: XML representation of a business process in BPMN 2.0 format
  • Process Instance: A running execution of a process definition
  • Task: A unit of work performed by a user or system
  • Service Task: Automated task executed by the system
  • User Task: Manual task performed by a human user
  • Execution: Represents a path of execution through the process

Important Database Tables

Table NamePurpose
ACT_RE_*Repository tables storing static information like process definitions
ACT_RU_*Runtime tables storing runtime data of process instances
ACT_HI_*History tables storing historical data of completed processes
ACT_ID_*Identity tables storing user and group information
ACT_GE_*General tables storing general data like properties

BPMN 2.0 Elements in Activiti

Events

  • Start Events: Trigger the beginning of a process (startEvent)
  • End Events: Indicate the completion of a process (endEvent)
  • Intermediate Events: Occur between start and end events
    • Timer Events: Trigger based on time (intermediateCatchEvent with timerEventDefinition)
    • Message Events: Triggered by messages (intermediateCatchEvent with messageEventDefinition)
    • Signal Events: Used for broadcast communication (intermediateCatchEvent with signalEventDefinition)

Activities

  • Tasks:
    • User Task: <userTask id="approveTask" name="Approve Request" activiti:assignee="${initiator}" />
    • Service Task: <serviceTask id="sendEmail" activiti:class="org.example.EmailTask" />
    • Script Task: <scriptTask id="calculateValues" scriptFormat="groovy">
    • Business Rule Task: <businessRuleTask id="evaluateRule" activiti:ruleVariablesInput="${data}" />
    • Receive Task: <receiveTask id="waitForMessage" />
  • Gateways:
    • Exclusive Gateway (XOR): <exclusiveGateway id="approvalDecision" />
    • Parallel Gateway (AND): <parallelGateway id="forkProcess" />
    • Inclusive Gateway (OR): <inclusiveGateway id="conditionalPaths" />
    • Event-based Gateway: <eventBasedGateway id="waitForEvent" />
  • Subprocesses:
    • Embedded Subprocess: <subProcess id="reviewSubProcess">
    • Call Activity (Reusable Subprocess): <callActivity id="invoiceProcess" calledElement="invoiceProcess">
    • Event Subprocess: <subProcess id="errorHandler" triggeredByEvent="true">

Flow Elements

  • Sequence Flow: <sequenceFlow id="flow1" sourceRef="task1" targetRef="task2" />
  • Conditional Flow: <sequenceFlow id="flow2" sourceRef="gateway" targetRef="task3"><conditionExpression>${amount > 1000}</conditionExpression></sequenceFlow>
  • Default Flow: <sequenceFlow id="defaultFlow" sourceRef="gateway" targetRef="task4" default="true" />

Setting Up Activiti

Maven Dependencies

 
xml
<dependency>
    <groupId>org.activiti</groupId>
    <artifactId>activiti-engine</artifactId>
    <version>6.0.0</version>
</dependency>
<dependency>
    <groupId>org.activiti</groupId>
    <artifactId>activiti-spring</artifactId>
    <version>6.0.0</version>
</dependency>

Process Engine Configuration

 
java
// Standalone configuration
ProcessEngine processEngine = ProcessEngineConfiguration
  .createStandaloneProcessEngineConfiguration()
  .setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE)
  .setJdbcUrl("jdbc:h2:mem:activiti;DB_CLOSE_DELAY=1000")
  .setJdbcDriver("org.h2.Driver")
  .setJdbcUsername("sa")
  .setJdbcPassword("")
  .buildProcessEngine();

// Spring configuration
@Bean
public ProcessEngineConfiguration processEngineConfiguration() {
    SpringProcessEngineConfiguration configuration = new SpringProcessEngineConfiguration();
    configuration.setDataSource(dataSource);
    configuration.setTransactionManager(transactionManager);
    configuration.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
    return configuration;
}

API Usage Examples

Deploying Process Definitions

 
java
// Deploy from classpath resource
Deployment deployment = processEngine.getRepositoryService()
  .createDeployment()
  .addClasspathResource("processes/approval-process.bpmn20.xml")
  .name("Approval Process")
  .deploy();

// Deploy from input stream
InputStream inputStream = new FileInputStream(new File("/path/to/process.bpmn20.xml"));
Deployment deployment = processEngine.getRepositoryService()
  .createDeployment()
  .addInputStream("process.bpmn20.xml", inputStream)
  .deploy();

Starting Process Instances

 
java
// Start by process definition key
Map<String, Object> variables = new HashMap<>();
variables.put("requestor", "John");
variables.put("amount", 5000);

ProcessInstance processInstance = processEngine.getRuntimeService()
  .startProcessInstanceByKey("approvalProcess", variables);

// Start by process definition ID
ProcessInstance processInstance = processEngine.getRuntimeService()
  .startProcessInstanceById("approvalProcess:1:1267", variables);

Working with Tasks

 
java
// Query for tasks
List<Task> tasks = processEngine.getTaskService()
  .createTaskQuery()
  .taskAssignee("manager")
  .processVariableValueEquals("amount", 5000)
  .list();

// Complete a task
processEngine.getTaskService().complete(task.getId());

// Complete with variables
Map<String, Object> variables = new HashMap<>();
variables.put("approved", true);
processEngine.getTaskService().complete(task.getId(), variables);

// Claim and unclaim tasks
taskService.claim(task.getId(), "john");
taskService.unclaim(task.getId());

Query APIs

 
java
// Process instance queries
ProcessInstance instance = runtimeService.createProcessInstanceQuery()
  .processInstanceId(processInstanceId)
  .singleResult();

// Historic process instance queries
HistoricProcessInstance historicInstance = historyService
  .createHistoricProcessInstanceQuery()
  .processInstanceId(processInstanceId)
  .finished()
  .singleResult();

// Execution queries
List<Execution> executions = runtimeService.createExecutionQuery()
  .processVariableValueEquals("approved", true)
  .list();

Working with Process Variables

Setting Variables

 
java
// Set variable on execution
runtimeService.setVariable(executionId, "approved", true);

// Set multiple variables
Map<String, Object> variables = new HashMap<>();
variables.put("approved", true);
variables.put("comment", "Looks good");
runtimeService.setVariables(executionId, variables);

// Set local variables (scope limited to current activity)
runtimeService.setVariableLocal(executionId, "temporaryData", data);

Retrieving Variables

 
java
// Get single variable
Boolean approved = (Boolean) runtimeService.getVariable(executionId, "approved");

// Get all variables
Map<String, Object> variables = runtimeService.getVariables(executionId);

// Get variables with specific names
List<String> varNames = Arrays.asList("approved", "comment");
Map<String, Object> specificVars = runtimeService.getVariables(executionId, varNames);

Transaction Management

Using Transactions

 
java
// Programmatic transaction
TransactionContext transactionContext = Context.getCommandContext().getTransactionContext();
try {
    // Your operations here
    transactionContext.commit();
} catch (Exception e) {
    transactionContext.rollback();
}

// With Spring (@Transactional)
@Transactional
public void executeProcessLogic() {
    // Process operations here, Spring handles the transaction
}

Handling Process Events

Event Listeners

 
java
// Create event listener
public class ProcessStartListener implements ExecutionListener {
    @Override
    public void notify(DelegateExecution execution) {
        String processInstanceId = execution.getProcessInstanceId();
        // Logic to handle process start
    }
}

// Add to process definition
<startEvent id="start">
  <extensionElements>
    <activiti:executionListener class="org.example.ProcessStartListener" event="start" />
  </extensionElements>
</startEvent>

Task Listeners

 
java
// Task listener implementation
public class TaskAssignmentListener implements TaskListener {
    @Override
    public void notify(DelegateTask delegateTask) {
        String assignee = delegateTask.getAssignee();
        // Logic for task assignment
    }
}

// Add to task definition
<userTask id="approveTask" name="Approve Request">
  <extensionElements>
    <activiti:taskListener event="assignment" class="org.example.TaskAssignmentListener" />
  </extensionElements>
</userTask>

Common Challenges and Solutions

ChallengeSolution
Process deployment failsCheck BPMN XML syntax, ensure resources are in classpath, verify database connection
Task not appearing for usersCheck assignee configuration, verify user/group mappings, check task query parameters
Process instance stuckUse management APIs to find suspended executions, check async continuations, verify service task implementations
Performance issuesImplement proper indexing on database, tune history level, optimize queries, consider alternative execution strategies
Debugging process executionEnable debug logging, use Activiti Explorer UI, analyze runtime tables, create custom event listeners

Best Practices

Design Best Practices

  • Keep processes simple and modular
  • Use call activities for reusable subprocesses
  • Model error handling explicitly with boundary events
  • Document process with BPMN annotations
  • Validate processes before deployment

Implementation Best Practices

  • Follow naming conventions for process definitions and elements
  • Minimize the amount of data stored in process variables
  • Use proper transaction boundaries
  • Implement proper exception handling
  • Set appropriate history levels

Deployment Best Practices

  • Version your process definitions
  • Use category and tenant concepts for organization
  • Consider using separate database for history
  • Implement proper monitoring and auditing
  • Create deployment scripts/procedures

Activiti Extensions and Hooks

Form Extensions

 
xml
<userTask id="approveTask" name="Approve Request">
  <extensionElements>
    <activiti:formProperty id="approved" name="Approved" type="boolean" required="true" />
    <activiti:formProperty id="comments" name="Comments" type="string" />
  </extensionElements>
</userTask>

Service Task Extensions

 
xml
<serviceTask id="sendEmail" activiti:class="org.example.EmailTask">
  <extensionElements>
    <activiti:field name="to" stringValue="manager@example.com" />
    <activiti:field name="subject" expression="${process.name}: New request" />
  </extensionElements>
</serviceTask>

Execution Listeners

 
xml
<process id="myProcess">
  <extensionElements>
    <activiti:executionListener class="org.example.ProcessStartListener" event="start" />
    <activiti:executionListener class="org.example.ProcessEndListener" event="end" />
  </extensionElements>
  <!-- Process elements -->
</process>

Resources for Further Learning

  • Official Documentation: Activiti User Guide
  • Books:
    • “Activiti in Action” by Tijs Rademakers
    • “Mastering Activiti” by Jakub Holý
  • Online Courses:
    • Alfresco Activiti Developer Course
    • Camunda BPM (similar concepts to Activiti)
  • Community Resources:
  • Tools:
    • Activiti Designer Eclipse Plugin
    • BPMN.io (online modeler)
    • Activiti Explorer Web Application

Activiti vs Other BPM Platforms

FeatureActivitiCamundajBPMFlowable
Core EngineJava-based, lightweightJava-based, robustJava-based, integrated with KIEFork of Activiti, enhanced
StandardsBPMN 2.0BPMN 2.0, DMN, CMMNBPMN 2.0, DMNBPMN 2.0, DMN, CMMN, Forms
UI ComponentsBasic ExplorerCockpit, Tasklist, AdminDesigner, ConsoleAdmin UI, Task App, IDM
Cloud SupportLimitedGoodGoodExcellent
CommunityActiveVery activeActiveGrowing
Commercial SupportAvailableAvailableAvailable through Red HatAvailable
IntegrationGoodExcellentExcellent with Red HatExcellent

This cheatsheet provides a comprehensive reference for working with Activiti BPM, covering everything from basic concepts to advanced implementation techniques. Use it to streamline your business process development and management with Activiti.

Scroll to Top