4 Replies Latest reply on Mar 31, 2010 4:49 AM by sameeh.harfoush

    NullPointerException when timeout transition maps to a Java activity

    sameeh.harfoush

      Hello,
      Below is a section of a workflow I am working on
      When triggering the timer the transition “Manager timeout” goes to  the java activity “Send timesheet to accounts” and executes the “manageTimesheet” method which only executes System.out to the console. All goes well but I always get the below null pointer exception.
      I tried mapping the transition to other than java task it works fine. The problem is in my implantation or the jpdl Timer?

       

      Thanks

       

              <task g="105,159,156,52" name="Manager reviews timesheet">
                  <assignment-handler>
                      <field name="assignee">
                          <string value="Mahmoud" />
                      </field>
                  </assignment-handler>

       


                  <transition g="433,186;435,673:-43,-16" name="Manager timeout"  to="Send timesheet to accounts">
                      <timer duedate="1 hour" />
                  </transition>
                  <transition g="-68,-18" name="Manager decision" to="Manager evaluation" />
              </task>
              <decision g="159,267,48,48" name="Manager evaluation">
                  <handler />
                  <transition g="-93,-11" name="Approve" to="Send timesheet to accounts" />
                  <transition g="348,292;352,673:-82,-206" name="Reject" to="Employee submits timesheet" />
              </decision>
              <java g="102,356,163,52"
                  method="manageTimesheet" name="Send timesheet to accounts">
                  <transition g="-83,-8" name="to Bookkeeper"    to="Bookkeeper reviews and posts timesheet" />
              </java>
             
             
      ### EXCEPTION ###########################################
      10:25:51,983 SEV   | [ExecuteJobCmd] exception while executing 'timer[550012|2010-03-30 11:25:51,000|Manager timeout]'
      java.lang.NullPointerException
          at org.jbpm.pvm.internal.wire.usercode.UserCodeReference.getProcessDefinition(UserCodeReference.java:75)
          at org.jbpm.pvm.internal.wire.usercode.UserCodeReference.getObject(UserCodeReference.java:60)
          at org.jbpm.pvm.internal.wire.usercode.UserCodeReference.getObject(UserCodeReference.java:51)
          at org.jbpm.pvm.internal.model.ExecutionImpl.initializeAssignments(ExecutionImpl.java:759)
          at org.jbpm.jpdl.internal.activity.TaskActivity.execute(TaskActivity.java:95)
          at org.jbpm.jpdl.internal.activity.TaskActivity.execute(TaskActivity.java:58)
          at org.jbpm.pvm.internal.model.op.ExecuteActivity.perform(ExecuteActivity.java:60)
          at org.jbpm.pvm.internal.model.ExecutionImpl.performAtomicOperationSync(ExecutionImpl.java:656)
          at org.jbpm.pvm.internal.model.ExecutionImpl.performAtomicOperation(ExecutionImpl.java:616)
          at org.jbpm.pvm.internal.model.op.TransitionEndActivity.perform(TransitionEndActivity.java:58)
          at org.jbpm.pvm.internal.model.ExecutionImpl.performAtomicOperationSync(ExecutionImpl.java:656)
          at org.jbpm.pvm.internal.model.ExecutionImpl.performAtomicOperation(ExecutionImpl.java:616)
          at org.jbpm.pvm.internal.model.ExecutionImpl.signal(ExecutionImpl.java:417)
          at org.jbpm.pvm.internal.model.ExecutionImpl.signal(ExecutionImpl.java:403)
          at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
          at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
          at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
          at java.lang.reflect.Method.invoke(Unknown Source)
          at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:197)
          at org.jbpm.pvm.internal.model.ExecutionImpl_$$_javassist_5.signal(ExecutionImpl_$$_javassist_5.java)
          at org.jbpm.pvm.internal.job.TimerImpl.execute(TimerImpl.java:91)
          at org.jbpm.pvm.internal.job.TimerImpl.execute(TimerImpl.java:52)
          at org.jbpm.pvm.internal.cmd.ExecuteJobCmd.execute(ExecuteJobCmd.java:76)
          at org.jbpm.pvm.internal.cmd.ExecuteJobCmd.execute(ExecuteJobCmd.java:42)
          at org.jbpm.pvm.internal.svc.DefaultCommandService.execute(DefaultCommandService.java:42)
          at org.jbpm.pvm.internal.tx.StandardTransactionInterceptor.execute(StandardTransactionInterceptor.java:54)
          at org.jbpm.pvm.internal.svc.EnvironmentInterceptor.executeInNewEnvironment(EnvironmentInterceptor.java:53)
          at org.jbpm.pvm.internal.svc.EnvironmentInterceptor.execute(EnvironmentInterceptor.java:40)
          at org.jbpm.pvm.internal.svc.RetryInterceptor.execute(RetryInterceptor.java:55)
          at org.jbpm.pvm.internal.svc.SkipInterceptor.execute(SkipInterceptor.java:43)
          at org.jbpm.pvm.internal.svc.ManagementServiceImpl.executeJob(ManagementServiceImpl.java:37)
          at com.roxana.test.jpdl.EmployeeTimesheetTest.testEmployeeTimesheetWorkflow(EmployeeTimesheetTest.java:52)
          at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
          at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
          at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
          at java.lang.reflect.Method.invoke(Unknown Source)
          at junit.framework.TestCase.runTest(TestCase.java:164)
          at org.jbpm.test.BaseJbpmTestCase.runTest(BaseJbpmTestCase.java:80)
          at junit.framework.TestCase.runBare(TestCase.java:130)
          at junit.framework.TestResult$1.protect(TestResult.java:106)
          at junit.framework.TestResult.runProtected(TestResult.java:124)
          at junit.framework.TestResult.run(TestResult.java:109)
          at junit.framework.TestCase.run(TestCase.java:120)
          at junit.framework.TestSuite.runTest(TestSuite.java:230)
          at junit.framework.TestSuite.run(TestSuite.java:225)
          at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:130)
          at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
          at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
          at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
          at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
          at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)     

        • 1. Re: NullPointerException when timeout transition maps to a Java activity
          swiderski.maciej

          Hi,

          seems like your java activity is missing class attribute, that could be the reason of the exception.

           

          HTH

          Maciej

          • 2. Re: NullPointerException when timeout transition maps to a Java activity
            sameeh.harfoush

            sorry, a copy mistake

            here is my java activity

             

                 <java g="102,356,163,52" class="com.roxana.test.jpdl.TimesheetManager"
                        method="manageTimesheet" name="Send timesheet to accounts">
                        <transition g="-83,-8" name="to Bookkeeper" to="Bookkeeper reviews and posts timesheet" />
                    </java>

            • 3. Re: NullPointerException when timeout transition maps to a Java activity
              swiderski.maciej

              could you poast complete process definition (jpdl) with a unit test? That could help a bit to investigate.

               

              /Maciej

              • 4. Re: NullPointerException when timeout transition maps to a Java activity
                sameeh.harfoush

                Hello
                I tried to eliminate the timer and made the <decision> transition maps to a java activity in order to see if the problem is with the Timer timeout trigger.
                After executing the workflow and when the decision handler returns "Approve" the java activity gets executed and throws a NullPointerException (see below). But when I replace the java activity with a <state> the java activity gets executed and no exception is thrown.

                 

                Below is all the data you asked for.

                Regards

                 

                Exception:
                ### EXCEPTION ###########################################
                11:26:47,828 INF   | [DefaultCommandService] exception while executing command org.jbpm.pvm.internal.cmd.CompleteTaskCmd@1f52460
                java.lang.NullPointerException
                    at org.jbpm.pvm.internal.wire.usercode.UserCodeReference.getProcessDefinition(UserCodeReference.java:75)
                    at org.jbpm.pvm.internal.wire.usercode.UserCodeReference.getObject(UserCodeReference.java:60)
                    at org.jbpm.pvm.internal.wire.usercode.UserCodeReference.getObject(UserCodeReference.java:51)
                    at org.jbpm.pvm.internal.model.ExecutionImpl.initializeAssignments(ExecutionImpl.java:759)
                    at org.jbpm.jpdl.internal.activity.TaskActivity.execute(TaskActivity.java:95)
                    at org.jbpm.jpdl.internal.activity.TaskActivity.execute(TaskActivity.java:58)
                    at org.jbpm.pvm.internal.model.op.ExecuteActivity.perform(ExecuteActivity.java:60)
                    at org.jbpm.pvm.internal.model.ExecutionImpl.performAtomicOperationSync(ExecutionImpl.java:656)
                    at org.jbpm.pvm.internal.model.ExecutionImpl.performAtomicOperation(ExecutionImpl.java:616)
                    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
                    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
                    at java.lang.reflect.Method.invoke(Unknown Source)
                    at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:197)
                    at org.jbpm.pvm.internal.model.ExecutionImpl_$$_javassist_5.performAtomicOperation(ExecutionImpl_$$_javassist_5.java)
                    at org.jbpm.pvm.internal.model.op.TransitionEndActivity.perform(TransitionEndActivity.java:58)
                    at org.jbpm.pvm.internal.model.ExecutionImpl.performAtomicOperationSync(ExecutionImpl.java:656)
                    at org.jbpm.pvm.internal.model.ExecutionImpl.performAtomicOperation(ExecutionImpl.java:616)
                    at org.jbpm.pvm.internal.model.ExecutionImpl.signal(ExecutionImpl.java:417)
                    at org.jbpm.pvm.internal.model.ExecutionImpl.signal(ExecutionImpl.java:403)
                    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
                    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
                    at java.lang.reflect.Method.invoke(Unknown Source)
                    at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:197)
                    at org.jbpm.pvm.internal.model.ExecutionImpl_$$_javassist_5.signal(ExecutionImpl_$$_javassist_5.java)
                    at org.jbpm.pvm.internal.task.TaskImpl.complete(TaskImpl.java:194)
                    at org.jbpm.pvm.internal.task.TaskImpl.complete(TaskImpl.java:186)
                    at org.jbpm.pvm.internal.cmd.CompleteTaskCmd.execute(CompleteTaskCmd.java:67)
                    at org.jbpm.pvm.internal.cmd.CompleteTaskCmd.execute(CompleteTaskCmd.java:32)
                    at org.jbpm.pvm.internal.svc.DefaultCommandService.execute(DefaultCommandService.java:42)
                    at org.jbpm.pvm.internal.tx.StandardTransactionInterceptor.execute(StandardTransactionInterceptor.java:54)
                    at org.jbpm.pvm.internal.svc.EnvironmentInterceptor.executeInNewEnvironment(EnvironmentInterceptor.java:53)
                    at org.jbpm.pvm.internal.svc.EnvironmentInterceptor.execute(EnvironmentInterceptor.java:40)
                    at org.jbpm.pvm.internal.svc.RetryInterceptor.execute(RetryInterceptor.java:55)
                    at org.jbpm.pvm.internal.svc.SkipInterceptor.execute(SkipInterceptor.java:43)
                    at org.jbpm.pvm.internal.svc.TaskServiceImpl.completeTask(TaskServiceImpl.java:88)
                    at com.roxana.test.jpdl.EmployeeTimesheetTest.executeTransitionInTask(EmployeeTimesheetTest.java:180)
                    at com.roxana.test.jpdl.EmployeeTimesheetTest.testManagerApproveTimesheet(EmployeeTimesheetTest.java:135)
                    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
                    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
                    at java.lang.reflect.Method.invoke(Unknown Source)
                    at junit.framework.TestCase.runTest(TestCase.java:164)
                    at org.jbpm.test.BaseJbpmTestCase.runTest(BaseJbpmTestCase.java:80)
                    at junit.framework.TestCase.runBare(TestCase.java:130)
                    at junit.framework.TestResult$1.protect(TestResult.java:106)
                    at junit.framework.TestResult.runProtected(TestResult.java:124)
                    at junit.framework.TestResult.run(TestResult.java:109)
                    at junit.framework.TestCase.run(TestCase.java:120)
                    at junit.framework.TestSuite.runTest(TestSuite.java:230)
                    at junit.framework.TestSuite.run(TestSuite.java:225)
                    at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:130)
                    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
                    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
                    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
                    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
                    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
                ### EXCEPTION ###########################################

                 

                JPDL:
                <process name="timesheetWorkflow" xmlns="http://jbpm.org/4.3/jpdl">
                    <start g="142,11,48,48" name="start">
                        <transition name="start workflow" g="-153,-18"
                            to="Employee submits timesheet" />
                    </start>
                    <task g="84,85,164,47" name="Employee submits timesheet">
                        <assignment-handler>
                            <field name="assignee">
                                <string value="sameeh" />
                            </field>
                        </assignment-handler>
                        <transition name="to group" g="-150,-18" to="manager bookkeeper group" />
                    </task>
                    <group name="manager bookkeeper group">
                        <start>
                            <transition name="to manager" to="Manager reviews timesheet" />
                        </start>
                        <task g="105,159,156,52" name="Manager reviews timesheet">
                            <assignment-handler>
                                <field name="assignee">
                                    <string value="Mahmoud" />
                                </field>
                            </assignment-handler>

                 

                            <!--timeout transition can be to other subprocess -->
                            <transition g="433,186;435,673:-43,-16" name="Manager timeout"
                                to="Manager review SLA">
                                <timer duedate="12 hours" />
                            </transition>
                            <transition g="-68,-18" to="Manager evaluation" />
                        </task>

                 

                        <sub-process name="Manager review SLA" sub-process-key="ManagerReviewSLA"
                            g="118,106,99,52">
                            <transition name="to accounts" to="Send timesheet to accounts"></transition>
                        </sub-process>

                 

                        <decision g="159,267,48,48" name="Manager evaluation">
                            <handler />
                            <transition g="-93,-11" name="Approve" to="Send timesheet to accounts" />
                            <transition g="348,292;352,673:-82,-206" name="Reject" to="Employee submits timesheet" />
                        </decision>
                               
                                <!--    
                        <state name="Send timesheet to accounts">
                          <transition g="-83,-8"    to="Bookkeeper reviews and posts timesheet" />
                        </state>
                                -->


                        <java g="102,356,163,52" class="com.roxana.test.jpdl.TimesheetManager"
                            method="manageTimesheet" name="Send timesheet to accounts">
                            <transition g="-83,-8" name="to Bookkeeper"
                                to="Bookkeeper reviews and posts timesheet" />
                        </java>


                        <task g="64,453,240,52" name="Bookkeeper reviews and posts timesheet">
                            <assignment-handler>
                                <field name="assignee">
                                    <string value="Mr.bookkeeper" />
                                </field>
                            </assignment-handler>
                            <transition name="to group end" g="-125,-3"
                                to="manager bookkeeper group end" />
                        </task>

                 

                        <end name="manager bookkeeper group end" />
                        <transition to="Accounting department pays employee" />
                               
                    </group>
                    <task g="77,567,219,52" name="Accounting department pays employee">
                        <assignment-handler>
                            <field name="assignee">
                                <string value="Mr.accountant" />
                            </field>
                        </assignment-handler>
                        <transition g="-42,-18" name="to end" to="end" />
                    </task>
                    <end g="167,651,48,48" name="end" />
                    <timer duedate="72 hours"></timer>
                </process>

                 


                JUnit
                package com.roxana.test.jpdl;

                 

                import java.util.HashMap;
                import java.util.Iterator;
                import java.util.List;
                import java.util.Map;

                 

                import org.jbpm.api.Execution;
                import org.jbpm.api.JobQuery;
                import org.jbpm.api.ProcessInstance;
                import org.jbpm.api.TaskQuery;
                import org.jbpm.api.job.Job;
                import org.jbpm.api.job.Timer;
                import org.jbpm.api.task.Task;
                import org.jbpm.test.JbpmTestCase;

                 

                public class EmployeeTimesheetTest extends JbpmTestCase {

                 

                    String deploymentId;
                    String ManagerSlaDeploymentId;

                 

                    protected void setUp() throws Exception {
                        super.setUp();
                        deploymentId = repositoryService
                                .createDeployment()
                                .addResourceFromClasspath(
                                        "com/roxana/test/jpdl/EmployeeTimesheetWorkflow.jpdl.xml")
                                .deploy();

                 

                        ManagerSlaDeploymentId = repositoryService.createDeployment()
                                .addResourceFromClasspath(
                                        "com/roxana/test/jpdl/ManagerReviewSLA.jpdl.xml")
                                .deploy();

                 

                    }

                 

                    protected void tearDown() throws Exception {
                        repositoryService.deleteDeploymentCascade(deploymentId);
                        repositoryService.deleteDeploymentCascade(ManagerSlaDeploymentId);
                        super.tearDown();
                    }

                 

                    public void testManagerApproveTimesheet() {

                 

                        Map<String, Object> variableMap = new HashMap();
                        // variableMap.put("action", "reject");
                        variableMap.put("action", "approve");

                 

                        ProcessInstance processInstance = executionService
                                .startProcessInstanceByKey("timesheetWorkflow", variableMap);

                 

                        String processInstanceId = processInstance.getId();

                 

                        executeTransitionInTask(processInstance.getId(),
                                "Employee submits timesheet", null);// employee

                 

                        executeTransitionInTask(processInstance.getId(),
                                "Manager reviews timesheet", null);// manager
                    }

                 

                    private void executeTimerInTask(ProcessInstance pi, String transitionName) {
                        List<Job> jobslist = managementService.createJobQuery().timers()
                                .processInstanceId(pi.getId()).list();
                        Job job2 = null;
                        for (Iterator<Job> i = jobslist.iterator(); i.hasNext();) {
                            job2 = i.next();
                            // System.out.println("****"+((Timer)job2).getSignalName());
                            if (((Timer) job2).getSignalName().trim().equals(transitionName))
                                managementService.executeJob(job2.getId());
                        }
                    }

                 

                    private void executeTransitionInTask(String piId, String taskName,
                            String transitionName) {

                 

                        ProcessInstance pi = executionService.findProcessInstanceById(piId);

                 

                        if (transitionName != null) {
                            executeTimerInTask(pi, transitionName);
                        } else {
                            TaskQuery taskQuery = taskService.createTaskQuery();
                            List<Task> allTasks = taskQuery.list();
                            Task task = null;
                            for (Iterator<Task> i = allTasks.iterator(); i.hasNext();) {
                                task = i.next();
                                if (task.getActivityName().trim().equals(taskName))
                                    break;
                            }
                            if (task != null) {
                                System.out.println("task.getId() = "
                                        + taskService.getOutcomes(task.getId()));
                                taskService.completeTask(task.getId());
                            }

                 

                        }
                    }
                }

                TimesheetManager.java:

                 

                package com.roxana.test.jpdl;

                 

                import java.io.Serializable;

                 

                public class TimesheetManager implements Serializable {

                 

                    public void manageTimesheet(){
                        System.out.println("timesheet sent to accounting");
                    }
                }