cancel
Showing results for 
Search instead for 
Did you mean: 

Execution with id $FOO does not have a subscription to a message event with name $BAR

mindcrime
Champ in-the-making
Champ in-the-making
I have a simple process that looks like this:


<?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: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="message1" name="message1"></message>
  <process id="sampleProcess1" name="Sample Process 1">
    <startEvent id="startevent1" name="Start"></startEvent>
    <serviceTask id="servicetask1" name="Service Task" activiti:async="true" activiti:exclusive="false" activiti:class="org.example.activiti.service.ServiceClass1"></serviceTask>
    <userTask id="usertask1" name="User Task"></userTask>
    <intermediateCatchEvent id="messageintermediatecatchevent1" name="MessageCatchEvent">
      <messageEventDefinition messageRef="message1"></messageEventDefinition>
    </intermediateCatchEvent>
    <exclusiveGateway id="exclusivegateway1" name="Exclusive Gateway"></exclusiveGateway>
    <endEvent id="endevent1" name="End"></endEvent>
    <serviceTask id="servicetask2" name="Service Task" activiti:class="org.example.activiti.service.ServiceClass2"></serviceTask>
    <scriptTask id="scripttask1" name="Script Task" scriptFormat="groovy">
      <script><![CDATA[println( "resuming after receiving message1 event" );]]></script>
    </scriptTask>
    <scriptTask id="scripttask2" name="Script Task" scriptFormat="groovy">
      <script><![CDATA[println( "Flow NOT altered" );]]></script>
    </scriptTask>
    <scriptTask id="scripttask3" name="Script Task" scriptFormat="groovy">
      <script></script>
    </scriptTask>
    <sequenceFlow id="flow1" name="" sourceRef="startevent1" targetRef="servicetask1"></sequenceFlow>
    <sequenceFlow id="flow2" name="" sourceRef="servicetask1" targetRef="usertask1"></sequenceFlow>
    <sequenceFlow id="flow4" name="" sourceRef="usertask1" targetRef="exclusivegateway1"></sequenceFlow>
    <sequenceFlow id="flow5" name="" sourceRef="exclusivegateway1" targetRef="scripttask2">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${alterFlowFlag == false}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="flow6" name="" sourceRef="exclusivegateway1" targetRef="scripttask3">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${alterFlowFlag == true}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="flow7" name="" sourceRef="messageintermediatecatchevent1" targetRef="scripttask1"></sequenceFlow>
    <sequenceFlow id="flow8" name="" sourceRef="scripttask1" targetRef="servicetask1"></sequenceFlow>
    <sequenceFlow id="flow9" name="" sourceRef="scripttask2" targetRef="endevent1"></sequenceFlow>
    <sequenceFlow id="flow10" name="" sourceRef="scripttask3" targetRef="servicetask2"></sequenceFlow>
  </process>
</definitions>

The goal is to alter the execution after the completion of the user task, based on the receipt of an external message.  So we have some Java code that will locate the process instance based on a variable set by ServiceClass1, and then inject a flag we use in the Exclusive Gateway that comes after the User Task.  If the flag is false, we simply proceed as normal, if it's true we want to do something different.

That part works as expected.

What doesn't work is this: In ServiceClass2, which comes after the UserTask in the "special case" we send a message, which we expect to cause execution to pick up at the Message Intermediate Catching Event.  The code in question is very simple and looks like this:


   public void execute( DelegateExecution exec ) throws Exception {
   
      ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
      RuntimeService runtimeService = engine.getRuntimeService();
      
      runtimeService.messageEventReceived("message1", exec.getId(), null );
   }

But when we send that message, Activiti gives us the error:

org.activiti.engine.ActivitiException: Execution with id '24801' does not have a subscription to a message event with name 'message1'

Is there something I'm missing here? 
3 REPLIES 3

mindcrime
Champ in-the-making
Champ in-the-making
OK, never mind that.  I was doing something dumb after all.  I should have been querying for the execution with the message subscription:


  ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
  RuntimeService runtimeService = engine.getRuntimeService();
 
  Execution msgExec = runtimeService.createExecutionQuery().processInstanceId(exec.getProcessInstanceId()).messageEventSubscriptionName("message1").singleResult();
 
  runtimeService.messageEventReceived("message1", msgExec.getId(), null );

The bigger issue is whether not not this whole approach is even feasible.  Basically, the client is trying to avoid having certain sequence flows in the BPMN because the make the diagram too "noisy" for some people.  So they are trying to cheat and use this "send and receive a message within the same process" mechanism to avoid those flows.

Does anybody know if that is possible / supported?  After I fixed the problem with passing the wrong execution ID (which was causing the original problem I posted about), I find that the execution will, indeed, pick back up at the Message Intermediate Catching Event, but somewhere after that I start getting exceptions from PostgreSQL where it detects a DB deadlock.  Should I just tell them "don't do that" or is there a way to make this work?


trademak
Star Contributor
Star Contributor
This is not a good way of implementing message events, no. So if you don't want to clutter the diagrams for the client, so may want to make 2 versions. But technically it should work. So if you run into DB deadlock issues can you post the stacktrace and maybe a unit test showing the issue?

Best regards,

mindcrime
Champ in-the-making
Champ in-the-making
OK, thanks.  For now I've had them just accept drawing all the flows explicitly on the diagram.  I'll rerun this and grab a stacktrace to post in a bit.