Camunda 7 läuft bei vielen Unternehmen stabil in Produktion - oft seit Jahren. Die Engine ist in die Spring-Boot-Anwendung eingebettet, die Prozesse sind erprobt, das Team kennt die API. Warum also umstellen?

Weil Camunda den Servicevertrag für Version 7 auslaufen lässt. Kein Support, keine Sicherheitspatches, keine Updates. Unternehmen sind gezwungen zu migrieren - und genau das ist aufwändiger als viele erwarten.

Warum die Migration zurückgestellt wird

Bei einem meiner Kunden lief Camunda 7 in einer komplexen Microservice-Landschaft. Die Umstellung auf Camunda 8 wurde evaluiert und zunächst zurückgestellt. Der Grund: Es ist kein Versionsupgrade - es ist ein Architekturwechsel.

Die Unterschiede zwischen Camunda 7 und 8 sind fundamental:

Camunda 7Camunda 8
EngineEingebettet in die Spring-Boot-AppExterne Zeebe-Engine (Cloud oder Self-Managed)
KommunikationDirekte Java-API-AufrufegRPC-basiert über das Netzwerk
Task-AusführungJava DelegatesJob Worker
TransaktionenGleiche DB-Transaktion wie die AppEigenes Transaktionsmodell (Event Sourcing)
DeploymentEin Artefakt (App + Engine)Mindestens zwei Komponenten (App + Zeebe)

Die drei größten Stolpersteine

1. Von Java Delegates zu Job Workern

Das ist der Kern der Migration. In Camunda 7 implementiert man Geschäftslogik als Java Delegates - Klassen, die direkt in der Engine laufen:

// Camunda 7: Java Delegate - läuft IN der Engine
@Component
public class OrderValidationDelegate implements JavaDelegate {

    @Override
    public void execute(DelegateExecution execution) {
        String orderId = (String) execution.getVariable("orderId");
        OrderValidationResult result = orderService.validate(orderId);
        execution.setVariable("isValid", result.isValid());
    }
}

In Camunda 8 gibt es keine Delegates mehr. Stattdessen registrieren sich Job Worker bei der Engine und holen sich Aufgaben ab:

// Camunda 8: Job Worker - läuft AUSSERHALB der Engine
@JobWorker(type = "order-validation")
public Map<String, Object> validateOrder(@Variable String orderId) {
    OrderValidationResult result = orderService.validate(orderId);
    return Map.of("isValid", result.isValid());
}

Der Code sieht ähnlich aus, aber das Ausführungsmodell ist grundlegend anders. Der Worker läuft in einem eigenen Service, kommuniziert über gRPC mit der Zeebe-Engine und verarbeitet Jobs asynchron. Fehlerbehandlung, Retry-Logik und Timeouts funktionieren anders als bei synchronen Delegates.

2. Kein direkter Zugriff auf Prozessvariablen

In Camunda 7 kann jeder Service direkt auf die Engine-API zugreifen und Prozessvariablen lesen oder setzen. In Camunda 8 ist dieser Zugriff nur noch über die Zeebe-API möglich - und die ist deutlich restriktiver.

Das bedeutet: Jeder Service, der bisher RuntimeService.getVariable() aufgerufen hat, muss umgebaut werden. Variablen werden beim Job mitgeliefert oder explizit als Output zurückgegeben.

3. BPMN-Prozesse: Kompatibel, aber nicht identisch

Die gute Nachricht: BPMN-Modelle können grundsätzlich übernommen werden. Prozessflüsse, Gateways und Events bleiben gleich.

Die schlechte Nachricht: Service Tasks müssen angepasst werden. Statt einer Java-Delegate-Klasse referenzieren sie jetzt einen Job-Typ als String. Timer, Fehlerbehandlung und Multi-Instance-Konfigurationen haben teilweise andere Semantik.

<!-- Camunda 7 -->
<serviceTask id="validate"
  camunda:delegateExpression="${orderValidationDelegate}" />

<!-- Camunda 8 -->
<serviceTask id="validate">
  <extensionElements>
    <zeebe:taskDefinition type="order-validation" />
  </extensionElements>
</serviceTask>

Migrationsstrategie

Parallel-Betrieb statt Big-Bang

Ein kompletter Umstieg an einem Stichtag ist riskant. Bewährter ist ein schrittweiser Ansatz:

  1. Camunda 8 aufsetzen - Zeebe Cluster (Self-Managed oder Cloud) bereitstellen, Monitoring einrichten.
  2. Neue Prozesse auf Camunda 8 - Jeder neue Prozess wird direkt für Camunda 8 entwickelt. Keine neuen Delegates mehr.
  3. Bestehende Prozesse schrittweise migrieren - Prozess für Prozess umstellen. Die kritischsten zuletzt, wenn das Team Erfahrung gesammelt hat.
  4. Camunda 7 abschalten - Erst wenn alle aktiven Prozessinstanzen abgeschlossen sind.

Adapter-Schicht als Übergangslösung

Für die Übergangsphase kann eine Adapter-Schicht helfen, die die bestehende Delegate-Logik in Job Workern kapselt:

