[JBoss JIRA] Created: (JBRULES-2335) StackOverflowError on serialization of KnowledgeBase
by Justin Waugh (JIRA)
StackOverflowError on serialization of KnowledgeBase
----------------------------------------------------
Key: JBRULES-2335
URL: https://jira.jboss.org/jira/browse/JBRULES-2335
Project: Drools
Issue Type: Bug
Security Level: Public (Everyone can see)
Components: drools-core
Affects Versions: 5.0.1.FINAL
Environment: Windows, JDK 1.6
Reporter: Justin Waugh
Assignee: Mark Proctor
This is a bit of a duplicate of another issue, which I will link, however I only tested against 5.0.1 and I have a proposed solution which I believe is only applicable to 5.0.1 +
The problem is of course, that when serializing a KnowledgeBase with a very large amount of rules, it can potentially cause a StackOverflowError on serialization. As far as I can tell this is due to the linked lists held by ObjectSinkNodeList and LeftTupleSinkNodeList. The problem is that they recursively serialize the list, by serializing the first node, which serializes its next node, which serializes its next node.... and so on. This was a bit harder to solve in the 4.0+ case I think as it relied purely on the built in java serialization. However in 5.0+ those classes all use write/readExternal to do their own serialization. That makes it a bit easier to solve, as we can now implement an iterative serialization for the lists.
The problem code looks like this:
ObjectSinkNodeList (also applies to LeftTupleSinkNodeList):
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
firstNode = (ObjectSinkNode) in.readObject();
lastNode = (ObjectSinkNode) in.readObject();
size = in.readInt();
}
public void writeExternal(ObjectOutput out) throws IOException {
out.writeObject( firstNode );
out.writeObject( lastNode );
out.writeInt( size );
}
AlphaNode (and all others implementing ObjectSinkNode, and similarly LeftTupleSinkNode):
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
super.readExternal( in );
constraint = (AlphaNodeFieldConstraint) in.readObject();
previousRightTupleSinkNode = (ObjectSinkNode) in.readObject();
nextRightTupleSinkNode = (ObjectSinkNode) in.readObject();
}
public void writeExternal(ObjectOutput out) throws IOException {
super.writeExternal( out );
out.writeObject( constraint );
out.writeObject( previousRightTupleSinkNode );
out.writeObject( nextRightTupleSinkNode );
}
As you can see it recursively serializes the list, so the stack depth increases linearly with the list length.
The solution is this:
ObjectSinkNodeList (also applies to LeftTupleSinkNodeList):
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
firstNode = (ObjectSinkNode) in.readObject();
lastNode = (ObjectSinkNode) in.readObject();
size = in.readInt();
ObjectSinkNode current = firstNode;
while(current != null)
{
ObjectSinkNode previous = (ObjectSinkNode) in.readObject();
ObjectSinkNode next = (ObjectSinkNode) in.readObject();
current.setPreviousObjectSinkNode(previous);
current.setNextObjectSinkNode(next);
current = next;
}
}
public void writeExternal(ObjectOutput out) throws IOException {
out.writeObject( firstNode );
out.writeObject( lastNode );
out.writeInt( size );
for (ObjectSinkNode node = firstNode; node != null; node = node.getNextObjectSinkNode())
{
out.writeObject(node.getPreviousObjectSinkNode());
out.writeObject(node.getNextObjectSinkNode());
}
}
AlphaNode (and all others implementing ObjectSinkNode, and similarly LeftTupleSinkNode):
public void writeExternal(ObjectOutput out) throws IOException {
super.writeExternal( out );
out.writeObject( constraint );
}
public AlphaNodeFieldConstraint getConstraint() {
return this.constraint;
}
As you can see the responsibility for serializing the list node links is now placed into the list objects themselves, and is performed iteratively. I suppose technically the lastNode reference of the list doesn't need to be stored separately, but it was just easier code.
The obvious concern here is if for some reason you had linked nodes which were not held by one of the list objects, then the links would be lost. However I checked references to the get/set of the prev/next, and they were only referenced by the list objects themselves, so I believe there is no chance for that to happen.
I'll attach a test case (but it's just the one from the linked ticket)
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: https://jira.jboss.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
13 years, 5 months
[JBoss JIRA] Created: (JBRULES-2278) NPE after knowledgebase updated when using entrypoints
by Michael Neale (JIRA)
NPE after knowledgebase updated when using entrypoints
------------------------------------------------------
Key: JBRULES-2278
URL: https://jira.jboss.org/jira/browse/JBRULES-2278
Project: Drools
Issue Type: Bug
Security Level: Public (Everyone can see)
Components: drools-core, drools-core (expert), drools-core (fusion)
Affects Versions: 5.0.1.FINAL
Reporter: Michael Neale
Assignee: Edson Tirelli
Fix For: 5.1.0.M1
Raised by Nestor Burriel on the dev list:
I've tried to configure my rule engine obtaining unexpected behaviour.
I configure my statefulSession as follows:
wm = (ReteooStatefulSession) ((KnowledgeBaseImpl) kagent
.getKnowledgeBase()).ruleBase.newStatefulSession(
(SessionConfiguration) sessionConf, env);
ksession = new StatefulKnowledgeSessionImpl(wm, kagent.getKnowledgeBase());
And after updating the KnowledgeBase in the agent I update my ksession:
wm.setRuleBase((InternalRuleBase) ((KnowledgeBaseImpl) kagent
.getKnowledgeBase()).ruleBase);
ksession = new StatefulKnowledgeSessionImpl(wm, kagent.getKnowledgeBase());
Without using entry-points this approach works as expected, but using them
it fails after the first update throwing the error:
Exception while processing message: java.lang.NullPointerException
java.lang.NullPointerException
at
org.drools.reteoo.ReteooFactHandleFactory.newFactHandle(ReteooFactHandleFactory.java:54)
at
org.drools.common.AbstractFactHandleFactory.newFactHandle(AbstractFactHandleFactory.java:79)
at
org.drools.common.AbstractFactHandleFactory.newFactHandle(AbstractFactHandleFactory.java:66)
at
org.drools.common.NamedEntryPoint.insert(NamedEntryPoint.java:109)
at org.drools.common.NamedEntryPoint.insert(NamedEntryPoint.java:80)
at org.drools.common.NamedEntryPoint.insert(NamedEntryPoint.java:28)
Browsing the drools core code I found the line that was throwing the
exception and tried to get the same result by implementing:
if (!((InternalRuleBase) ((KnowledgeBaseImpl)
ksession.getKnowledgeBase()).ruleBase)
.getTypeDeclaration(fact.getClass()) ==
null)
log.info (((InternalRuleBase) ((KnowledgeBaseImpl)
ksession.getKnowledgeBase()).ruleBase)
.getTypeDeclaration(fact.getClass()).getTimestampExtractor().toString());
after updating my ksession. The result was the same, again the same
exception thrown but my logger wrote:
18:01:50,232 INFO [ClassFieldExtractor class=MyPackage.MyFact
field=myTimestampField]
So I dont know why the core is throwing that exception, is that
implementation correct?, any ideas?
Thanks,
Nestor
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: https://jira.jboss.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
13 years, 5 months
[JBoss JIRA] Created: (JBRULES-2274) Rule does not fire as expected using deep object model and nested 'or' clause
by Brian DeCamp (JIRA)
Rule does not fire as expected using deep object model and nested 'or' clause
-----------------------------------------------------------------------------
Key: JBRULES-2274
URL: https://jira.jboss.org/jira/browse/JBRULES-2274
Project: Drools
Issue Type: Bug
Security Level: Public (Everyone can see)
Components: drools-core (expert)
Affects Versions: 5.0.1.FINAL
Environment: Windows NT with JBoss 4.2.2GA using the 5.0.1 jars for core, compiler and api.
Reporter: Brian DeCamp
Assignee: Mark Proctor
When combining deep facts and nested 'or' statements, rules do not fire. I've reduced the problem as much as possible with the following example:
------- begin test.drl --------
rule "find one and two with 'or' clause - WORKS"
when
com.xyz.SimpleFact(name == "one");
(eval(true) or eval(true));
com.xyz.SimpleFact(name == "two");
then
System.out.println("found one and two with 'or' clause");
end
rule "Deep one and two without 'or' - WORKS"
when
d1: com.xyz.DeepFact();
com.xyz.SimpleFact(name=="one") from d1.simple;
d2: com.xyz.DeepFact();
com.xyz.SimpleFact(name=="two") from d2.simple;
then
System.out.println("Found deep facts with simple facts one and two without 'or' clause");
end
rule "Deep one and two with nested 'or' - FAILURE!!!"
when
d1: com.xyz.DeepFact();
com.xyz.SimpleFact(name=="one") from d1.simple;
(eval(true) or eval(true));
d2: com.xyz.DeepFact();
com.xyz.SimpleFact(name=="two") from d2.simple;
then
System.out.println("THIS DOES NOT FIRE");
end
-------end test.drl --------
------- begin DeepFact.java --------
package com.xyz;
public class DeepFact {
private SimpleFact simple;
public SimpleFact getSimple() {
return simple;
}
public void setSimple(SimpleFact simple) {
this.simple = simple;
}
}
------- end DeepFact.java --------
------- begin SimpleFact.java --------
package com.xyz;
public class SimpleFact {
private String name;
public SimpleFact() {}
public SimpleFact(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
------- end SimpleFact.java --------
------- begin test code-------
public void testRules() {
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
org.drools.io.Resource ruleResource;
try {
ruleResource = ResourceFactory.newInputStreamResource(new FileInputStream("test.drl"));
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
kbuilder.add(ruleResource, ResourceType.DRL);
if ( kbuilder.hasErrors() ) {
System.err.println( kbuilder.getErrors().toString() );
}
Collection<KnowledgePackage> compiledPackages = kbuilder.getKnowledgePackages();
KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
kbase.addKnowledgePackages(compiledPackages);
StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
// Insert facts
ksession.insert(new SimpleFact("one"));
ksession.insert(new SimpleFact("two"));
DeepFact d1 = new DeepFact();
d1.setSimple(new SimpleFact("one"));
ksession.insert(d1);
DeepFact d2 = new DeepFact();
d2.setSimple(new SimpleFact("two"));
ksession.insert(d2);
ksession.fireAllRules();
ksession.dispose();
}
------- end test code --------
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: https://jira.jboss.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
13 years, 5 months
[JBoss JIRA] Created: (JBRULES-1457) please support containment test for map keys
by Godmar Back (JIRA)
please support containment test for map keys
--------------------------------------------
Key: JBRULES-1457
URL: http://jira.jboss.com/jira/browse/JBRULES-1457
Project: JBoss Drools
Issue Type: Feature Request
Security Level: Public (Everyone can see)
Components: Drl Parser/Builder
Affects Versions: 4.0.4
Environment: any
Reporter: Godmar Back
Using MVEL as the language for clauses, there is no way to test whether a map's key contain a value.
For instance:
rule "number 1"
when
e : S(map.keySet() contains "x")
then
System.out.println("rule number 1");
end
leads to a syntax error because Drool's parser does not allow function calls ("keySet())" in clauses.
On the other hand, MVEL (according to Mike Brocks, please read http://jira.codehaus.org/browse/MVEL-53 ) does not provide an operator to test containment in a map's set (or values). He said he's considering adding a shortcut such as .keys and .values in 2.0 and recommended I open a Drools JIRA issue.
Please provide a way to test for membership in a map's key and value set.
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://jira.jboss.com/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
13 years, 5 months
[JBoss JIRA] Created: (JBRULES-2404) "not contains" operator doesn't work on inner fields
by Taras Svirskyi (JIRA)
"not contains" operator doesn't work on inner fields
-----------------------------------------------------
Key: JBRULES-2404
URL: https://jira.jboss.org/jira/browse/JBRULES-2404
Project: Drools
Issue Type: Bug
Security Level: Public (Everyone can see)
Components: drools-compiler
Reporter: Taras Svirskyi
Assignee: Mark Proctor
Consider following example.
There are nodes that are connected into directed graph. Each node has
special collection of attributes. Under some conditions attributes
should be propagated along the edges in the graph.
Lets model this with following code.
/******* propagation rules **********************/
package com.test.collection;
rule "move child"
when
c : Child()
s : CNode( children contains c)
l : Link( src == s,
t : target && target.children not contains c )
then
System.out.println("adding "+c+" from "+s+" to "+t);
t.addChild(c);
update(t);
end
/** Child.java (represent special attributes of a node) *******/
package com.test.collection;
public class Child {
private String name;
public Child(String name){
this.name = name;
}
public String getName() {
return name;
}
@Override
public String toString() {
return "child("+name+")";
}
}
/********* CNode.java - nodes of a graph *************/
package com.test.collection;
import java.util.HashSet;
import java.util.Set;
public class CNode {
private Set<Child> children;
public CNode() {
this.children = new HashSet<Child>();
}
public Set<Child> getChildren() {
return children;
}
public void addChild(Child ch){
children.add(ch);
}
@Override
public String toString() {
return "Node{children="+children+"}";
}
}
/**** Link.java - edges of a graph *******/
package com.test.collection;
public class Link {
private CNode src;
private CNode target;
public Link(CNode src, CNode target) {
this.src = src;
this.target = target;
}
public CNode getSrc() {
return src;
}
public CNode getTarget() {
return target;
}
}
/********************* populate session with facts **********/
Child c0 = new Child("x");
Child c1 = new Child("y");
Child c2 = new Child("z");
CNode src = new CNode();
src.addChild(c0);
src.addChild(c1);
CNode target = new CNode();
target.addChild(c0);
Link link = new Link(src,target);
// populate with facts
ksession.insert(c0);
ksession.insert(c1);
ksession.insert(c2);
ksession.insert(link);
ksession.insert(src);
ksession.insert(target);
/****************************************************************/
So with all that code listed above I've got following output from rules:
--
adding child(x) from Node{children=[child(x), child(y)]} to
Node{children=[child(x)]}
--
That means that 'not contains' operator actually works as 'contains'
one. Still when I changed it to older operator 'excludes' everything
goes right printing out.
---
adding child(y) from Node{children=[child(y), child(x)]} to
Node{children=[child(x)]}
---
I've noticed that rewriting rule in form of simple statements also fix
issue.
rule "move child"
when
c : Child()
s : CNode( children contains c)
t : CNode( children not contains c )
l : Link( src == s, target == t)
then
System.out.println("adding "+c+" from "+s+" to "+t);
t.addChild(c);
update(t);
end
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: https://jira.jboss.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
13 years, 5 months
[JBoss JIRA] Created: (EJBTHREE-1870) stopDelivery on active MDB results in exception (Session not found)
by Philip Dodds (JIRA)
stopDelivery on active MDB results in exception (Session not found)
-------------------------------------------------------------------
Key: EJBTHREE-1870
URL: https://jira.jboss.org/jira/browse/EJBTHREE-1870
Project: EJB 3.0
Issue Type: Bug
Components: ejb3
Affects Versions: 1.1.3
Environment: Mac OS/X Leopard, JDK 6, JBoss 5.1.0GA
Reporter: Philip Dodds
Attachments: stopdelivery-mdb.zip
If you start an MDB and introduce a messages to it then use the stopDelivery method of the MDB's MBean to stop it consuming messages you get an exception. Note this problem only occurs if the MDB has a transaction in flight when the stopDelivery is called.
2009-05-20 12:30:52,499 ERROR [org.jboss.messaging.util.ExceptionUtil] (WorkManager(2)-44) Connectio
nEndpoint[fe-oz919yuf-1-mj809yuf-bruz48-x21o4c5] sendTransaction [ur4-b6b39yuf-1-mj809yuf-bruz48-x21
o4c5]
javax.jms.IllegalStateException: Cannot find session with id ie-qz919yuf-1-mj809yuf-bruz48-x21o4c5
at org.jboss.jms.server.endpoint.ServerConnectionEndpoint.processTransaction(ServerConnectionEndpoi
nt.java:835)
at org.jboss.jms.server.endpoint.ServerConnectionEndpoint.sendTransaction(ServerConnectionEndpoint.
java:497)
at org.jboss.jms.server.endpoint.advised.ConnectionAdvised.org$jboss$jms$server$endpoint$advised$Co
nnectionAdvised$sendTransaction$aop(ConnectionAdvised.java:101)
at org.jboss.jms.server.endpoint.advised.ConnectionAdvised$sendTransaction_N3268650789275322226.inv
okeTarget(ConnectionAdvised$sendTransaction_N3268650789275322226.java)
I have attached a slightly doctors version of the EJB3 MDB example code, it has been changed to introduce a sleep of 5 seconds in the MDB (to keep the transaction active longer) and also introduces a higher volume of messages to give you a chance to get to the JMX console and call stopDelivery. If you don't get an exception on the first attempt it is worth trying again as the transaction must be in flight for the problem to occur.
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: https://jira.jboss.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
13 years, 5 months
[JBoss JIRA] Created: (JBRULES-2248) Drools Expert User Guide errors
by Karsten Thoms (JIRA)
Drools Expert User Guide errors
-------------------------------
Key: JBRULES-2248
URL: https://jira.jboss.org/jira/browse/JBRULES-2248
Project: Drools
Issue Type: Bug
Security Level: Public (Everyone can see)
Components: drools-docs
Affects Versions: 5.0.1.FINAL
Reporter: Karsten Thoms
Assignee: Mark Proctor
Priority: Trivial
Some minor issues I found when following the User Guide:
Improvement: Variable 'kbase' is not introduced in the first example. Add declaration and instantiation to example in 2.1.1.
Rule "Status output when things are ok"
error:
not Sprinkler( on === true )
correct:
not Sprinkler( on == true )
ERROR
if ( kbuilder.hasErrors() ) {
System.err.println( builder.getErrors().toString() );
}
CORRECT
if ( kbuilder.hasErrors() ) {
System.err.println( kbuilder.getErrors().toString() );
}
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: https://jira.jboss.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
13 years, 5 months