How to start a process with an in memory engine/db?

1,445 views
Skip to first unread message

fher...@gmail.com

unread,
Jul 31, 2015, 5:15:33 AM7/31/15
to camunda BPM users
Hi,

I am currently trying to bootstrap the engine standalone in memory with an in-memory database as well. I am able to deploy the process and it seems to be valid as per Bpmn.validateModel().

This is what I am doing for starting my process:

ProcessEngine processEngine = ProcessEngineConfiguration.createStandaloneInMemProcessEngineConfiguration()
.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_CREATE_DROP).setJdbcUrl("jdbc:h2:mem:my-own-db;DB_CLOSE_DELAY=1000") .buildProcessEngine();


RepositoryService repositoryService = processEngine.getRepositoryService();
String deploymentId = repositoryService.createDeployment().addModelInstance("Instance1", modelInstance).deploy().getId();

List<String> deploymentResources = repositoryService.getDeploymentResourceNames(deploymentId);
assertEquals(1, deploymentResources.size());

InputStream deploymentInputStream = repositoryService.getResourceAsStream(deploymentId, deploymentResources.get(0));
String contentFromDeployment = readInputStreamToString(deploymentInputStream);

System.out.println(contentFromDeployment);
repositoryService.activateProcessDefinitionByKey("process-with-one-task");

RuntimeService runtimeService = processEngine.getRuntimeService();
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("process-with-one-task");


My process model which I get back from this call System.out.println(contentFromDeployment); looks the following:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<definitions targetNamespace="http://camunda.org/examples" xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL">
<process id="process-with-one-task">
<startEvent id="start">
<outgoing>start-task1</outgoing>
</startEvent>
<userTask id="task1" name="User Task">
<incoming>start-task1</incoming>
<outgoing>task1-end</outgoing>
</userTask>
<endEvent id="end">
<incoming>task1-end</incoming>
</endEvent>
<sequenceFlow id="start-task1" sourceRef="start" targetRef="task1"/>
<sequenceFlow id="task1-end" sourceRef="task1" targetRef="end"/>
</process>
</definitions>

I call repositoryService.activateProcessDefinitionByKey("process-with-one-task"); and it works as far as I don't get an error for this :) ... but when I now call runtimeService.startProcessInstanceByKey("process-with-one-task"); I get the following exception:

SCHWERWIEGEND: Error while closing command context
org.camunda.bpm.engine.exception.NullValueException: no processes deployed with key 'process-with-one-task': processDefinition is null
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:408)
at org.camunda.bpm.engine.impl.util.EnsureUtil.generateException(EnsureUtil.java:283)
at org.camunda.bpm.engine.impl.util.EnsureUtil.ensureNotNull(EnsureUtil.java:44)
at org.camunda.bpm.engine.impl.util.EnsureUtil.ensureNotNull(EnsureUtil.java:39)
at org.camunda.bpm.engine.impl.persistence.deploy.DeploymentCache.findDeployedLatestProcessDefinitionByKey(DeploymentCache.java:90)
at org.camunda.bpm.engine.impl.cmd.StartProcessInstanceCmd.execute(StartProcessInstanceCmd.java:63)
at org.camunda.bpm.engine.impl.cmd.StartProcessInstanceCmd.execute(StartProcessInstanceCmd.java:35)
at org.camunda.bpm.engine.impl.interceptor.CommandExecutorImpl.execute(CommandExecutorImpl.java:24)
at org.camunda.bpm.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:97)
at org.camunda.bpm.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:32)
at org.camunda.bpm.engine.impl.RuntimeServiceImpl.startProcessInstanceByKey(RuntimeServiceImpl.java:66)
at com.bearingpoint.bpmn.test.TestCreation.createModel(TestCreation.java:79)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

What am I missing to successfully deploy and start this specific process? I tried several other variants including starting the process via the startProcessInstanceById(...)
and deploying the model differently as shown in some of your unittests on github but it either resulted in a NullPointerException or the exception shown above.

Thank you for your help already and kind regards,
Francesca

thorben....@camunda.com

unread,
Jul 31, 2015, 11:12:38 AM7/31/15
to camunda BPM users, fher...@gmail.com
Hi Francesca,

Could you please condense the problem to small running example that we can use to reproduce the behavior? For example a simple Maven project with a main class.

Thanks,
Thorben

Sebastian Menski

unread,
Jul 31, 2015, 1:34:16 PM7/31/15
to camunda BPM users, fher...@gmail.com
Hi Francesca,

your resource name must either end with ".bpmn" or ".bpmn20.xml" otherwise the BPMN deployer will not recognize your resource as BPMN process and skip it. Change you deployment command to:

String deploymentId = repositoryService.createDeployment().addModelInstance("Instance1.bpmn", modelInstance).deploy().getId();

To check if your process was actual deployed as BPMN process use the repositoryService:

ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().singleResult();
assertEquals
("process-with-one-task", processDefinition.getKey());

You also don't have to call repositoryService.activateProcessDefinitionByKey("process-with-one-task"); it is the inverse operation of suspendProcessDefinitionByKey. Per default a process definition is active.

Cheers,
Sebastian

fher...@gmail.com

unread,
Aug 3, 2015, 3:24:48 AM8/3/15
to camunda BPM users, fher...@gmail.com
Hi,

thank you, that did the trick… I just have a follow up question for me to understand this better.
Why did my original code work initially until I wanted to query the process definition? Because this was working fine:
String deploymentId = repositoryService.createDeployment().addModelInstance("Instance1", modelInstance).deploy().getId();

