Context Switch

When executing a process instance, the process engine has to know which process application provides the corresponding resources. It then internally performs a context switch. This has the following effects:

  • The thread context class loader is set to the process application classloader. This enables loading classes from the process application, e.g., a Java Delegate implementation.
  • The process engine can access the resources it manages for that particular process application. This enables invoking scripting engines or Spin data formats specific to the process application.
    For example, before invoking a Java Delegate, the process engine performs a context switch into the respective process application. It is therefore able to set the thread context classloader to the process application classloader. If no context switch is performed, only those resources are available that are accessible on the process engine level. This is typically a different classloader and a different set of managed resources.

Note that the actual mechanics behind the context switch are platform dependent. For example: in a servlet container like Apache Tomcat, it is only necessary to set the Thread’s current Context Classloader to the web application Classloader. Context specific operations like the resolution of application-local JNDI names all build on this. In an EJB container, this is more complex. This is why the ProcessApplication class is an EJB itself in that environment (see: Ejb Process Application). The process engine can then add an invocation of a business method of that EJB to the call stack and have the Application Server perform its specific logic behind the scenes.

  • Delegation Code Invocation: Whenever delegation code like Java Delegates, execution/task listeners (Java code or scripts), etc. is called by the process engine
  • Explicit Process Application Context Declaration: For every engine API invocation, when a process application was declared using the utility class org.camunda.bpm.application.ProcessApplicationContext

    Declare Process Application Context

Process application context must be declared whenevever custom code uses the engine API that is not part of delegation code and when a context switch is needed for proper function.

To clarify the use case, we assume that a process application employs the . However, for that application JSON serialization shall be customized (think about the numerous ways to serialize a date as a JSON string). The process application therefore contains a Camunda Spin data format configurator implementation that configures the Spin JSON data format in the desired way. In turn, the process engine manages a Spin data format for that specific process application to serialize object values with. Now, we assume that a Java servlet calls the process engine API to submit a Java object and serialize it with the JSON format. The code might look as follows:

Note that the engine API is not called from within delegation code but a from servlet instead. The process engine is therefore not aware of process application context and cannot perform a context switch to use the correct JSON data format for variable serialization. In consequence, the process application-specific JSON configuration does not apply.

  1. ProcessApplicationContext.setCurrentProcessApplication("nameOfTheProcessApplication");
  2. runtimeService.setVariable("processInstanceId", "variableName", jsonValue);
  3. } finally {

Now, the process engine knows in which context to execute the #setVariable call in. It therefore can access the correct JSON data format and serializes the variable correctly.

The methods ProcessApplicationContext#setCurrentProcessApplication declare process application context for all following API invocations until is called. It is therefore advised to use a try-finally block to ensure clearance even when exceptions are raised. In addition, the methods ProcessApplicationContext#withProcessApplicationContext execute a Callable and declare the context during the Callable’s execution.

Declaring process application context whenever engine API is invoked can result in highly repetitive code. Depending on your programming model, you may consider declaring the context in a place that applies to all the desired business logic in a cross-cutting manner. For example, in CDI it is possible to define method invocation interceptors that trigger based on the presence of annotations. Such an interceptor can identify the process application based on the annotation and declare the context transparently.