Skip to main content

Java

QuantumBPM/quantum-java-sdk — split into a plain Java client and a Spring Boot starter. Requires Java 21+ (the worker runtime uses virtual threads).

Installation

<!-- Plain Java client -->
<dependency>
<groupId>com.quantumbpm</groupId>
<artifactId>quantum-client</artifactId>
<version>1.0.0</version>
</dependency>

<!-- Spring Boot starter — autoconfigured client + @JobWorker registration -->
<dependency>
<groupId>com.quantumbpm</groupId>
<artifactId>quantum-spring</artifactId>
<version>1.0.0</version>
</dependency>

Quick start (plain Java)

import com.quantumbpm.client.QuantumBPM;
import com.quantumbpm.client.auth.ZitadelTokenProvider;
import com.quantumbpm.client.variables.Vars;
import java.util.UUID;

ZitadelTokenProvider provider = new ZitadelTokenProvider(
"./service-account.json",
"https://auth.quantumbpm.com",
"your-zitadel-project-id");

QuantumBPM client = QuantumBPM.builder()
.baseUrl("https://api.quantumbpm.com")
.projectId(UUID.fromString("YOUR_PROJECT_ID"))
.tokenProvider(provider)
.build();

var result = client.dmn().evaluate(
"loan-eligibility",
new Vars().set("requestedAmt", 1000).set("creditScore", 720));

Quick start (Spring Boot)

application.yml:

quantumbpm:
base-url: https://api.quantumbpm.com
project-id: YOUR_PROJECT_ID
auth:
zitadel:
key-file: /path/to/service-account.json
issuer: https://auth.quantumbpm.com
project-id: YOUR_ZITADEL_PROJECT_ID
worker:
enabled: true # default; scans @JobWorker beans
client-id: billing-svc

Then inject QuantumBPM anywhere and annotate handler methods with @JobWorker:

import com.quantumbpm.client.variables.Vars;
import com.quantumbpm.client.workers.Job;
import com.quantumbpm.spring.JobWorker;
import org.springframework.stereotype.Component;

@Component
public class EmailHandler {

@JobWorker(type = "send-email", maxJobs = 5, lockDuration = "1m")
public Vars handle(Job<EmailJob> job) {
emailService.send(job.typed().recipient(), job.typed().subject());
return new Vars().set("messageID", "msg-123");
}

public record EmailJob(String recipient, String subject) {}
}

The autoconfig scans every Spring bean for @JobWorker methods, infers the typed payload from Job<T>, and starts/stops a managed worker via SmartLifecycle.

External job workers (without Spring)

import com.quantumbpm.client.workers.BpmnError;
import com.quantumbpm.client.workers.Worker;

Worker worker = client.newWorker("billing-svc");

worker.handle("send-email", job -> {
String recipient = job.vars().get("recipient", String.class);
emailer.send(recipient);
return new Vars().set("messageID", "msg-123"); // → Complete
}, Worker.withMaxJobs(10), Worker.withLockDuration("1m"));

worker.start(); // returns immediately; loops on virtual threads
Runtime.getRuntime().addShutdownHook(new Thread(() -> worker.stop(15_000)));

Throw a BpmnError to fail with a code boundary error events can catch:

throw new BpmnError("INSUFFICIENT_FUNDS", new Vars().set("balance", 12.0));

For typed dispatch outside Spring, pass the type as the second argument:

record EmailJob(String recipient, String subject) {}
worker.handle("send-email", EmailJob.class, job -> {
emailer.send(job.typed().recipient());
return new Vars();
});

Full reference

See the SDK README for the complete API surface, the Vars typed-access helpers, and the Spring Boot configuration reference.