]
Thomas Diesler updated JBPM-1169:
---------------------------------
Assignee: (was: Tom Baeyens)
NPE in org.jbpm.graph.node.Decision.execute() when using transitions
with null conditions migrated from JBPM 3.0
----------------------------------------------------------------------------------------------------------------
Key: JBPM-1169
URL:
http://jira.jboss.com/jira/browse/JBPM-1169
Project: JBoss jBPM
Issue Type: Bug
Components: Core Engine
Affects Versions: jBPM jPDL 3.2.2
Environment: win2000, JBPM 3.2.2, Jboss 4.2.2, Eclipse Europa 3.3
Reporter: Julien Kronegg
Original Estimate: 6 weeks
Remaining Estimate: 6 weeks
A NullPointerException is raised by
org.jbpm.graph.node.Decision.execute(ExecutionContext) if the table
JBPM_DECISIONCONDITIONS row has null EXPRESSION_ field.
The following conditions must meet:
1) initially, the user has a JBPM database in version 3.0 and a decision with conditional
transitions
2) one of the conditional condition is cleared, which leads to setting the field
EXPRESSION_ to null in the database
3) the JBPM database migrated from 3.0 schema to version 3.2
Note: the JBPM 3.2 database is (almost?) the same as the version 3.1, so the bug should
also occur in version 3.1 (not tested).
The exception is:
Exception in thread "main" org.jbpm.graph.def.DelegationException
at org.jbpm.graph.def.GraphElement.raiseException(GraphElement.java:387)
at org.jbpm.graph.def.GraphElement.raiseException(GraphElement.java:378)
at org.jbpm.graph.node.Decision.execute(Decision.java:148)
at org.jbpm.graph.def.Node.enter(Node.java:319)
at org.jbpm.graph.def.Transition.take(Transition.java:151)
at org.jbpm.graph.def.Node.leave(Node.java:394)
at org.jbpm.graph.node.StartState.leave(StartState.java:70)
at org.jbpm.graph.exe.Token.signal(Token.java:195)
at org.jbpm.graph.exe.Token.signal(Token.java:140)
at org.jbpm.graph.exe.ProcessInstance.signal(ProcessInstance.java:271)
at com.sample.TestDecisionNPE.main(TestDecisionNPE.java:53)
Caused by: java.lang.NullPointerException
at
org.jbpm.jpdl.el.impl.JbpmExpressionEvaluator.translateExpressionToDollars(JbpmExpressionEvaluator.java:52)
at
org.jbpm.jpdl.el.impl.JbpmExpressionEvaluator.evaluate(JbpmExpressionEvaluator.java:38)
at
org.jbpm.jpdl.el.impl.JbpmExpressionEvaluator.evaluate(JbpmExpressionEvaluator.java:30)
at org.jbpm.graph.node.Decision.execute(Decision.java:110)
... 8 more
This bug can be tested using the following test case:
package com.sample;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import org.jbpm.graph.def.ProcessDefinition;
import org.jbpm.graph.def.Transition;
import org.jbpm.graph.exe.ProcessInstance;
import org.jbpm.graph.node.Decision;
import org.jbpm.graph.node.DecisionCondition;
public class TestDecisionNPE {
public static final void main(String[] args) throws SecurityException,
NoSuchFieldException, IllegalArgumentException, IllegalAccessException{
ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(
"<process-definition>" +
" <start-state>" +
" <transition to='d' />" +
" </start-state>" +
" <decision name='d'>" +
" <transition name='one' to='a'>" +
" <condition>#{a == 1}</condition>" +
" </transition>" +
" <transition name='two' to='b'>" +
" <condition>#{a == 2}</condition>" +
" </transition>" +
" <transition name='three' to='c'>" +
" <condition>#{a == 3}</condition>" +
" </transition>" +
" </decision>" +
" <state name='a' />" +
" <state name='b' />" +
" <state name='c' />" +
"</process-definition>");
// start-state.
ProcessInstance processInstance = new ProcessInstance(processDefinition);
// Update a transition decision condition as if it was on the old format
// by setting the condition to null (i.e. no condition).
// Build a decisionConditions list (emulates an old database from
// JBPM 3.0, obsolete JBPM_DECISIONCONDITION table).
List decision_conditions = new ArrayList();
decision_conditions.add(new DecisionCondition("one", null));
Decision decision = (Decision) processDefinition.getNode("d");
Field field =
decision.getClass().getDeclaredField("decisionConditions");
field.setAccessible(true);
field.set(decision, decision_conditions);
// fire the transition (as we have an old decision condition set,
org.jbpm.graph.node.Decision#execute will raise a NullPointerException).
processInstance.signal();
}
}
The bug can be corrected using the following code in the execute() method (added lines
ends with "JK") :
// backwards compatible mode based on separate DecisionCondition's
Iterator iter = decisionConditions.iterator();
while (iter.hasNext() && (transition==null)) {
DecisionCondition decisionCondition = (DecisionCondition) iter.next();
if (decisionCondition.expression!=null) {//JK
Object result =
JbpmExpressionEvaluator.evaluate(decisionCondition.getExpression(), executionContext);
if (Boolean.TRUE.equals(result)) {
if (transition!=null) {
transition.removeConditionEnforcement();
}
String transitionName = decisionCondition.getTransitionName();
transition = getLeavingTransition(transitionName);
}
} else {//JK
String transitionName = decisionCondition.getTransitionName();//JK
transition = getLeavingTransition(transitionName);//JK
}//JK
Note that the JBPM 3.0.4 version had this check against null values.
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: