According to the Activiti User Guide, only the IDs of start messages for processes should be unique over all process definitions. In our scenario (using Activiti 5.16.4), we have the situation that a currently running process instance is waiting for an intermediate or boundary message event. When we try to deploy a new process definition at this point that uses a message with the same ID , the deployment is rejected with the same message as when trying to deploy two process definitions using the same start message:
org.activiti.engine.ActivitiException: Cannot deploy process definition 'SystemProcess.bpmn': there already is a message event subscription for the message with name 'startmessage'.
at org.activiti.engine.impl.bpmn.deployer.BpmnDeployer.addMessageEventSubscriptions(BpmnDeployer.java:328)
at org.activiti.engine.impl.bpmn.deployer.BpmnDeployer.deploy(BpmnDeployer.java:202)
at org.activiti.engine.impl.persistence.deploy.DeploymentManager.deploy(DeploymentManager.java:50)
at org.activiti.engine.impl.cmd.DeployCmd.execute(DeployCmd.java:103)
at org.activiti.engine.impl.cmd.DeployCmd.execute(DeployCmd.java:37)
at org.activiti.engine.impl.interceptor.CommandInvoker.execute(CommandInvoker.java:24)
at org.activiti.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:57)
at org.activiti.spring.SpringTransactionInterceptor$1.doInTransaction(SpringTransactionInterceptor.java:47)
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133)
at org.activiti.spring.SpringTransactionInterceptor.execute(SpringTransactionInterceptor.java:45)
at org.activiti.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:31)
at org.activiti.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:40)
at org.activiti.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:35)
at org.activiti.engine.impl.RepositoryServiceImpl.deploy(RepositoryServiceImpl.java:78)
at org.activiti.engine.impl.repository.DeploymentBuilderImpl.deploy(DeploymentBuilderImpl.java:156)
…
My assumption is that during deployment, the engine checks if any message subscriptions exist with the same ID as the start message, but does not check if the existing subscription is a start message or not. Can anybody confirm that this is a bug in Activiti and I haven't misunderstood the user guide?The behavior can be tested with the following unit test and processes:[java]import static org.hamcrest.CoreMatchers.is;import static org.hamcrest.CoreMatchers.notNullValue;import static org.junit.Assert.assertThat;import java.util.List;import org.activiti.engine.RepositoryService;import org.activiti.engine.RuntimeService;import org.activiti.engine.repository.Deployment;import org.activiti.engine.repository.ProcessDefinition;import org.activiti.engine.runtime.ProcessInstance;import org.junit.Test;public class ActivitiDeploymentTest{ @Rule public ActivitiRule activitiRule; @Test public void deployProcessWithSameMessageAsActiveIntermediateEvent() { RepositoryService repositoryService = activitiRule.getRepositoryService(); // deploy the definition with the message "startmessage" as intermediate event repositoryService.createDeployment().addClasspathResource("IntermediateEventTestProcess.bpmn") .deploy(); // start an instance of this definition RuntimeService runtimeService = activitiRule.getRuntimeService(); ProcessInstance instance = runtimeService.startProcessInstanceByKey("intermediateEventTestProcess"); // check that the instance has been created and is waiting for the message event assertThat(instance, notNullValue()); assertThat( runtimeService.createExecutionQuery().messageEventSubscriptionName("startmessage").count(), is(1L)); // attempt to deploy the definition using "startmessage" as start event repositoryService.createDeployment().addClasspathResource("SystemProcess.bpmn").deploy(); }}[/java]The test uses JUnit4 and Hamcrest CoreMatchers. When executed, it should throw the exception posted above when trying to deploy the second serviceThe processes: IntermediateEventTestProcess.bpmn:
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test">
<message id="testProcessEventFinished" name="testProcessEventFinished"></message>
<message id="START_BOUNDARY_EVENT_PROCESS" name="START_BOUNDARY_EVENT_PROCESS"></message>
<message id="startmessage" name="startmessage"></message>
<process id="intermediateEventTestProcess" name="Intermediate Event Test Process" isExecutable="true" activiti:candidateStarterGroups="service">
<documentation>Test Process</documentation>
<endEvent id="endevent1" name="End"></endEvent>
<startEvent id="startevent1" name="Message start"></startEvent>
<intermediateCatchEvent id="messageintermediatecatchevent1" name="MessageCatchEvent">
<messageEventDefinition messageRef="startmessage"></messageEventDefinition>
</intermediateCatchEvent>
<sequenceFlow id="flow1" sourceRef="startevent1" targetRef="messageintermediatecatchevent1"></sequenceFlow>
<sequenceFlow id="flow2" sourceRef="messageintermediatecatchevent1" targetRef="endevent1"></sequenceFlow>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_intermediateEventTestProcess">
<bpmndi:BPMNPlane bpmnElement="intermediateEventTestProcess" id="BPMNPlane_intermediateEventTestProcess">
<bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
<omgdc:Bounds height="35.0" width="35.0" x="640.0" y="330.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
<omgdc:Bounds height="35.0" width="35.0" x="410.0" y="330.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="messageintermediatecatchevent1" id="BPMNShape_messageintermediatecatchevent1">
<omgdc:Bounds height="35.0" width="35.0" x="520.0" y="330.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
<omgdi:waypoint x="445.0" y="347.0"></omgdi:waypoint>
<omgdi:waypoint x="520.0" y="347.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
<omgdi:waypoint x="555.0" y="347.0"></omgdi:waypoint>
<omgdi:waypoint x="640.0" y="347.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>
…and SystemProcess.bpmn
?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="bpm">
<message id="message" name="message"></message>
<message id="startmessage" name="startmessage"></message>
<process id="systemProcess" name="My process" isExecutable="true">
<scriptTask id="scripttask1" name="Script Task" scriptFormat="javascript" activiti:autoStoreVariables="false">
<script>print("hallo")</script>
</scriptTask>
<sequenceFlow id="flow1" sourceRef="messagestartevent1" targetRef="scripttask1"></sequenceFlow>
<intermediateCatchEvent id="messageintermediatecatchevent1" name="MessageCatchEvent">
<messageEventDefinition messageRef="message"></messageEventDefinition>
</intermediateCatchEvent>
<sequenceFlow id="flow2" sourceRef="scripttask1" targetRef="messageintermediatecatchevent1"></sequenceFlow>
<endEvent id="endevent1" name="End"></endEvent>
<sequenceFlow id="flow3" sourceRef="messageintermediatecatchevent1" targetRef="endevent1"></sequenceFlow>
<startEvent id="messagestartevent1" name="Start">
<messageEventDefinition messageRef="startmessage"></messageEventDefinition>
</startEvent>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_systemProcess">
<bpmndi:BPMNPlane bpmnElement="systemProcess" id="BPMNPlane_systemProcess">
<bpmndi:BPMNShape bpmnElement="scripttask1" id="BPMNShape_scripttask1">
<omgdc:Bounds height="55.0" width="105.0" x="670.0" y="310.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="messageintermediatecatchevent1" id="BPMNShape_messageintermediatecatchevent1">
<omgdc:Bounds height="35.0" width="35.0" x="820.0" y="320.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
<omgdc:Bounds height="35.0" width="35.0" x="900.0" y="320.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="messagestartevent1" id="BPMNShape_messagestartevent1">
<omgdc:Bounds height="35.0" width="35.0" x="590.0" y="320.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
<omgdi:waypoint x="625.0" y="337.0"></omgdi:waypoint>
<omgdi:waypoint x="670.0" y="337.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
<omgdi:waypoint x="775.0" y="337.0"></omgdi:waypoint>
<omgdi:waypoint x="820.0" y="337.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3">
<omgdi:waypoint x="855.0" y="337.0"></omgdi:waypoint>
<omgdi:waypoint x="900.0" y="337.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>