cancel
Showing results for 
Search instead for 
Did you mean: 

can't access to bpm_package childrens in a ExecutionListener

jpmerlin
Champ in-the-making
Champ in-the-making
Hi,

I'm with Alfresco community 4.2.c and activiti 5.10-alf.20121114.

I have a problem when i want to access to bpm_package content in a executionListener.
I've got a NPE on org.alfresco.repo.jscript.ScriptNode.getChildren() function.
I have not this problem with a taskListener.

Here is a simple process for test :


<?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" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="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="myProcess" name="My process" isExecutable="true">
    <startEvent id="startevent1" name="Start"></startEvent>
    <endEvent id="endevent1" name="End"></endEvent>
    <sequenceFlow id="flow1" sourceRef="startevent1" targetRef="endevent1">
      <extensionElements>
        <activiti:executionListener event="take" class="fr.rsi.whi.bpm.taskListener.TestExecutionListener"></activiti:executionListener>
      </extensionElements>
    </sequenceFlow>
  </process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_myProcess">
    <bpmndi:BPMNPlane bpmnElement="myProcess" id="BPMNPlane_myProcess">
      <bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
        <omgdc:Bounds height="35.0" width="35.0" x="80.0" y="150.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
        <omgdc:Bounds height="35.0" width="35.0" x="220.0" y="150.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
        <omgdi:waypoint x="115.0" y="167.0"></omgdi:waypoint>
        <omgdi:waypoint x="220.0" y="167.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>


Here is my ExecutionListener :


public class TestExecutionListener implements ExecutionListener {
   
   private static Log logger = LogFactory.getLog(TestExecutionListener.class);
   
   @Override
   public void notify(DelegateExecution execution) throws Exception {
      ActivitiScriptNode  bpm_package = (ActivitiScriptNode) execution.getVariable("bpm_package");
      if (bpm_package == null){
         logger.error("le bpm_package is null");
      } else {
      Scriptable childrens = bpm_package.getChildren();
      if (childrens == null){
         logger.error(" bpm_package.getChildren() is null");
      }else {
         
         ScriptNode firstChild = (ScriptNode) childrens.get(0, null);
      
         String noderef = firstChild.getStoreType()+"://"+firstChild.getStoreId()+"/"+firstChild.getId();
         logger.error("Noderef first child : " + noderef);
      }

   }

   }
}


Here is the stacktrace :


Caused by: java.lang.NullPointerException
        at org.mozilla.javascript.ScriptableObject.getTopLevelScope(ScriptableObject.java:1483)
        at org.mozilla.javascript.ScriptRuntime.setObjectProtoAndParent(ScriptRuntime.java:3106)
        at org.mozilla.javascript.Context.newArray(Context.java:1547)
        at org.alfresco.repo.jscript.ScriptNode.getChildren(ScriptNode.java:439)
        at fr.rsi.whi.bpm.taskListener.TestExecutionListener.notify(TestExecutionListener.java:21)


2 REPLIES 2

afaust
Legendary Innovator
Legendary Innovator
Hello,

this is a result of you working with (Activiti)ScriptNode outside of a Rhino/JavaScript context. All operations in (Activiti)ScriptNode require a runtime context to be set, which Alfresco automatically does when you use a script-based listener. When you want to access (Activiti)ScriptNode manually from Java, you need to wrap the entire code block in a try-finally construct and do
Context.enter();
before the block and
Context.exit();
within the finally block. You also need to perform a
bpmPackage.setScope(scope);
call where
scope
is an object you obtain via
Context.initStandardObjects();
.

Of course, it would be far simpler to either just use a script-based listener or extract the NodeRef via
bpmPackage.getNodeRef();
and use regular NodeService etc. instead of ScriptNode API (
getNodeRef()
does not require a Rhino/JavaScript context).

Regards
Axel

jpmerlin
Champ in-the-making
Champ in-the-making
Thank you for your response !
I use the second method with NodeService and bmpPackage.getNodeRef().
What suprise me is that it works fine with a java TaskListener, the context is not initialize the same way in a TaskListener than in a ExecutionListener.

here is the code of the ExecutionListener :

public class TestExecutionListener implements ExecutionListener {
   
   private static Log logger = LogFactory.getLog(TestExecutionListener.class);
   
   
   @Override
   public void notify(DelegateExecution execution) throws Exception {
      
      
      ActivitiScriptNode  bpm_package = (ActivitiScriptNode) execution.getVariable("bpm_package");
      if (bpm_package == null){
         logger.error("le bpm_package est null");
      } else {
         NodeRef packageNodeRef = bpm_package.getNodeRef();
         NodeService nodeService = getServiceRegistry().getNodeService();
      
      
         List<ChildAssociationRef> children = nodeService.getChildAssocs(packageNodeRef);
          for (ChildAssociationRef childAssoc : children) {
              NodeRef childNodeRef = childAssoc.getChildRef();
              logger.error("Noderef of child : " + childNodeRef.getStoreRef().getProtocol()+"://"+childNodeRef.getStoreRef().getIdentifier()+"/"+childNodeRef.getId());
          }
      
      }

   }


   
   protected ServiceRegistry getServiceRegistry() {

        ProcessEngineConfigurationImpl config = Context.getProcessEngineConfiguration();

        if (config != null) {

            // Fetch the registry that is injected in the activiti spring-configuration
            ServiceRegistry registry = (ServiceRegistry) config.getBeans().get(ActivitiConstants.SERVICE_REGISTRY_BEAN_KEY);

            if (registry == null) {

                throw new RuntimeException(

                            "Service-registry not present in ProcessEngineConfiguration beans, expected ServiceRegistry with key" +     ActivitiConstants.SERVICE_REGISTRY_BEAN_KEY);
            }
            return registry;
        }

        throw new IllegalStateException("No ProcessEngineCOnfiguration found in active context");

    }
}


thank you.

Jean-Paul
Getting started

Tags


Find what you came for

We want to make your experience in Hyland Connect as valuable as possible, so we put together some helpful links.