Skip to main content
Version: Next

Get started as a Java developer using Spring

Beginner1 hour

note

This tutorial is not intended for production purposes.

In this guide, we'll step through using Spring Boot and the Spring Zeebe SDK with Desktop Modeler to interact with your local Self-Managed Camunda 8 installation. While this guide focuses on Self-Managed, you can do something similar with SaaS.

By the end of this tutorial, you'll be able to use Spring and Java code with Zeebe to:

  • Deploy a process model.
  • Initiate a process instance.
  • Handle a service task.

For example, in this guide we will outline a BPMN model to receive a payment request, prepare a transaction, charge a credit card, and execute a payment:

example BPMN model to receive a payment request, prepare a transaction, charge a credit card, and execute a payment

Prerequisites

Before getting started, ensure you:

Step 1: Install Camunda 8 Self-Managed

Starting in 8.6.0-alpha2, you can install Camunda 8 Self-Managed as an integrated plain Java application.

For this installation, you must have:

  • OpenJDK 21+ locally installed
  • Camunda 8.6.0-alpha2 or later
  1. Download the latest release artifact, starting with 8.6.0-alpha2.
  2. Download Elasticsearch 8.9.2.
  3. For non-production cases, disable Elasticsearch's security packages by setting the xpack.security.* configuration options to false in ELASTICSEARCH_HOME/config/elasticsearch.yml.
  4. Start Elasticsearch by running ELASTICSEARCH_HOME/bin/elasticsearch (or ELASTICSEARCH_HOME\bin\elasticsearch.bat on Windows).
  5. To start Camunda, run bin/camunda (or bin\camunda.bat on Windows).

Step 2: Create a new Spring Boot project

Next, create a new Spring Boot project:

  1. Go to https://start.spring.io/ to get started.
  2. Under Project, select Maven. Under Language, select Java. Under Spring Boot, select the latest non-SNAPSHOT version (currently 3.3.0).
  3. Under Project Metadata, configure the following:
    1. Group: io.camunda.demo
    2. Artifact: process_payments
    3. Name: Process payments
    4. Description: Process payments with Camunda
    5. Package name: io.camunda.demo.process_payments
    6. Packaging: Jar
    7. Java: Select the Java version you have installed.
    8. For this tutorial, we will not install any dependencies.
  4. Click Generate.
  5. Download the project, extract the .zip file, and add the contents to your desired location.
  6. Open this project in your preferred code editor.
  7. Run mvn spring-boot:run in your terminal to confirm your Spring project builds.
  8. (Optional) Run git init if you'd like to commit milestones along the way, and add a .gitignore file containing target/ to ignore build artifacts.

Step 3: Create a new BPMN diagram

Next, we'll create a BPMN diagram to represent the transaction model shown at the beginning of this guide:

  1. Open Desktop Modeler.
  2. Click Create a new diagram in Camunda 8, and name your diagram Process payments with an id of process-payments.
  3. Add a start event, and name it Payment request received.
  4. Append a task named Prepare transaction.
  5. Click the wrench-shaped change type context menu icon to change the type of task to a script task, and configure the following properties:
    1. Implementation: FEEL expression
    2. Script/Result variable: totalWithTax
    3. Script/FEEL expression: total * 1.1 (this represents the tax applied to the transaction.)
  6. Append a task named Charge credit card.
  7. Click on the task and click the wrench-shaped icon to change the type of task to a service task. In the properties panel, change the Task definition/Type to charge-credit-card.
  8. Append an end event named Payment executed.
  9. Save this BPMN file to your Spring project in src/main/resources, and name it process-payments.bpmn.

Step 4: Deploy your process

To deploy your process, take the following steps:

  1. Open Desktop Modeler and click the rocket icon in the bottom left corner.
  2. Change the Deployment name to process-payments, and ensure the Target is Camunda 8 Self-Managed.
  3. Change the Cluster endpoint to http://localhost:26500/, with no authentication.
  4. Click Deploy.

When you open Operate at http://localhost:8081/, you should now note the process deployed to your local Self-Managed setup.

Step 5: Run your process from Modeler

To run your process, take the following steps:

  1. From Desktop Modeler, click the "play" icon (next to the rocket icon to deploy) in the bottom left corner.
  2. In Variables, insert the JSON object {"total": 100}.
  3. Click Start.

From Operate, you should now notice a process instance running. You'll notice the process instance is waiting at Charge credit card, because we'll need to configure a job worker.

