Skip to content

Importing from Flowable/Camunda

Orvanta parses BPMN 2.0 XML from Flowable, Camunda, and Activiti as a single dialect — all three vendors use the same OMG standard with closely related extension namespaces, and Orvanta recognises flowable:, camunda:, and activiti: attributes interchangeably where they overlap.

Against a corpus of 1,754 real-world Flowable process definitions, the current engine:

  • Parses 86.0% (1,508 files) without hitting an unsupported construct.
  • Fully validates 60.9% (1,068 files) — parses and passes deploy-time validation.

These numbers are for orvanta-platform 6.4.1. They come from an automated test suite run against the actual parser and validator (backend/tests/fixtures/bpmn/flowable_corpus/BASELINE.json in orvanta-platform), not an estimate. Orvanta does not support all of BPMN 2.0 — treat these figures as the honest current baseline, not a target already met.

No single construct dominates what is left to parse. The largest blockers are signal start events (41 files, 2.3%), Flowable’s event-registry start events (30, 1.7%), sendTask (27, 1.5%), the mail service task (26, 1.5%) and the send-event service task (22, 1.3%). The bigger gap is after parsing: a process that parses can still fail deploy-time validation, most often on an unbound service delegate (199 files, 11.4%; see The Java delegate boundary) or on a path that does not reach an end event (155 files, 8.8%). See the element reference for what is supported.

Anything on the supported-elements list executes exactly as documented there, regardless of whether it originated in Flowable, Camunda, or Orvanta’s own modeller. A businessRuleTask with an orvanta:decisionRef evaluates its linked DMN decision table inline — see Decision models. Flowable’s own dialect for the same idea, a serviceTask carrying flowable:type="dmn", evaluates identically, reading its decision reference from a <flowable:field> instead. If either references a <decisionService> rather than a plain decision, the import deploys with a warning and evaluates only the single decision the service names — see Decision Services and DRDs. A serviceTask carrying flowable:type="external-worker" (or the legacy "external" spelling) also executes, as a wait state, and one carrying flowable:type="http" executes as an HTTP task — see the element reference for exactly what each does.

flowable:async, asyncLeave/asyncAfter, and exclusive carry over from an import and execute. These Flowable extension attributes are honoured as forced quiescence boundaries on whichever element carries them — see Execution semantics for exactly what each does and the one documented over-approximation (asyncBefore, a Camunda-only spelling, is accepted rather than ignored). They aren’t yet authorable from the Orvanta editor itself — see Authoring a BPMN diagram — but an element imported with them keeps them, and the boundary is enforced at runtime either way.

Condition expressions are evaluated in the dialect they are written in. A conditionExpression carrying an unescaped ${...} or #{...} region is evaluated by Orvanta’s own JUEL evaluator (orvanta-juel), where ${'1' == 1} is true; anything else, including the undelimited JavaScript Orvanta’s modeller writes, is evaluated as JavaScript. The two are never mixed: a JUEL expression is never retried as JavaScript. The JUEL evaluator covers a subset (literals, variable and property access, arithmetic, comparison, logic, the ternary operator, and the var:/vars:/variables: function family). Method calls, other namespaced functions such as task:get(id), instanceof and engine roots such as execution are refused at deploy time, so those expressions must be rewritten by hand.

Pools and lanes (laneSet/lane), documentation, textAnnotation, association, and the BPMN diagram interchange elements (BPMNDiagram/BPMNPlane/BPMNShape/BPMNEdge) are parsed but their subtrees are neither rejected nor modelled — the engine simply doesn’t build an execution concept for them. The XML you deploy is stored as-is, so these elements round-trip byte-for-byte in storage; there is no swimlane-based execution semantic, and pool/lane structure has no effect on how a process runs.

extensionElements content — Flowable/Camunda I/O mappings (flowable:in/out/field, camunda:inputOutput), listeners, and form properties — is parsed and captured from a namespace-aware allowlist. The I/O mappings (flowable:in/out/field, camunda:inputOutput) are lowered to one internal form and executed: inputs and outputs write process variables before and after the activity, and fields become the activity’s arguments, evaluated in the dialect they were written in (JUEL for the Flowable and Camunda spellings). A JUEL expression outside the evaluated subset, or a Camunda script, fails the mapping and raises an incident naming the expression. This page has not verified that listeners and form properties execute.

A construct the engine cannot run fails deploy-time validation with an error naming it. As of 6.4.1 these are refused:

  • Compensation: compensation boundary and throw events, and any activity marked isForCompensation.
  • Activities: sendTask, adHocSubProcess, transaction sub-processes, and any task or sub-process carrying a standard loop marker.
  • Flowable service task types Orvanta does not run: mail, send-event, shell, and any other unrecognised flowable:type. Attaching an Orvanta script to the element makes it an ordinary script-bound service task instead.
  • Gateways: complexGateway, and an eventBasedGateway with instantiate="true" or eventGatewayType="Parallel".
  • Events:
    • a process-level start event other than none, timer or message (signal, escalation, conditional and error starts are refused there; inside an event sub-process, error, message, timer, conditional and escalation starts are fine);
    • an end event other than none, error, escalation or terminate;
    • an untyped or link intermediate catch event, and an intermediate throw event other than none, signal or escalation;
    • a boundary event of cancel, compensate or variable-listener type;
    • Flowable’s event-registry triggers (flowable:eventType) on any event;
    • a conditional event whose script language is anything other than JUEL or JavaScript, for example Groovy.

Event sub-processes, non-interrupting boundary events, receiveTask, callActivity, terminate end events and signal and escalation events all execute. Deploy-time validation is authoritative: the engine never silently drops or partially executes a construct it can’t fully support. If your process uses anything refused above, it can be imported for viewing but can’t be deployed until those constructs are removed or replaced with equivalents Orvanta does execute.

A serviceTask with a Java delegate (flowable:class, delegateExpression, or the legacy activiti:class) parses today, but currently has no bound Orvanta script — it fails deploy-time validation as a missing script binding rather than running the delegate. This is, on the measured corpus, the single largest reason a process that parses still fails to validate (199 of the 1,754 files, 11.4%).

That failure is expected, not a gap Orvanta intends to close by running your Java code: Flowable doesn’t ship your delegate either. A delegate class is your application code, resolved by your classloader at your deploy — the same is true for any equivalent Orvanta binding. “Orvanta runs what Flowable runs” is true modulo user-supplied delegate bodies, which is exactly the modulo Flowable itself has. A dedicated deploy-time binding flow — resolve each delegate against an Orvanta script once, per workspace, with a clear error until it’s bound — is planned but not yet shipped; today, bind the equivalent logic to the task by hand after import.