List<String> deploymentResources = repositoryService.getDeploymentResourceNames(deploymentId);
assertEquals(1, deploymentResources.size());

Would it be a feasible solution to throw an exception if camunda does not get an ID with the correct ending? Or is it possible to work with resources which do not have the ".bpmn" ending?

Thank you for your help and have a nice start of the week :)

BR,
Francesca

Christian Lipphardt

unread,
Aug 3, 2015, 3:33:26 AM8/3/15
to camunda-...@googlegroups.com
Hi Fransceca,

It is possible to have include different resources in your deployment
like PNGs, groovy/whatever scripts etc. But the engine only creates a
process definition out of *.bpmn / *.bpmn20.xml files. Similiar, Case
definitions are only parsed when they have the file extension *.cmmn /
*.cmmn10.xml.
A deployment for the engine is only some kind of archive with some
resources. When they do not include bpmn/cmmn files, they are inserted
the database too, but no process/case definition will be created.

Cheers,
Christian
signature.asc

fher...@gmail.com

unread,
Aug 3, 2015, 4:40:37 AM8/3/15
to camunda BPM users
Thank you for your help and information. :)

Paolo Cabras

unread,
Oct 15, 2015, 11:01:37 AM10/15/15
to camunda BPM users, fher...@gmail.com
Hi everyone,

I have a similar problem but I don't understand where the trick is.

I have a .bpmn file generated by the camunda modeler.

I have implemented a test class for understanding and testing (my business logic outside a container) camunda API.
I am using JUnit 4 features for that.

So, this is a piece of my .bpmn file (just the lines related to this question)


<?xml version="1.0" encoding="UTF-8"?>
<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:camunda="http://activiti.org/bpmn" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd" id="_pBCBME-4EeWz-IOMgTJR7g" exporter="camunda modeler" exporterVersion="2.7.0" targetNamespace="http://activiti.org/bpmn">
 
<bpmn2:collaboration id="_Collaboration_3">
   
<bpmn2:participant id="new_mutation" name="New Mutation Request" processRef="hrmutations_app"/>
 
</bpmn2:collaboration>
 
<bpmn2:process id="hrmutations_app" name="HRMutation" isExecutable="true">
   
<bpmn2:laneSet id="LaneSet_1" name="Lane Set 1">
     
<bpmn2:lane id="dg_sd_hr_correspondent" name="DG/SD-HR Correspondent">
       
<bpmn2:flowNodeRef>ParallelGateway_1</bpmn2:flowNodeRef>
       
<bpmn2:flowNodeRef>StartEvent_newMutation</bpmn2:flowNodeRef>
       
<bpmn2:flowNodeRef>SubProcess_MutationBuilding</bpmn2:flowNodeRef>
       
<bpmn2:flowNodeRef>EndEvent_CancelledMutation</bpmn2:flowNodeRef>


And this is my test class:

public class CamundaAPITest{

   
private static ProcessEngine processEngine;

   
static{

       
processEngine = StandaloneInMemProcessEngineConfiguration.
                           
createStandaloneInMemProcessEngineConfiguration().
                            buildProcessEngine
();
   
}

   
@Rule
    public ProcessEngineRule processEngineRule = new ProcessEngineRule(processEngine);

   
@Test
    @Deployment(resources = "hrmutations_new_test.bpmn")
   
public void testInstantiateProcessInstance(){

       
RuntimeService runtimeService = processEngineRule.getRuntimeService();

       
ProcessInstance processInstance = runtimeService.startProcessInstanceById(HRMutationProcessActivity.hrMutationsProcessName);

       
/*Assert.assertNotNull(processInstance);*/


    }

HRMutationProcessActivity.hrMutationsProcessName is equal to hrmutations_app so the process ID according to the .bpmn file.


The .bpmn file is fine because junit doesn't complain about it (actually not anymore).
And I'm able to retrieve the processInstance through the runtimeService.startProcessInstanceByKey method but not from the runtimeService.startProcessInstanceById one.
What I get is 

org.camunda.bpm.engine.exception.NullValueException: no deployed process definition found with id 'hrmutations_app': processDefinition is null

Now, the workflow I would like to test is the following:

-creating ProcessInstances from the runtimeService corresponding to that Id
-setting a key which should identify a particular active ProcessInstance for dealing with tasks
-dealing with tasks depending on the type

Have I well understood how API works?
If so, where am I wrong in building tests?

Cheers,

Paolo

thorben....@camunda.com

unread,
Oct 15, 2015, 12:08:45 PM10/15/15
to camunda BPM users, fher...@gmail.com
Hi Paolo,

The process definition key in the Java API is the ID of the BPMN XML [1]. The process definition id in the Java API is automatically generated to distinguish between two process definitions with the same key (since you can deploy two process models with the same ID in the XML).

The key you look for might be the business key. You can supply it when you start a process instance, e.g. by

runtimeService.startProcessInstance(HRMutationProcessActivity.hrMutationsProcessName, "someBusinessKey");

You can then use the business key to search for tasks, e.g.

taskService.createTaskQuery().processInstanceBusinessKey("someBusinessKey").list();

This filter is also accessible in Tasklist.

Cheers,
Thorben

[1] https://docs.camunda.org/manual/7.3/guides/user-guide/#process-engine-process-engine-concepts-keys-and-versions

Paolo Cabras

unread,
Oct 16, 2015, 2:57:16 AM10/16/15
to camunda BPM users, fher...@gmail.com
Ok,

always good to receive clarifications!!

Should I flag the question as answered somehow?

Thanks for helping,

Cheers,

Paolo
Reply all
Reply to author
Forward
0 new messages