Search

Camunda BPM as a JavaScript Engine

JavaScript is becoming more and more popular, as it has the envious combination of a broad developer base - both front-end and back-end developers alike - and a rapidly growing set of capabilities. As a result, we're seeing more and more demand for its use in lieu of Java for any coding that is required in Camunda BPM process models. Here are a couple of real-world examples:


  1. One of our current clients - a Fortune 200 telecommunications company - is using JavaScript in its Camunda BPM process models. Their .NET developers know JavaScript from using it for front-end/UI development work, so using it for back-end work is an easy transition.

  2. A past client, in this case a very large defense contractor, also chose to use JavaScript instead of Java. In their case, they had a team of expert-level JavaScript developers with front-end and back-end JavaScript experience. They've been using Camunda BPM and JavaScript together now for years with success.


NOTE: While JavaScript is currently deprecated in Camunda BPM, Summit58 offers a fix to this, a modified Camunda BPM engine that can run the Graal.js JavaScript engine in lieu of Nashorn. It's a drop-in replacement; you won't have to change your existing Nashorn code. Please see the earlier link in this paragraph for more details.


In the paragraphs below, I'm going to show an illustration of how you can use JavaScript in lieu of Java in a complex process model construct, a parallel multi-instance embedded subprocess. The TL;DR version, however, is that there are no limitations to what you can do in JavaScript in Camunda BPM. Could it be considered to be a JavaScript BPM engine? That supports BPMN 2.0? We'll let you decide, but you can use JavaScript everywhere in Camunda.


Camunda BPM isn't just for "Java shops". If you want a flexible, open and capable BPM engine, give us a call; we can help you leverage Camunda in a way that is comfortable for your enterprise, giving you a customizable, Apache-licensed BPM engine that works for your enterprise at an attractive cost. Contact us at info@summit58.co.


--


For those of you who are ready to get your hands dirty, here's more detail! :)


Let's look at my recent conversion of our "standard-examples" package to JavaScript. This package was re-written from scratch after I left Camunda Inc. and has been used in many different flavors to demonstrate the core capabilities of Camunda BPM. In short, I was able to successfully rewrite everything in JavaScript, and I found that there was essentially nothing that I couldn't do! A great example is this process model illustrating how parallel multi-instance embedded subprocesses work in Camunda:



While the use case is simplistic, the code is not; managing parallel multi-instance constructs is something that often trips up Camunda users, both those who are new to the platform and seasoned veterans alike.


Let's focus on the "Concatenate Names & Build List of Full Names" step, because we'll need to: (1) Concatenate names, (2) Add the concatenated names to a Java ArrayList object and (3) move the "lastName" variable, which is assigned via a Camunda Tasklist form and thus automatically added to the process instance scope, from that process instance scope to the local scope for a multi-instance iteration. This ensures that we'll be able to see the variable in our current iteration but that it won't pollute other iterations. Here's the Java code to do that (in condensed/uncommented form):


List<String> namesList = (List<String>)execution.getVariable("namesList");
String firstName = (String)execution.getVariable("firstName");
String lastName = (String)execution.getVariable("lastName");

if(namesList == null) {
  namesList = new ArrayList<String>();
  namesList.add(firstName + " " + lastName);
}
else
  namesList.add(firstName + " " + lastName);

execution.setVariable("namesList", namesList);

while(execution != null) {
  if(execution.isConcurrent()) {
    execution.removeVariable("lastName");
    execution.setVariableLocal("lastName", lastName);
  }

  execution = execution.getParent();
}

And - when using either Nashorn or Graal.js as our JavaScript engine - this is our JavaScript code to do the same:


var ArrayList = Java.type('java.util.ArrayList');

var namesList = execution.getVariable('namesList');
var firstName = execution.getVariable('firstName');
var lastName = execution.getVariable('lastName');

if(!namesList) {
  namesList = new ArrayList();
  namesList.add(firstName + ' ' + lastName);
}
else
  namesList.add(firstName + ' ' + lastName);

execution.setVariable('namesList', namesList);

while(execution) {
  if(execution.isConcurrent()) {
    execution.removeVariable('lastName');
    execution.setVariableLocal('lastName', lastName);
  }

  execution = execution.getParent();
}

The major differences are in the way we check for nulls - it's hard not to love JavaScript/ECMAScript's method! - and the variable typing, with JavaScript of course being loosely/dynamically typed. Most importantly, however, we can do the same things with JavaScript, and we can do it with roughly the same number of lines. And there are many other examples in that "standard-examples" package illustrating how we can successfully convert Java code to JavaScript code in Camunda.


So where can we use JavaScript instead of Java in Camunda BPM?


  • In lieu of JavaDelegate implementations,

  • As execution or task listeners,

  • With connectors,

  • In decision tables or in decision literal expressions,

  • Etc!


With Summit58's modified Camunda BPM engine (starting with version 7.12.1, which is available via Maven Central), you can add custom JavaScript code that is usable within your decision tables and decision literal expressions! NOTE: This same custom JavaScript code can be added easily for BPMN with just a handful of lines of configuration code.


For more details and more examples, please contact us via info@summit58.co.

381 views0 comments

Recent Posts

See All