Java ProcessEngine - Initial Variables Lost (Timers and Re-Run Processes)

Since you are using a timer start event, the start is time-triggered by the process engine itself, not on request of a user. Do you maybe mean the user who deploys the workflow to the process engine?

Correct. We have a web service that accepts the workflow to execute, as well as the variables to pass to the workflow. That web service then invokes the workflow via the processEngine.

Just to avoid a misunderstanding: So your web service invokes the method RepositoryService#createDeployment, deploying the BPMN XML provided in the service call?

Great question. We have it broken down into two actions: a save/deploy function, then an execute function. Here is the save/deploy:

public String deploy(byte[] content, String deploymentName, String resourceName, String tenantId) throws WorkflowException {
    try {
        String deploymentID = processEngine.getRepositoryService().createDeployment().tenantId(tenantId).name(deploymentName).addInputStream(resourceName, new ByteArrayInputStream(content)).deploy().getId();
        logger.info("Resource {} was deployed with deployment id: {}", resourceName, deploymentID);

        ProcessDefinition def = processEngine.getRepositoryService().createProcessDefinitionQuery().tenantIdIn(tenantId).deploymentId(deploymentID).singleResult();

Okay, now we are getting there :slight_smile:

First of all, for timer start events, you won’t need the execute part, since process instantiation is triggered by the engine itself based on the timer configuration. When you call RuntimeService#startProcessInstanceByKey or similar methods for a process with a timer start event, then the engine creates a new process instance, but that is totally unrelated to the repeated instantations based on the timer. Accordingly, when you instantiate the process in your execute phase, you make those variables available only to that instance. Now, there is currently no high-level feature to predefine variables during deployment that should be added to every process instance that the engine itself starts.

And still I think it is possible to build this. If you want to avoid maintaining some external service to retrieve the variables, then those variables must be persisted in Camunda’s database tables. A pragmatic way to provide the variables could be to add them to the deployment, assuming you can serialize the variables. This would be the rough steps:

  1. In your deploy method, serialize the variables into a single byte array, create a byte array input stream bis
  2. Add the variables to the deployment by invoking DeploymentBuilder#addInputStream and give the variables resource a predefined name, for example variables
  3. In the execution listener of the start event, fetch the deployment id for the current process instance (you get the process definition id from the DelegateExecution object, then use RepositoryService#getProcessDefinition to obtain the definition, then use ProcessDefinition#getDeploymentId)
  4. Fetch the variables deployment resource via RepositoryService#getResourceAsStream
  5. Deserialize the resource and set the variables in your process instance

I hope that makes sense.

Cheers,
Thorben

2 Likes

That would be a great feature to have.

It makes complete sense. Many thanks. I’ll give it a shot and post results here. Cheers.