I've encountered a NPE in TruthMaintananceSystem:304 on retractions of
tracked facts (because getLogicalDependencies() returns null).
I hunted it down to DefaultKnowledgeHelper::setActivation() method. A
comment there says that this was added to resolve the JBRULES-2558
bug.
My attempt to fix it is attached - instead of removing the list of
logical dependencies, I instead track re-additions and then remove
everything else.
diff --git a/prj/sd-server/src/main/java/org/drools/base/DefaultKnowledgeHelper.java b/prj/sd-server/src/main/java/org/drools/base/DefaultKnowledgeHelper.java
index dc0eaac..0192840 100644
--- a/prj/sd-server/src/main/java/org/drools/base/DefaultKnowledgeHelper.java
+++ b/prj/sd-server/src/main/java/org/drools/base/DefaultKnowledgeHelper.java
@@ -22,6 +22,7 @@ import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.Collections;
import java.util.IdentityHashMap;
+import java.util.Iterator;
import java.util.Map;
import org.drools.FactException;
@@ -31,6 +32,7 @@ import org.drools.common.InternalFactHandle;
import org.drools.common.InternalRuleFlowGroup;
import org.drools.common.InternalWorkingMemoryActions;
import org.drools.common.InternalWorkingMemoryEntryPoint;
+import org.drools.common.TruthMaintenanceSystem;
import org.drools.impl.StatefulKnowledgeSessionImpl;
import org.drools.reteoo.ReteooWorkingMemory;
import org.drools.rule.Declaration;
@@ -66,7 +68,7 @@ public class DefaultKnowledgeHelper
private IdentityHashMap<Object, FactHandle> identityMap;
- private LinkedList previousJustified;
+ private IdentityHashMap<Object, FactHandle> reasserted;
public DefaultKnowledgeHelper() {
@@ -77,6 +79,7 @@ public class DefaultKnowledgeHelper
this.identityMap = new IdentityHashMap<Object, FactHandle>();
+ this.reasserted = new IdentityHashMap<Object, FactHandle>();
}
public void readExternal(ObjectInput in) throws IOException,
@@ -87,6 +90,7 @@ public class DefaultKnowledgeHelper
tuple = (Tuple) in.readObject();
workingMemory = (InternalWorkingMemoryActions) in.readObject();
identityMap = (IdentityHashMap<Object, FactHandle>) in.readObject();
+ reasserted = (IdentityHashMap<Object, FactHandle>) in.readObject();
}
public void writeExternal(ObjectOutput out) throws IOException {
@@ -96,6 +100,7 @@ public class DefaultKnowledgeHelper
out.writeObject( tuple );
out.writeObject( workingMemory );
out.writeObject( identityMap );
+ out.writeObject( reasserted );
}
public void setActivation(final Activation agendaItem) {
@@ -103,8 +108,9 @@ public class DefaultKnowledgeHelper
this.subrule = agendaItem.getSubRule();
this.activation = agendaItem;
// -- JBRULES-2558: logical inserts must be properly preserved
- this.previousJustified = agendaItem.getLogicalDependencies();
- agendaItem.setLogicalDependencies( null );
+ //Ha. This hack doesn't work in case of recursive retractions.
+ //this.previousJustified = agendaItem.getLogicalDependencies();
+ //agendaItem.setLogicalDependencies( null );
// -- JBRULES-2558: end
this.tuple = agendaItem.getTuple();
}
@@ -115,7 +121,7 @@ public class DefaultKnowledgeHelper
this.activation = null;
this.tuple = null;
this.identityMap.clear();
- this.previousJustified = null;
+ this.reasserted.clear();
}
public void insert(final Object object) throws FactException {
@@ -132,6 +138,7 @@ public class DefaultKnowledgeHelper
this.activation );
this.getIdentityMap().put( object,
handle );
+ this.reasserted.put(object, handle);
}
public void insertLogical(final Object object) throws FactException {
@@ -141,39 +148,31 @@ public class DefaultKnowledgeHelper
public void insertLogical(final Object object,
final boolean dynamic) throws FactException {
- // iterate to find previous equal logical insertion
- LogicalDependency dep = null;
- if ( this.previousJustified != null ) {
- for ( dep = (LogicalDependency) this.previousJustified.getFirst(); dep != null; dep = (LogicalDependency) dep.getNext() ) {
- if ( object.equals( ((InternalFactHandle) dep.getFactHandle()).getObject() ) ) {
- this.previousJustified.remove( dep );
- break;
- }
- }
- }
+ FactHandle handle = this.workingMemory.insert( object,
+ dynamic,
+ true,
+ this.rule,
+ this.activation );
- if ( dep != null ) {
- // Add the previous matching logical dependency back into the list
- this.activation.addLogicalDependency( dep );
- } else {
- // no previous matching logical dependency, so create a new one
- FactHandle handle = this.workingMemory.insert( object,
- dynamic,
- true,
- this.rule,
- this.activation );
-
- this.getIdentityMap().put( object,
- handle );
- }
+ this.getIdentityMap().put( object,
+ handle );
+
+ this.reasserted.put(object, handle);
}
public void cancelRemainingPreviousLogicalDependencies() {
- if ( this.previousJustified != null ) {
- for ( LogicalDependency dep = (LogicalDependency) this.previousJustified.getFirst(); dep != null; dep = (LogicalDependency) dep.getNext() ) {
- this.workingMemory.getTruthMaintenanceSystem().removeLogicalDependency( activation, dep, activation.getPropagationContext() );
- }
- }
+ // iterate to find previous equal logical insertion
+ final LinkedList previousJustified=this.activation.getLogicalDependencies();
+ final TruthMaintenanceSystem tms=this.workingMemory.getTruthMaintenanceSystem();
+ if ( previousJustified != null ) {
+ for (Iterator iter = previousJustified.javaUtilIterator(); iter.hasNext();) {
+ LogicalDependency dep =(LogicalDependency) iter.next();
+ final Object obj=((InternalFactHandle) dep.getFactHandle()).getObject();
+ if (!reasserted.containsKey(obj))
+ tms.removeLogicalDependency( activation, dep, activation.getPropagationContext() );
+
+ }
+ }
}
public void update(final FactHandle handle,
_______________________________________________
rules-dev mailing list
[email protected]
https://lists.jboss.org/mailman/listinfo/rules-dev