cancel
Showing results for 
Search instead for 
Did you mean: 

Why NullPointerException, when I use TimerBoundaryEvent?

mscai
Champ in-the-making
Champ in-the-making
I just begin to study BPMN and Activiti. I write a prototype to use TimerBoundaryEvent. But when I run the prototype, java.lang.NullPointerException throws. Could anyone help me, please?
Thank you.

The logical  of my prototype is simple. There is one ServiceTask "NormalTask1". If the duration of "NormalTask1" is larger than 10 secondes, do ServiceTask"NT_Timer". 

In my prototype, the execution duration of "NormalTask1" is more than 20 seconds, and I have set "jobExecutorActivate" as true. My activiti engine version is 5.2

Below is the xml of my workflow:
*************
<process id="Timer_Test1" name="">
    <startEvent id="startevent1" name="Start"></startEvent>
    <serviceTask id="servicetask1" name="NormalTask1" activiti:class="com.sybase.rs.wkpt.process.wfe.HWorld"></serviceTask>
    <endEvent id="endevent1" name="End"></endEvent>
    <sequenceFlow id="flow1" name="" sourceRef="startevent1" targetRef="servicetask1"></sequenceFlow>
    <boundaryEvent id="boundarytimer1" name="Timer_NT1" cancelActivity="true" attachedToRef="servicetask1">
      <timerEventDefinition>
        <timeDuration>PT10S</timeDuration>
      </timerEventDefinition>
    </boundaryEvent>
    <parallelGateway id="parallelgateway1" name="Parallel Gateway"></parallelGateway>
    <sequenceFlow id="flow3" name="" sourceRef="servicetask1" targetRef="parallelgateway1"></sequenceFlow>
    <sequenceFlow id="flow10" name="" sourceRef="parallelgateway1" targetRef="endevent1"></sequenceFlow>
    <serviceTask id="servicetask2" name="NT_Timer" activiti:class="com.sybase.rs.wkpt.process.wfe.HWorldTimer"></serviceTask>
    <sequenceFlow id="flow13" name="" sourceRef="boundarytimer1" targetRef="servicetask2"></sequenceFlow>
    <sequenceFlow id="flow14" name="" sourceRef="servicetask2" targetRef="parallelgateway1"></sequenceFlow>
  </process>
*************

When I run the prototype, the below error throws:
*****************
java.lang.NullPointerException at org.activiti.engine.impl.jobexecutor.TimerExecuteNestedActivityJobHandler.execute(TimerExecuteNestedActivityJobHandler.java:39)
   at org.activiti.engine.impl.runtime.JobEntity.execute(JobEntity.java:79)
   at org.activiti.engine.impl.runtime.TimerEntity.execute(TimerEntity.java:47)
   at org.activiti.engine.impl.cmd.ExecuteJobsCmd.execute(ExecuteJobsCmd.java:54)
   at org.activiti.engine.impl.interceptor.CommandExecutorImpl.execute(CommandExecutorImpl.java:22)
   at org.activiti.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:37)
   at org.activiti.spring.SpringTransactionInterceptor$1.doInTransaction(SpringTransactionInterceptor.java:42)
   at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:130)
   at org.activiti.spring.SpringTransactionInterceptor.execute(SpringTransactionInterceptor.java:40)
   at org.activiti.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:33)
   at org.activiti.engine.impl.jobexecutor.ExecuteJobsRunnable.run(ExecuteJobsRunnable.java:36)
   at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
   at java.lang.Thread.run(Thread.java:619)
*****************

