JBoss Community

[jBPM4.4] custom activity has an end time before this activity is leaveds the activity

created by saig0 in jBPM - View the full discussion

Hi,

 

I note that a custom activity has an end time before this activity is leaved.

 

process:

 

<?xml version="1.0" encoding="UTF-8"?>


<process name="HistoryServiceTest" xmlns="http://jbpm.org/4.4/jpdl">
          <start name="start" g="77,144,48,48">
                    <transition to="custom-state" />
          </start>
          <custom name="custom-state" g="175,140,105,52" class="processes.classes.SimpleCustomState">
                    <transition to="end" />
          </custom>
          <end name="end" g="324,144,48,48" />
</process>

 

SimpleCustomState.java:

 

package processes.classes; 
 
import java.util.Map; 
import org.jbpm.api.activity.ActivityExecution;
import org.jbpm.api.activity.ExternalActivityBehaviour; 
 
public class SimpleCustomState implements ExternalActivityBehaviour
{
    private static final long serialVersionUID = 1L;
 
    public void execute(ActivityExecution execution) throws Exception    {
        execution.waitForSignal();
    }
 
    public void signal(ActivityExecution execution, String signalName, Map<String, ?> parameters)
            throws Exception    {
        execution.takeDefaultTransition();
    }
 
}
 

 

test:

 

package services; 
 
import org.junit.Assert.*;
import java.util.Date;
import java.util.List;
import java.util.zip.ZipInputStream;  
import org.jbpm.api.*;
import org.junit.*; 
 
public class HistoryServiceTest
{ 
    private HistoryService    historyService;
    private ExecutionService  executionService;
    private RepositoryService repositoryService;
 
    @Before
    public void setup()    {
        initEngine();
        deployProcess();
    }
 
    public void initEngine()    {
        ProcessEngine processEngine = new Configuration().setResource("default.jbpm.cfg.xml")
                .buildProcessEngine();
        executionService = processEngine.getExecutionService();
        historyService = processEngine.getHistoryService();
        repositoryService = processEngine.getRepositoryService();
    }
 
    public void deployProcess()    {
        ZipInputStream zipInputStream = new ZipInputStream(getClass().getResourceAsStream("/jbpm.zip"));
        repositoryService.createDeployment().addResourcesFromZipInputStream(zipInputStream).setName("test")
                .setTimestamp(new Date().getTime()).deploy();
    }
 
    public String startProcess()    {
        ProcessInstance processInstance = executionService.startProcessInstanceByKey("HistoryServiceTest");
        return processInstance.getId();
    }
 
    private boolean isRunning(String processInstanceId)    {
        ProcessInstance pi = executionService.findProcessInstanceById(processInstanceId);
        return pi != null ? pi.isEnded() : false;
    }
 
    @Test
    public void testHasEndDateForEndedCustomActivity()    {
        String processInstanceId = startProcess();
        String activityName = "custom-state";
        assertTrue(executionService.findProcessInstanceById(processInstanceId).isActive(activityName));
 
 
        executionService.signalExecutionById(processInstanceId, "");
        assertFalse(isRunning(processInstanceId));
 
 
        HistoryActivityInstance historyActivityInstance = historyService.createHistoryActivityInstanceQuery()
                .processInstanceId(processInstanceId).activityName(activityName).uniqueResult();
        assertNotNull(historyActivityInstance.getEndTime());
    }
 
    @Test
    public void testHasNoEndDateForActiveCustomActivity()    {
        String processInstanceId = startProcess();
        String activityName = "custom-state";
        assertTrue(executionService.findProcessInstanceById(processInstanceId).isActive(activityName));
 
 
        List<HistoryActivityInstance> historyActivityInstances = historyService
                .createHistoryActivityInstanceQuery().processInstanceId(processInstanceId)
                .activityName(activityName).list();
        if (!historyActivityInstances.isEmpty())
        {
            for (HistoryActivityInstance historyActivityInstance : historyActivityInstances)
                assertNull(historyActivityInstance.getEndTime()); // this fail!
        }
    }
}

 

After I looking for a reason, I found something in class UserCodeActivityBehaviour:

 

public void execute(ActivityExecution execution) throws Exception {
    ActivityBehaviour activityBehaviour = (ActivityBehaviour) customActivityReference.getObject(execution);
    activityBehaviour.execute(execution);
    ((ExecutionImpl)execution).historyAutomatic();
  }

 

This methode create a object of class HistoryActivityInstanceImpl and call:

 

public HistoryAutomaticInstanceImpl(HistoryProcessInstance historyProcessInstanceImpl, ExecutionImpl execution) {
    super(historyProcessInstanceImpl, execution);
    setEndTime(Clock.getTime());
  }

 

Now I want to ask why this was not implemented like in class StateActivity?

And how to fix this bug?

Reply to this message by going to Community

Start a new discussion in jBPM at Community