Step 6: Implement a service task

To implement a service task, take the following steps:

Configure Spring Boot Starter

See our documentation on adding the Spring Zeebe SDK to your project for more details, also described below:

  1. Copy the following code snippet into the pom.xml file of your Spring project, below properties and above dependencies:
<repositories>
<repository>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
<id>identity</id>
<name>Camunda Identity</name>
<url>https://artifacts.camunda.com/artifactory/camunda-identity/</url>
</repository>
</repositories>
  1. Add the following dependency to your pom.xml file:
<dependency>
<groupId>io.camunda</groupId>
<artifactId>spring-boot-starter-camunda-sdk</artifactId>
<version>8.5.0</version>
</dependency>

Configure the Zeebe client

Open your src/main/resources/application.properties file, and paste the following snippet to connect to the Self-Managed Zeebe broker:

zeebe.client.broker.grpcAddress=http://127.0.0.1:26500
zeebe.client.broker.restAddress=http://127.0.0.1:8080
zeebe.client.security.plaintext=true

Create a worker

  1. In src/main/java/io/camunda/demo/process_payments/, create a file called ChargeCreditCardWorker.java.
  2. In the file created above, paste the following dependencies and package package io.camunda.demo.process_payments:
package io.camunda.demo.process_payments;

import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import io.camunda.zeebe.spring.client.annotation.JobWorker;
import io.camunda.zeebe.spring.client.annotation.Variable;
  1. Next, we can add a ChargeCreditCardWorker class decorated with @Component and instantiate a logger. Additionally, we will add a chargeCreditCard method and decorate it with @JobWorker, specifying the type of service tasks it will handle. The method takes a @Variable(name = "totalWithTax") Double totalWithTax argument to indicate which variables it needs from the task. The implementation of the method will log the totalWithTax, and return a map, to indicate to Zeebe that the task has been handled:
@Component
public class ChargeCreditCardWorker {
private final static Logger LOG = LoggerFactory.getLogger(ChargeCreditCardWorker.class);
@JobWorker(type = "charge-credit-card")
public Map<String, Double> chargeCreditCard(@Variable(name = "totalWithTax") Double totalWithTax) {
LOG.info("charging credit card: {}", totalWithTax);
return Map.of("amountCharged", totalWithTax);
}
}
note

To check your work, visit our sample repository with the completed code.

In your terminal, run mvn spring-boot:run, where you should see the charging credit card output. In Operate, refresh if needed, and note the payment has executed.

Step 7: Start a process instance

To start a process instance programmatically, take the following steps:

  1. In ProcessPaymentsApplication.java, convert the application to a CommandLineRunner, by adding implements CommandLineRunner to the ProcessPaymentsApplication class declaration. Instantiate a static Logger variable, and an instance variable named zeebeClient with the @Autowired annotation.
@SpringBootApplication
@Deployment(resources = "classpath:process-payments.bpmn")
public class ProcessPaymentsApplication implements CommandLineRunner {

private static final Logger LOG = LoggerFactory.getLogger(ProcessPaymentsApplication.class);

@Autowired
private ZeebeClient zeebeClient;

public static void main(String[] args) {
SpringApplication.run(ProcessPaymentsApplication.class, args);
}
}
  1. Implement an overriding run method in ProcessPaymentsApplication. When the application runs, it will create a new process-payments process instance, of the latest version, with specified variables, and send it to our local Self-Managed instance:
    @Override
public void run(final String... args) {
var processDefinitionKey = "process-payments";
var event = zeebeClient.newCreateInstanceCommand()
.bpmnProcessId(processDefinitionKey)
.latestVersion()
.variables(Map.of("total", 100))
.send()
.join();
LOG.info(String.format("started a process: %d", event.getProcessInstanceKey()));
}
note

To check your work, visit our sample repository with the completed code.

Re-run the application in your terminal with mvn spring-boot:run to see the process run, and note the instance history in Operate.

Step 8: Deploy the process

To deploy your process, take the following steps:

  1. Decorate the ProcessPaymentsApplication class with @Deployment(resources = "classpath:process-payments.bpmn") in ProcessPaymentsApplication.java:
  2. In Desktop Modeler, change the tax amount calculated to total * 1.2 under FEEL expression and save your changes.

Re-run the application in your terminal with mvn spring-boot:run to see the process run. In Operate, note the new version 2 when filtering process instances, and the tax amount has increased for the most recent process instance.