I debug the prototype. It doesn't get the ExecutionEntity by executionId at org.activiti.engine.impl.runtime.JobEntity.execute
*************
public void execute(CommandContext commandContext) {

if (executionId != null) {
      execution = runtimeSession.findExecutionById(executionId);
    }

*************
8 REPLIES 8

jbarrez
Star Contributor
Star Contributor
How do you test this? Could it be that your service task has already run before the timer fires?

mscai
Champ in-the-making
Champ in-the-making
Hi jbarrez,

Thank you for the remind. It seems there is issue for the execution of Service Task.

My java class for this Service Task is as the below. It sleeps 200 seconds:
**************
public void doServiceTask(ActivityExecution execution) throws Exception {
  System.out.println("hello world");
  Thread.sleep(200000);
  System.out.println("Goodbye world"); 
}
**************

According to the output, the timer doesn't fire until my Service Task finishes.

I change the service task to User Task. Sleep 30 seconds when do this user task. And then timer is fired, and everything is ok.
***************
taskService.claim(yask.getId(), "mscai");
ExecutionTask( …);
    try {
     Thread.sleep(30000);
    } catch (InterruptedException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }
       try {
        taskService.complete(task.getId());
       } catch(ActivitiException e) {
  
     return;
    }
***************

mproch
Champ in-the-making
Champ in-the-making
I think that service tasks are not meant to be used in this way. They are executed in one transaction, and do not handle timers nicely. I think that this should be rather done by combination of serviceTask & receiveTask

jbarrez
Star Contributor
Star Contributor
Indeed, Maciek is right. Using a timer on a service task is something which will not work as expected. If you want to have a timer on your logic, using your own java timer in the logic call itself will work.

pmarzec
Champ in-the-making
Champ in-the-making
hello
I have the same problem when i use TimerBoundaryEvent together with UserTask.
I want to implement an escalation mail. I've checked in database that Activiti creates additional job for other execution id.
I think this is connected somehow with UserTask which is cancelled. Exception is thrown when Activiti tries to execute this additional job.
I use Activiti 5.8 on OSGi. Any idea, workaround? Maybe upgrade Activiti to 5.10 version resolve problem?.
Thanks,

jbarrez
Star Contributor
Star Contributor
Could you provide a failing unit test with process xml that demonstrates this problem?

pmarzec
Champ in-the-making
Champ in-the-making
Below I have included my example xml snippet. That is what i want achieve:
————————
<?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"
xmlnsSmiley Surprisedmgdc="http://www.omg.org/spec/DD/20100524/DC" xmlnsSmiley Surprisedmgdi="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">
  <process id="mail-group-acceptance" name="mail-group-acceptance">
    <documentation>Place documentation for the 'mail-group-acceptance' process here.</documentation>
    <startEvent id="startevent1" name="Start"></startEvent>
    <userTask id="GROUP_LEADER_ACCEPT_TASK_ID" name="Acceptance of the group leader"></userTask>
    <boundaryEvent id="boundarytimer1" name="" cancelActivity="true" attachedToRef="GROUP_LEADER_ACCEPT_TASK_ID">
      <timerEventDefinition>
        <timeCycle>0 0/30 * * * ?</timeCycle>
      </timerEventDefinition>
    </boundaryEvent>
    <endEvent id="endevent1" name="End"></endEvent>
    <serviceTask id="servicetask1" name="Mail reminder" activiti:expression="${springBean.sendMail(execution)}"></serviceTask>
    <sequenceFlow id="flow15" name="" sourceRef="startevent1" targetRef="GROUP_LEADER_ACCEPT_TASK_ID"></sequenceFlow>
    <sequenceFlow id="flow17" name="" sourceRef="GROUP_LEADER_ACCEPT_TASK_ID" targetRef="endevent1"></sequenceFlow>
    <sequenceFlow id="flow18" name="" sourceRef="boundarytimer1" targetRef="servicetask1"></sequenceFlow>
    <sequenceFlow id="flow19" name="" sourceRef="servicetask1" targetRef="GROUP_LEADER_ACCEPT_TASK_ID"></sequenceFlow>
  </process>
</definitions>
————————
and exception stacktrace:
————————
java.lang.NullPointerException
        at org.activiti.engine.impl.jobexecutor.TimerExecuteNestedActivityJobHandler.execute(TimerExecuteNestedActivityJobHandler.java:39)[217Smiley Surprisedrg.activiti.engine:5.8.0]
        at org.activiti.engine.impl.persistence.entity.JobEntity.execute(JobEntity.java:78)[217Smiley Surprisedrg.activiti.engine:5.8.0]
        at org.activiti.engine.impl.persistence.entity.TimerEntity.execute(TimerEntity.java:62)[217Smiley Surprisedrg.activiti.engine:5.8.0]
        at org.activiti.engine.impl.cmd.ExecuteJobsCmd.execute(ExecuteJobsCmd.java:61)[217Smiley Surprisedrg.activiti.engine:5.8.0]
        at org.activiti.engine.impl.interceptor.CommandExecutorImpl.execute(CommandExecutorImpl.java:24)[217Smiley Surprisedrg.activiti.engine:5.8.0]
        at org.activiti.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:42)[217Smiley Surprisedrg.activiti.engine:5.8.0]
        at org.activiti.engine.impl.interceptor.JtaTransactionInterceptor.execute(JtaTransactionInterceptor.java:59)[217Smiley Surprisedrg.activiti.engine:5.8.0]
        at org.activiti.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:33)[217Smiley Surprisedrg.activiti.engine:5.8.0]
        at org.activiti.engine.impl.jobexecutor.ExecuteJobsRunnable.run(ExecuteJobsRunnable.java:36)[217Smiley Surprisedrg.activiti.engine:5.8.0]
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)[:1.6.0_26]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)[:1.6.0_26]
        at java.lang.Thread.run(Thread.java:662)[:1.6.0_26]
———————–
Link to junit test: https://github.com/pmarzec/activiti.git
Is there any other way to modeling such a reminder?
Thanks,

jbarrez
Star Contributor
Star Contributor
First of all, thanks for the excellent unit test! I wish every post would be like that.

That being said:
-  yes, it is a bug
- But it sure is a strange use case. A cancel activity with a repeating timer. (which is no excuses for not working). The workaround would be to remove cancelActivity for the moment.

Created http://jira.codehaus.org/browse/ACT-1427