@Component
@RequiredArgsConstructor
public class DelegateAdapter {
    private final OrderValidationDelegate delegate;

    @JobWorker(type = "order-validation")
    public Map<String, Object> handle(@Variable Map<String, Object> variables) {
        SimpleDelegateExecution execution = new SimpleDelegateExecution(variables);
        delegate.execute(execution);
        return execution.getModifiedVariables();
    }
}

Der Adapter nimmt einen bestehenden Java Delegate, simuliert die DelegateExecution aus Camunda 7 und leitet die Variablen durch. So kann die vorhandene Geschäftslogik unverändert weiterlaufen, obwohl sie jetzt als Job Worker angesprochen wird.

Das ist keine Dauerlösung, aber es ermöglicht eine schnelle Migration ohne sofortiges Umschreiben der gesamten Geschäftslogik.

Worauf besonders zu achten ist

  • Monitoring: Camunda Cockpit (7) wird durch Operate (8) ersetzt. Dashboards und Alerting müssen neu aufgesetzt werden.
  • Laufende Instanzen: Prozessinstanzen, die in Camunda 7 gestartet wurden, können nicht in Camunda 8 fortgesetzt werden. Sie müssen in der alten Engine zu Ende laufen.
  • Lizenzkosten: Camunda 8 Self-Managed erfordert eine Lizenz für produktiven Einsatz. Das Preismodell unterscheidet sich von Camunda 7.

Tests: Gleiches Ziel, anderes Framework

Die bestehenden Prozesstests können nicht 1:1 übernommen werden. In Camunda 7 läuft die Engine eingebettet im Test - mit direktem Zugriff auf ProcessEngine und RuntimeService. In Camunda 8 braucht man den Zeebe Testcontainer:

// Camunda 7: Eingebettete Engine im Test
@ExtendWith(ProcessEngineExtension.class)
public class OrderProcessTest {

    @Test
    @Deployment(resources = "order-process.bpmn")
    public void shouldCompleteOrder() {
        ProcessInstance instance = runtimeService()
            .startProcessInstanceByKey("order-process",
                Map.of("orderId", "123", "amount", 99.90));

        assertThat(instance).isWaitingAt("validate-order");
        complete(task(), Map.of("isValid", true));
        assertThat(instance).isEnded();
    }
}

// Camunda 8: Zeebe Testcontainer
@ZeebeSpringTest
public class OrderProcessTest {

    @Autowired
    private ZeebeClient zeebeClient;

    @Test
    public void shouldCompleteOrder() {
        ProcessInstanceEvent instance = zeebeClient.newCreateInstanceCommand()
            .bpmnProcessId("order-process")
            .latestVersion()
            .variables(Map.of("orderId", "123", "amount", 99.90))
            .send().join();

        ZeebeTestEngine.waitForIdleState(Duration.ofSeconds(5));
        assertThat(instance).hasPassedElement("validate-order");
        assertThat(instance).isCompleted();
    }
}

Die Testlogik bleibt gleich - welche Pfade durchlaufen werden, welche Variablen gesetzt sind, welches Ergebnis erwartet wird. Aber die API ist komplett anders. complete(task()) wird zu asynchronen Job-Worker-Aufrufen, assertThat(instance).isWaitingAt() wird zu hasPassedElement(). Jeder einzelne Prozesstest muss angefasst werden.

Der Tipp: Tests zusammen mit dem jeweiligen Prozess migrieren, nicht separat. So stellt man sicher, dass der migrierte Prozess sofort abgesichert ist.

Fazit

Die Migration von Camunda 7 auf 8 ist kein Versionsupgrade, sondern ein Architekturwechsel. Die BPMN-Prozesse bleiben erhalten, aber die technische Anbindung ändert sich grundlegend. Java Delegates werden zu Job Workern, die eingebettete Engine wird zu einem externen Cluster, synchrone Aufrufe werden asynchron.

Der Aufwand hängt stark davon ab, wie viele Delegates, direkte Engine-API-Zugriffe und Prozesstests existieren. Wer frühzeitig anfängt und schrittweise migriert, verteilt das Risiko. Wer bis zum End-of-Life wartet, steht unter Zeitdruck - und genau dann passieren die teuren Fehler.


Ergänzung: 9. März 2026

Seit diesem Artikel hat sich die KI-gestützte Softwareentwicklung massiv weiterentwickelt. Genau bei Migrationen wie dieser zeigt sich der Mehrwert: Die Umstellung von Java Delegates auf Job Worker und die Anpassung der Prozesstests folgen einem klaren, schematischen Muster - ideal für KI-gestützte Code-Transformation. Was 2023 noch wochenlange manuelle Arbeit bedeutete, lässt sich heute mit erheblich reduziertem Aufwand umsetzen. Die KI erkennt die Delegate-Struktur, generiert den passenden Job Worker und passt die zugehörigen Tests auf das Zeebe-Testframework an. Der Entwickler prüft und verfeinert - statt jede Klasse von Hand umzuschreiben. Wer die Migration bisher gescheut hat: Jetzt ist ein guter Zeitpunkt.