Community

NullPointerException when timeout transition maps to a Java activity

reply from Sameeh Harfoush in jBPM - View the full discussion

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");
    }
}

Reply to this message by going to Community

Start a new discussion in jBPM at Community