6 Replies Latest reply on May 30, 2012 2:05 PM by dward

    NullPointerException with BPM

    shen_haisheng

      Hi everybody:

                 i create a bpm demo by myself. it's bpmn file simply like below.

      Capture.JPG

      bpmn file("MonitorService.bpmn") ' content

      <?xml version="1.0" encoding="UTF-8"?> 
      <definitions id="Definition"
                   targetNamespace="http://www.jboss.org/drools"
                   typeLanguage="http://www.java.com/javaTypes"
                   expressionLanguage="http://www.mvel.org/2.0"
                   xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd"
                   xmlns:g="http://www.jboss.org/drools/flow/gpd"
                   xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
                   xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"
                   xmlns:di="http://www.omg.org/spec/DD/20100524/DI"
                   xmlns:tns="http://www.jboss.org/drools">
      
      
        <itemDefinition id="_valueItem" structureRef="String" />
        <itemDefinition id="_ticketItem" structureRef="com.accenture.quickstarts.jbpm.demo.Ticket" />
        <itemDefinition id="_ticketAckItem" structureRef="com.accenture.quickstarts.jbpm.demo.TicketAck" />
      
      
        <process processType="Private" isExecutable="true" id="MonitorService" name="Monitor Service" tns:packageName="com.accenture.quickstarts.jbpm.demo" >
      
      
          <extensionElements>
           <tns:import name="java.util.Random" />
          </extensionElements>
          <!-- process variables -->
          <property id="value" itemSubjectRef="_valueItem"/>
          <property id="ticket" itemSubjectRef="_ticketItem"/>
          <property id="ticketAck" itemSubjectRef="_ticketAckItem"/>
      
      
          <!-- nodes -->
          <task id="_17" name="translate service" tns:taskName="SwitchYard Service" >
            <ioSpecification>
              <dataInput id="_17_ticketInput" name="ticket" />
              <dataInput id="_17_ServiceNameInput" name="ServiceName" />
              <dataInput id="_17_ServiceOperationNameInput" name="ServiceOperationName" />
              <inputSet>
                <dataInputRefs>_17_ticketInput</dataInputRefs>
                <dataInputRefs>_17_ServiceNameInput</dataInputRefs>
                <dataInputRefs>_17_ServiceOperationNameInput</dataInputRefs>
              </inputSet>
              <outputSet>
              </outputSet>
            </ioSpecification>
            <dataInputAssociation>
              <sourceRef>ticket</sourceRef>
              <targetRef>_17_ticketInput</targetRef>
            </dataInputAssociation>
            <dataInputAssociation>
              <targetRef>_17_ServiceNameInput</targetRef>
              <assignment>
                <from xsi:type="tFormalExpression">MonitorManagementService</from>
                <to xsi:type="tFormalExpression">_17_ServiceNameInput</to>
              </assignment>
            </dataInputAssociation>
            <dataInputAssociation>
              <targetRef>_17_ServiceOperationNameInput</targetRef>
              <assignment>
                <from xsi:type="tFormalExpression">translate</from>
                <to xsi:type="tFormalExpression">_17_ServiceOperationNameInput</to>
              </assignment>
            </dataInputAssociation>
          </task>
          <task id="_16" name="Save Data To DB" tns:taskName="SwitchYard Service" >
            <ioSpecification>
              <dataInput id="_16_ticketInput" name="ticket" />
              <dataInput id="_16_ServiceNameInput" name="ServiceName" />
              <dataInput id="_16_ServiceOperationNameInput" name="ServiceOperationName" />
              <inputSet>
                <dataInputRefs>_16_ticketInput</dataInputRefs>
                <dataInputRefs>_16_ServiceNameInput</dataInputRefs>
                <dataInputRefs>_16_ServiceOperationNameInput</dataInputRefs>
              </inputSet>
              <outputSet>
              </outputSet>
            </ioSpecification>
            <dataInputAssociation>
              <sourceRef>ticket</sourceRef>
              <targetRef>_16_ticketInput</targetRef>
            </dataInputAssociation>
            <dataInputAssociation>
              <targetRef>_16_ServiceNameInput</targetRef>
              <assignment>
                <from xsi:type="tFormalExpression">MonitorManagementService</from>
                <to xsi:type="tFormalExpression">_16_ServiceNameInput</to>
              </assignment>
            </dataInputAssociation>
            <dataInputAssociation>
              <targetRef>_16_ServiceOperationNameInput</targetRef>
              <assignment>
                <from xsi:type="tFormalExpression">saveDataToDB</from>
                <to xsi:type="tFormalExpression">_16_ServiceOperationNameInput</to>
              </assignment>
            </dataInputAssociation>
          </task>
          <startEvent id="_1" name="StartProcess" />
          <task id="_4" name="Monitor File" tns:taskName="SwitchYard Service" >
            <ioSpecification>
              <dataInput id="_4_valueInput" name="value" />
              <dataInput id="_4_ServiceNameInput" name="ServiceName" />
              <dataInput id="_4_ServiceOperationNameInput" name="ServiceOperationName" />
              <dataOutput id="_4_ticketOutput" name="ticket" />
              <inputSet>
                <dataInputRefs>_4_valueInput</dataInputRefs>
                <dataInputRefs>_4_ServiceNameInput</dataInputRefs>
                <dataInputRefs>_4_ServiceOperationNameInput</dataInputRefs>
              </inputSet>
              <outputSet>
                <dataOutputRefs>_4_ticketOutput</dataOutputRefs>
              </outputSet>
            </ioSpecification>
            <dataInputAssociation>
              <sourceRef>value</sourceRef>
              <targetRef>_4_valueInput</targetRef>
            </dataInputAssociation>
            <dataInputAssociation>
              <targetRef>_4_ServiceNameInput</targetRef>
              <assignment>
                <from xsi:type="tFormalExpression">MonitorManagementService</from>
                <to xsi:type="tFormalExpression">_4_ServiceNameInput</to>
              </assignment>
            </dataInputAssociation>
            <dataInputAssociation>
              <targetRef>_4_ServiceOperationNameInput</targetRef>
              <assignment>
                <from xsi:type="tFormalExpression">monitorFile</from>
                <to xsi:type="tFormalExpression">_4_ServiceOperationNameInput</to>
              </assignment>
            </dataInputAssociation>
            <dataOutputAssociation>
              <sourceRef>_4_ticketOutput</sourceRef>
              <targetRef>ticket</targetRef>
            </dataOutputAssociation>
          </task>
          <task id="_5" name="Remove from db" tns:taskName="SwitchYard Service" >
            <ioSpecification>
              <dataInput id="_5_ticketInput" name="ticket" />
              <dataInput id="_5_ServiceNameInput" name="ServiceName" />
              <dataInput id="_5_ServiceOperationNameInput" name="ServiceOperationName" />
              <inputSet>
                <dataInputRefs>_5_ticketInput</dataInputRefs>
                <dataInputRefs>_5_ServiceNameInput</dataInputRefs>
                <dataInputRefs>_5_ServiceOperationNameInput</dataInputRefs>
              </inputSet>
              <outputSet>
              </outputSet>
            </ioSpecification>
            <dataInputAssociation>
              <sourceRef>ticket</sourceRef>
              <targetRef>_5_ticketInput</targetRef>
            </dataInputAssociation>
            <dataInputAssociation>
              <targetRef>_5_ServiceNameInput</targetRef>
              <assignment>
                <from xsi:type="tFormalExpression">MonitorManagementService</from>
                <to xsi:type="tFormalExpression">_5_ServiceNameInput</to>
              </assignment>
            </dataInputAssociation>
            <dataInputAssociation>
              <targetRef>_5_ServiceOperationNameInput</targetRef>
              <assignment>
                <from xsi:type="tFormalExpression">reject</from>
                <to xsi:type="tFormalExpression">_5_ServiceOperationNameInput</to>
              </assignment>
            </dataInputAssociation>
          </task>
          <endEvent id="_6" name="End" >
              <terminateEventDefinition/>
          </endEvent>
          <userTask id="_10" name="Check Data From DB" >
            <extensionElements>
              <tns:onExit-script>
                <script></script>
              </tns:onExit-script>
            </extensionElements>
            <ioSpecification>
              <dataInput id="_10_ticketInput" name="ticket" />
              <dataInput id="_10_SkippableInput" name="Skippable" />
              <dataInput id="_10_TaskNameInput" name="TaskName" />
              <dataInput id="_10_GroupIdInput" name="GroupId" />
              <dataOutput id="_10_ticketOutput" name="ticket" />
              <inputSet>
                <dataInputRefs>_10_ticketInput</dataInputRefs>
                <dataInputRefs>_10_SkippableInput</dataInputRefs>
                <dataInputRefs>_10_TaskNameInput</dataInputRefs>
                <dataInputRefs>_10_GroupIdInput</dataInputRefs>
              </inputSet>
              <outputSet>
                <dataOutputRefs>_10_ticketOutput</dataOutputRefs>
              </outputSet>
            </ioSpecification>
            <dataInputAssociation>
              <sourceRef>ticket</sourceRef>
              <targetRef>_10_ticketInput</targetRef>
            </dataInputAssociation>
            <dataInputAssociation>
              <targetRef>_10_SkippableInput</targetRef>
              <assignment>
                <from xsi:type="tFormalExpression">false</from>
                <to xsi:type="tFormalExpression">_10_SkippableInput</to>
              </assignment>
            </dataInputAssociation>
            <dataInputAssociation>
              <targetRef>_10_TaskNameInput</targetRef>
              <assignment>
                <from xsi:type="tFormalExpression">ReviewTicket</from>
                <to xsi:type="tFormalExpression">_10_TaskNameInput</to>
              </assignment>
            </dataInputAssociation>
            <dataInputAssociation>
              <targetRef>_10_GroupIdInput</targetRef>
              <assignment>
                <from xsi:type="tFormalExpression">developers</from>
                <to xsi:type="tFormalExpression">_10_GroupIdInput</to>
              </assignment>
            </dataInputAssociation>
            <dataOutputAssociation>
              <sourceRef>_10_ticketOutput</sourceRef>
              <targetRef>ticket</targetRef>
            </dataOutputAssociation>
            <potentialOwner>
              <resourceAssignmentExpression>
                <formalExpression></formalExpression>
              </resourceAssignmentExpression>
            </potentialOwner>
          </userTask>
          <exclusiveGateway id="_11" name="Gateway" gatewayDirection="Diverging" />
          <task id="_12" name="Send to queue" tns:taskName="SwitchYard Service" >
            <ioSpecification>
              <dataInput id="_12_ticketInput" name="ticket" />
              <dataInput id="_12_ServiceNameInput" name="ServiceName" />
              <dataInput id="_12_ServiceOperationNameInput" name="ServiceOperationName" />
              <inputSet>
                <dataInputRefs>_12_ticketInput</dataInputRefs>
                <dataInputRefs>_12_ServiceNameInput</dataInputRefs>
                <dataInputRefs>_12_ServiceOperationNameInput</dataInputRefs>
              </inputSet>
              <outputSet>
              </outputSet>
            </ioSpecification>
            <dataInputAssociation>
              <sourceRef>ticket</sourceRef>
              <targetRef>_12_ticketInput</targetRef>
            </dataInputAssociation>
            <dataInputAssociation>
              <targetRef>_12_ServiceNameInput</targetRef>
              <assignment>
                <from xsi:type="tFormalExpression">MonitorManagementService</from>
                <to xsi:type="tFormalExpression">_12_ServiceNameInput</to>
              </assignment>
            </dataInputAssociation>
            <dataInputAssociation>
              <targetRef>_12_ServiceOperationNameInput</targetRef>
              <assignment>
                <from xsi:type="tFormalExpression">aprove</from>
                <to xsi:type="tFormalExpression">_12_ServiceOperationNameInput</to>
              </assignment>
            </dataInputAssociation>
          </task>
          <endEvent id="_15" name="End" >
              <terminateEventDefinition/>
          </endEvent>
      
      
          <!-- connections -->
          <sequenceFlow id="_4-_17" sourceRef="_4" targetRef="_17" />
          <sequenceFlow id="_17-_16" sourceRef="_17" targetRef="_16" />
          <sequenceFlow id="_1-_4" sourceRef="_1" targetRef="_4" />
          <sequenceFlow id="_11-_5" sourceRef="_11" targetRef="_5" name="reject" tns:priority="1" >
            <conditionExpression xsi:type="tFormalExpression" language="http://www.java.com/java" >return ticket.getStatus().equals("rejected");</conditionExpression>
          </sequenceFlow>
          <sequenceFlow id="_5-_6" sourceRef="_5" targetRef="_6" />
          <sequenceFlow id="_16-_10" sourceRef="_16" targetRef="_10" />
          <sequenceFlow id="_10-_11" sourceRef="_10" targetRef="_11" />
          <sequenceFlow id="_11-_12" sourceRef="_11" targetRef="_12" name="approve" tns:priority="1" >
            <conditionExpression xsi:type="tFormalExpression" language="http://www.java.com/java" >return ticket.getStatus().equals("approved");</conditionExpression>
          </sequenceFlow>
          <sequenceFlow id="_12-_15" sourceRef="_12" targetRef="_15" />
      
      
        </process>
      
      
        <bpmndi:BPMNDiagram>
          <bpmndi:BPMNPlane bpmnElement="MonitorService" >
            <bpmndi:BPMNShape bpmnElement="_17" >
              <dc:Bounds x="156" y="111" width="138" height="48" />
            </bpmndi:BPMNShape>
            <bpmndi:BPMNShape bpmnElement="_16" >
              <dc:Bounds x="163" y="196" width="133" height="48" />
            </bpmndi:BPMNShape>
            <bpmndi:BPMNShape bpmnElement="_1" >
              <dc:Bounds x="0" y="0" width="48" height="48" />
            </bpmndi:BPMNShape>
            <bpmndi:BPMNShape bpmnElement="_4" >
              <dc:Bounds x="169" y="29" width="100" height="48" />
            </bpmndi:BPMNShape>
            <bpmndi:BPMNShape bpmnElement="_5" >
              <dc:Bounds x="308" y="464" width="120" height="48" />
            </bpmndi:BPMNShape>
            <bpmndi:BPMNShape bpmnElement="_6" >
              <dc:Bounds x="347" y="572" width="48" height="48" />
            </bpmndi:BPMNShape>
            <bpmndi:BPMNShape bpmnElement="_10" >
              <dc:Bounds x="153" y="289" width="156" height="48" />
            </bpmndi:BPMNShape>
            <bpmndi:BPMNShape bpmnElement="_11" >
              <dc:Bounds x="210" y="388" width="48" height="48" />
            </bpmndi:BPMNShape>
            <bpmndi:BPMNShape bpmnElement="_12" >
              <dc:Bounds x="54" y="458" width="113" height="48" />
            </bpmndi:BPMNShape>
            <bpmndi:BPMNShape bpmnElement="_15" >
              <dc:Bounds x="89" y="563" width="48" height="48" />
            </bpmndi:BPMNShape>
            <bpmndi:BPMNEdge bpmnElement="_4-_17" >
              <di:waypoint x="219" y="53" />
              <di:waypoint x="225" y="135" />
            </bpmndi:BPMNEdge>
            <bpmndi:BPMNEdge bpmnElement="_17-_16" >
              <di:waypoint x="225" y="135" />
              <di:waypoint x="229" y="220" />
            </bpmndi:BPMNEdge>
            <bpmndi:BPMNEdge bpmnElement="_1-_4" >
              <di:waypoint x="24" y="24" />
              <di:waypoint x="219" y="53" />
            </bpmndi:BPMNEdge>
            <bpmndi:BPMNEdge bpmnElement="_11-_5" >
              <di:waypoint x="234" y="412" />
              <di:waypoint x="368" y="488" />
            </bpmndi:BPMNEdge>
            <bpmndi:BPMNEdge bpmnElement="_5-_6" >
              <di:waypoint x="368" y="488" />
              <di:waypoint x="371" y="596" />
            </bpmndi:BPMNEdge>
            <bpmndi:BPMNEdge bpmnElement="_16-_10" >
              <di:waypoint x="229" y="220" />
              <di:waypoint x="231" y="313" />
            </bpmndi:BPMNEdge>
            <bpmndi:BPMNEdge bpmnElement="_10-_11" >
              <di:waypoint x="231" y="313" />
              <di:waypoint x="234" y="412" />
            </bpmndi:BPMNEdge>
            <bpmndi:BPMNEdge bpmnElement="_11-_12" >
              <di:waypoint x="234" y="412" />
              <di:waypoint x="110" y="482" />
            </bpmndi:BPMNEdge>
            <bpmndi:BPMNEdge bpmnElement="_12-_15" >
              <di:waypoint x="110" y="482" />
              <di:waypoint x="113" y="587" />
            </bpmndi:BPMNEdge>
          </bpmndi:BPMNPlane>
        </bpmndi:BPMNDiagram>
      
      
      </definitions>
      
      

       

      MonitorService

      public interface MonitorService {
                public Ticket greet(String value);
      }
      
      

       

      MonitorServiceProcess

      @Process(
          value=MonitorService.class,
          messageContentInName="value",
          messageContentOutName="ticket",
          taskHandlers={CommandBasedWSHumanTaskHandler.class})
      public interface MonitorServiceProcess {}
      
      

       

      MonitorManagementService

      public interface  MonitorManagementService {
                public Ticket monitorFile(String value);
      
          public void saveDataToDB(Ticket ticket);
      
      
          public void aprove(Ticket ticket);
      
      
          public void reject(Ticket ticket);
      
      
          public void sendToQueue(Ticket ticket);
      
          public void removeFromDB(Ticket ticket);
      
          public void translate(Ticket ticket);
      
      
      }
      
      

       

      MonitorManagementServiceImpl

       

      @Service(MonitorManagementService.class)
      public class MonitorManagementServiceImpl implements MonitorManagementService {
      
      
                private static final Logger LOGGER = Logger.getLogger(MonitorManagementServiceImpl.class);
                @Override
                public void saveDataToDB(Ticket ticket) {
      //                    LOGGER.info("------------------------------" + ticket.getId());
                          LOGGER.info("saveDataToDB ticket");
                             ticket.setStatus("saveDataToDB");
      //                    return ticket;
                }
      
      
                @Override
                public void aprove(Ticket ticket) {
                          LOGGER.info("aprove ticket");
                             ticket.setStatus("aprove");
                }
      
      
                @Override
                public void reject(Ticket ticket) {
                          LOGGER.info("reject ticket");
              ticket.setStatus("reject");
                }
      
      
                @Override
                public void sendToQueue(Ticket ticket) {
                          LOGGER.info("sendToQueue ticket");
                             ticket.setStatus("sendToQueue");
                }
      
      
                @Override
                public void removeFromDB(Ticket ticket) {
                          LOGGER.info("removeFromDB ticket");
                          ticket.setStatus("removeFromDB");
                }
      
      
                @Override
                public Ticket monitorFile(String value) {
      //                    value = " monitorFile" + value;
                          Ticket ticket = new Ticket();
                          LOGGER.info("monitorFile "+ value);
                          ticket.setStatus("monitorFile");
                          return ticket;
                }
      
      
                @Override
                public void translate(Ticket ticket) {
                          LOGGER.info("translate ticket");
                             ticket.setStatus("translate");
                }
      
      
      }
      
      

       

       

      when i start to test this project, it always throws NullPointerException at file MonitorManagementServiceImpl(function "translate" and "saveDataToDB")

      but at the database's table task i still will hava a record like below

      Capture1.JPG

      i know the problem is there is no instance with ticket, what should i do?

        • 1. Re: NullPointerException with BPM
          kcbabo

          Hey,

           

          Which version of SwitchYard are you using?  Also, can you post the stack trace you're getting around the NPE?

           

          If you don't mind sharing, attaching your application project would be good.  Or if you don't want to do that, attaching target/classes/META-INF/switchyard.xml from your project would be helpful.

           

          ~ keith

          • 2. Re: NullPointerException with BPM
            shen_haisheng

            hi keith:

                 i am still use version 0.4, i just upload my project.

                 ps: create file with name "test.txt" at "D:\test\target" can trigger this program.

            • 3. Re: NullPointerException with BPM
              dward

              Robbie,

               

              I've looked into this a bit today.  First off, I've updated your project to work with SwitchYard 0.5.0-SNAPHOT.  I'm attaching it as "switchyard-quickstart-jbpm-demo-0.5.zip".  If you grep through *all* the files, look for instances of "DWARD" in the comments of the code (java, xml or bpmn), and you'll see what I've done to accomplish this.

               

              In your process, your "Monitor File" node occurs first, which creates the ticket from the value.  Then, "translate service" happens.  I put in an entry-action on "translate service", and I do see the ticket there - not null.  However, when "translate service" executes your

              MonitorManagementService, the ticket is null.  This leads me to believe their MIGHT be a bug in SwitchYardServiceTaskHandler.  The reason your example is different than anything we've exercised so far is that in all cases so far, the parameters that the SwitchYardServiceTaskHandler used came in through the Exchange and transformed.  However, in your case, your parameter comes as a RESULT of your preceding execution of SwitchYardServiceTaskHandler.  Thus, I'm guessing there's a disconnect there someplace.

               

              I hafta attend to something else now, but will look at this either later tonight or first thing tomorrow morning. Something tells me a jira will come out of this, so thank you.

               

              To run my upated version of your quickstart, you will have to:

              1) rebuild using the rest of the 0.5.0-SNAPSHOT stuff, including release to deploy into.

              2) start your task server via "mvn exec:java -Dexec.args="start.taskserver" (NOT your old junit test harness)

              3) You will want to update your eclipse bpmn2 plugin to the one referenced in the most recent jBPM 5.3.0.Final docs before opening up my newer version of MonitorService.bpmn.

               

               

              David

              1 of 1 people found this helpful
              • 4. Re: NullPointerException with BPM
                shen_haisheng

                hi David

                     thank you so much! i just download your project, and will give you a reponse after i through all the detail of this project.

                    

                     thank you again.

                • 5. Re: NullPointerException with BPM
                  dward

                  Okay Robbie,

                   

                  I figured out what the problem was, and it turns out nothing in SwitchYard needs to be fixed.  Please see my updated attachment, "switchyard-quickstart-jbpm-demo-0.5b.zip".

                   

                  Here's what was going on, and what I did to get it all to work:

                  1. Remember that only ONE instance of SwitchYardServiceHandler exists for the entire BPM process.  This is not a "strange" thing, since it is "The Way" jBPM does Task Handlers.  In fact, it's exactly how they implement their HumanTaskHandler too.
                  2. Given that, the messageContentInName is going to be the same for every step in your process.
                  3. Given THAT, it the handler is always going to look for the message content to be under a parameter called "value".  It's not going to be the ticket the way you had your process defined.
                  4. So..... What I did was call messageContentInName="value" and messageContentOutName="value", and in the BPMN2 file, define the item as java.lang.Object (not com.accenture......Ticket and not String).  Thus, "value" is an overloaded variable which means the payload, whatever it is at any particular node in your process.
                  5. The reason we overload it is because for your first node, you assume the value to be a String, but then from then on you assume it to be a Ticket. Thus, we type it to java.lang.Object so the variable can hold either.

                   

                  I would say look through my updated version of your bpmn file to see what I mean.  Given the latest changes, I was able to run your entire example application through with no NPE's or any other errors.  I was even able to execute the human task part in my web browser, and see the process complete.

                   

                  Hope this helps,

                  David

                  • 6. Re: NullPointerException with BPM
                    dward

                    Oh, and I changed the gatway logic in the process so it looks at the details of the ticket to determine which way to branch. In the web app, fill in the ticket details with "approved" for it to go that path, otherwise anything else goes to "rejected". Change this behavior as you see fit.