How to write rules that can skip checking some constraint (i.e. "or" inside the rule)
by Maxim Veksler
Hello List,
I'm trying to express a list of channels the subscriber is allowed to
access, this splits into 2 possible flows :
1. Subscriber has X>0 in $enabledChannels, allow passing only for
these channels.
2. Subscriber has "null" in the $enabledChannels - In that case
continue because this check is not required.
I'm trying to express this in the constraint node in like this, which
does not work
$subscriber : DynaSubscriber(
adsEnabled == true,
$optoutStr : optoutStr,
enabledChannels contains $channelId // Make sure subscriber is
"service registered" for this channel.
/*PROBLEM::::*/ or enabledChannels == null
)
I would like to be able to say, If enabledChannels is marked (In any
way you would suggest) as "empty" don't check this constraint node.
How can I do this?
I'm using Drools3, but if feasible solution is presented in the form
of Drools4, 5 please kindly let me know this information.
Thank you,
Maxim.
--
Cheers,
Maxim Veksler
"Free as in Freedom" - Do u GNU ?
15 years, 11 months
meet Operator 'Operator = 'contains'' does not exist for StringEvaluator error
by Zeke
Hi, all:
I meet a strange error when use "contains" operator on string type, My
rule is like below:
> package org.drools.examples;
>
> import org.drools.examples.HelloWorldExample.Message;
>
> rule "check str contains"
> dialect "java"
> when
> m:Message( message contains "Hello" )
> then
> System.out.println( "===check str contains ok===" );
> end
It throw below exception:
> Exception in thread "main" java.lang.RuntimeException: Operator 'Operator
> = 'contains'' does not exist for StringEvaluator
> at
> org.drools.base.evaluators.StringFactory.getEvaluator(StringFactory.java:70)
> at org.drools.base.ValueType.getEvaluator(ValueType.java:166)
> at
> org.drools.rule.builder.PatternBuilder.getEvaluator(PatternBuilder.java:900)
> at
> org.drools.rule.builder.PatternBuilder.buildRestriction(PatternBuilder.java:714)
> at
> org.drools.rule.builder.PatternBuilder.buildRestriction(PatternBuilder.java:625)
> at
> org.drools.rule.builder.PatternBuilder.createRestriction(PatternBuilder.java:434)
> at
> org.drools.rule.builder.PatternBuilder.build(PatternBuilder.java:308)
> at
> org.drools.rule.builder.PatternBuilder.buildConstraint(PatternBuilder.java:199)
> at
> org.drools.rule.builder.PatternBuilder.build(PatternBuilder.java:168)
> at org.drools.rule.builder.PatternBuilder.build(PatternBuilder.java:93)
> at
> org.drools.rule.builder.GroupElementBuilder.build(GroupElementBuilder.java:69)
> at org.drools.rule.builder.RuleBuilder.build(RuleBuilder.java:53)
> at org.drools.compiler.PackageBuilder.addRule(PackageBuilder.java:446)
> at
> org.drools.compiler.PackageBuilder.addPackage(PackageBuilder.java:304)
> at
> org.drools.compiler.PackageBuilder.addPackageFromDrl(PackageBuilder.java:167)
> at
> org.drools.examples.HelloWorldExample.main(HelloWorldExample.java:28)
>
But if I use a "deep" str field, this issue does not exist, Everything goes
well.
The drl is like below:
> package org.drools.examples;
>
> import org.drools.examples.HelloWorldExample.Message;
>
> rule "check deep str contains"
> dialect "java"
> when
> m:Message( sec.fir.msg contains "Hello" )
> then
> System.out.println( "===check deep str contains ok===" );
> end
It seems a bug, but I am not sure. I attached my test code and the two drl
files.
I use below jars to compile and run this test case:
> antlr-runtime-3.0.jar
> core-3.2.3.v_686_R32x.jar
> drools-compiler-4.0.7.jar
> drools-core-4.0.7.jar
> drools-decisiontables-4.0.7.jar
> drools-jsr94-4.0.7.jar
> janino-2.5.10.jar
> jsr94-1.1.jar
> mvel-1.3.12-java1.4.2.jar
Can everyone kindly give me any suggestion?
Thanks!
- Zeke
15 years, 11 months
"less time- and memory-consuming" usage of KnowledgeAgent - need some advice
by psentosa
Hi...
I'm trying to use KnowledgeAgent in my application; I already saw he
examples in the docs..but somehow I'm still not sure whether I've used it
correctly.
The case is that I implement a STATELESS session bean, which provides the
method that makes use of rule engine.
private KnowledgeBase kbase;
private KnowledgeAgentConfiguration aconf;
private KnowledgeAgent kagent;
public myBeansMethod(...) {
......
if (this.kbase == null) {
this.kbase = KnowledgeBaseFactory.newKnowledgeBase();
}
if (this.aconf == null) {
LOG.info("Creating new KnowledgeAgentConfigurator ...");
this.aconf = KnowledgeAgentFactory.newKnowledgeAgentConfiguration();
this.aconf.setProperty("drools.agent.scanDirectories", "true");
this.aconf.setProperty("drools.agent.newInstance", "true");
}
if (this.kagent == null) {
this.kagent = KnowledgeAgentFactory.newKnowledgeAgent("kagent",
this.kbase, this.aconf);
}
this.kagent.applyChangeSet(ResourceFactory.newFileResource(this.CHANGE_SET));
StatelessKnowledgeSession ksession =
kagent.getKnowledgeBase().newStatelessKnowledgeSession();
.........
}
My purpose is to create as few new instances as possible on calling the
method, but still get the latest version of the rules. Is this already
correct?
Is there any way to avoid rebuilding/updating the knowledge base if it is
still the very same resource the change set refering to? (not updated one)
Thanks in advance
--
View this message in context: http://www.nabble.com/%22less-time--and-memory-consuming%22-usage-of-Know...
Sent from the drools - user mailing list archive at Nabble.com.
15 years, 11 months
how to specify classpath dependencies in .drl files.
by Godmar Back
My question is how to manage a rule base that is composed from sets of
rules drawn from different sources.
Our goal is to supply sets of rules as .jar files - each .jar file
containing a related set of rules. For instance, consider an expert
system where different experts could export their expertise in such a
jar file. Such a .jar file would contain one or more .drl files and a
set of supporting .java classes. We'd like to be able to refer to
these .jar files using a URLClassLoader and/or JarURLConnection so
they can be referred to without a user having to download them prior
to starting their application.
Users should be able to combine those provided rules (that is, the
rules of those experts whose knowledge they wish to exploit) with
their own rules in their own .drl files.
My question is whether drools supports such a setup easily.
Specifically, is there a way for a user to import external .jar files
in their .drl files? A statement such as
use jar:http://expertbase.com/expert1/knowledge5.jar
which would instruct the rule compiler to load the classes from this
jar to its compile class path, and which would instruct the class
loader used to load the user's classes to delegate to the loader used
to load the jar file's classes? [Note that a given expert's knowledge
should only be loaded by one classloader.]
I browsed through the API and discovered that the package builder
configuration allows the specification of a class loader. Does this
mean the rule compiler will attempt to load related classes through
this loader as well? If so, it would need to use reflection to examine
those classes (which I'd find unlikely). If not, is there a way to
control the rule compiler's compiler classpath?
In our current prototype, we need to load everything through the
application classpath to avoid compile errors.
- Godmar
15 years, 11 months
Firing Rules in Rule Flows
by keithnielsen
I have a fairly involved rule flow consisting of rule flow groups. I am
trying to understand
if the behavior I am seeing and my understanding of it are correct.
The flow executes as exepected the first pass through, objects are inserted
and the rules associated with the different nodes are executed. On the
second pass through the flow various nodes are triggered but none of the
ruleflow groups are activated/executed. My understanding of this is as
follows:
1) The only way to have these ruleflow groups fire/execute again is to
insert objects that cause a match or to fire all rules on the session again.
2) Constraints on split/join nodes are always evaluated and don't need to be
activated which is different than the constraints on a given rule
3) Rules that don't have any constraints, i.e. they are always true will
only execute once and will only execute with a call to fire all rules
Assuming my understanding of what is going on correct I have the following
questions:
Q. My particular use case is really screen flow/business process, and it
would be nice if I came to a node, that the rule was always evaluated, i.e.
currently rules that always evaluate to true aren't fired more than once.
For instance I have a node that simply instantiates a dialog and waits for
user input and I always want to instantiate that dialog when I come to that
node, regardless of the facts. Is there a way to achieve this without firing
all rules again?
Q. Is firing all rules within a rule flow a legitimate way of achieving the
desired affect?
Shouldn't the ruleflow-group associated with a node always be evaluated if
the node is triggered? As it happens now, the rule flow gets stuck in an
infinite loop as the node contraints are conitniously evaluated but the
actual rule contraints are not. Seems inconsistent too me especially in the
context of a business process/rule flow.
Thanks
--
View this message in context: http://www.nabble.com/Firing-Rules-in-Rule-Flows-tp21489239p21489239.html
Sent from the drools - user mailing list archive at Nabble.com.
15 years, 11 months
NPE in RightTuple
by Evans, Jess
Does anyone know what this would be indicative of? I've seen it occur periodically at which point I have to discard the session. I flatten and assert my data, run the rules, and then retract the handles collected on assertion. I've ensured the fact handle parameter is never null. I have the stateful session wrapped in a synchronized business façade, so I don't think it should be a concurrency issue (unless I have a bug of course). I'm running Drools 5 M4.
java.lang.NullPointerException
at org.drools.util.RightTupleIndexHashTable.remove(RightTupleIndexHashTable.java:224)
at org.drools.reteoo.JoinNode.retractRightTuple(JoinNode.java:204)
at org.drools.reteoo.ObjectTypeNode.retractObject(ObjectTypeNode.java:210)
at org.drools.reteoo.EntryPointNode.retractObject(EntryPointNode.java:190)
at org.drools.common.AbstractWorkingMemory.retract(AbstractWorkingMemory.java:1078)
at org.drools.common.AbstractWorkingMemory.retract(AbstractWorkingMemory.java:1045)
15 years, 11 months
No ClassLoaders found for: String
by psentosa
Hallo,
I have a rule like this, defined in Guvnor:
when
Activity ( $date : date, workingTime > 240)
then
System.out.println("Working time limit has been reached");
violatedRegulation.add(new String("regulation.general.working1"));
violatedRegulation is a List<String> which I set as a global because later
on I will extract the content of that list which is a key defined in a
properties file
ksession.setGlobal("violatedRegulation", violatedRegulation);
ksession.executeObject(activity);
but then I got the following exception:
15:52:59,687 INFO [STDOUT] Working time limit has been reached
15:52:59,687 ERROR [MyExceptionInterceptor] [Error: could not create
constructor: No ClassLoaders found for: String ]
[Near : {... Unknown ....}]
^
org.drools.runtime.rule.ConsequenceException: [Error: could not create
constructor: No ClassLoaders found for: String ]
[Near : {... Unknown ....}]
^
at
org.drools.runtime.rule.impl.DefaultConsequenceExceptionHandler.handleException(DefaultConsequenceExceptionHandler.java:23)
at org.drools.common.DefaultAgenda.fireActivation(DefaultAgenda.java:918)
at org.drools.common.DefaultAgenda.fireNextItem(DefaultAgenda.java:871)
at org.drools.common.DefaultAgenda.fireAllRules(DefaultAgenda.java:1035)
at
org.drools.common.AbstractWorkingMemory.fireAllRules(AbstractWorkingMemory.java:612)
at
org.drools.common.AbstractWorkingMemory.fireAllRules(AbstractWorkingMemory.java:589)
at
org.drools.impl.StatelessKnowledgeSessionImpl.executeObject(StatelessKnowledgeSessionImpl.java:158)
..................
Caused by: [Error: could not create constructor: No ClassLoaders found for:
String ]
[Near : {... Unknown ....}]
^
at
org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.optimizeObjectCreation(ReflectiveAccessorOptimizer.java:805)
at
org.mvel2.optimizers.dynamic.DynamicOptimizer.optimizeObjectCreation(DynamicOptimizer.java:80)
at
org.mvel2.ast.NewObjectNode.getReducedValueAccelerated(NewObjectNode.java:148)
at
org.mvel2.compiler.ExecutableAccessor.getValue(ExecutableAccessor.java:37)
at
org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.getMethod(ReflectiveAccessorOptimizer.java:590)
at
org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.compileGetChain(ReflectiveAccessorOptimizer.java:285)
at
org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.optimizeAccessor(ReflectiveAccessorOptimizer.java:134)
at
org.mvel2.optimizers.dynamic.DynamicOptimizer.optimizeAccessor(DynamicOptimizer.java:61)
at org.mvel2.ast.ASTNode.getReducedValueAccelerated(ASTNode.java:127)
at org.mvel2.MVELRuntime.execute(MVELRuntime.java:91)
at
org.mvel2.compiler.CompiledExpression.getValue(CompiledExpression.java:101)
at org.mvel2.MVEL.executeExpression(MVEL.java:1025)
at org.drools.base.mvel.MVELConsequence.evaluate(MVELConsequence.java:89)
at org.drools.common.DefaultAgenda.fireActivation(DefaultAgenda.java:909)
... 97 more
Caused by: java.lang.ClassNotFoundException: No ClassLoaders found for:
String
at org.jboss.mx.loading.LoadMgr3.beginLoadTask(LoadMgr3.java:306)
at
org.jboss.mx.loading.RepositoryClassLoader.loadClassImpl(RepositoryClassLoader.java:521)
at
org.jboss.mx.loading.RepositoryClassLoader.loadClass(RepositoryClassLoader.java:415)
at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:164)
at org.mvel2.util.ParseTools.createClass(ParseTools.java:458)
at org.mvel2.util.ParseTools.findClass(ParseTools.java:796)
at
org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.compileConstructor(ReflectiveAccessorOptimizer.java:832)
at
org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.optimizeObjectCreation(ReflectiveAccessorOptimizer.java:799)
... 110 more
Any help would be very appreciated
ps: the very same rule worked with drools 4.0.7
Regards
--
View this message in context: http://www.nabble.com/No-ClassLoaders-found-for%3A-String-tp21437370p2143...
Sent from the drools - user mailing list archive at Nabble.com.
15 years, 11 months
Apache XML beans as facts with shadow proxy turned on (Drools 4.0.7)
by Przemysław Różycki
Hello!
I've got a problem with using XML beans (v. 2.2) as facts with shadow
proxy turned on (Drools 4.0.7). I'm using a stateful session created by
method newStatefulSession(java.io.InputStream stream). I have a base
WorkingMemory instance with some predefined facts implemented as Apache
XML beans. Then, I write it to an array of bytes using
ByteArrayOutputStream and ObjectOutputStream in order to create
ByteArrayInputStream and create new stateful session using the method
mentioned above. Here is the fragment of my code:
// --> BEGIN OF CODE FRAGMENT
// This is just an initialization of an XML bean fact
MyBean fact1 = MyBean.Factory.newInstance();
fact1.setField1("someText");
fact1.setField2(FieldType.Factory.newInstance());
// props contains some properties defined, but it doesn't matter
RuleAgent ruleAgent = RuleAgent.newRuleAgent(props);
RuleBase ruleBase = ruleAgent.getRuleBase();
// Here I create a base working memory instance
WorkingMemory baseWm = ruleBase.newStatefulSession(false);
// and insert the fact
baseWm.insert(fact1);
// Here I write a base working memory to a byte buffer
ByteArrayOutputStream baos1 = new ByteArrayOutputStream();
ObjectOutputStream oos1 = new ObjectOutputStream(baos1);
oos1.writeObject(baseWm);
oos1.close();
byte[] buf1 = baos1.toByteArray();
// and create a new stateful session based on the buffer
ByteArrayInputStream bais1 = new ByteArrayInputStream(buf1);
StatefulSession session1 = ruleBase.newStatefulSession(bais1);
// --> END OF CODE FRAGMENT
When shadow proxies is turned off, everything works fine. I can fire
rules and they see the fact. But when I turn the shadow proxies on, I've
got an exception:
java.io.NotSerializableException: org.example.myBean.MyBeanShadowProxy
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1081)
at
java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1375)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1347)
at
java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1290)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1079)
at
java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1375)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1347)
at
java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1290)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1079)
at
java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1375)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1347)
at
java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1290)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1079)
at java.io.ObjectOutputStream.writeArray(ObjectOutputStream.java:1251)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1075)
at
java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1375)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1347)
at
java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1290)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1079)
at
java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1375)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1347)
at
java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1290)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1079)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:302)
at java.util.HashMap.writeObject(HashMap.java:2336)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:917)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1339)
at
java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1290)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1079)
at
java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1375)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1347)
at
java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1290)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1079)
at
java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1375)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1347)
at
java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1290)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1079)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:302)
at com.sample.DroolsTest4.main(DroolsTest4.java:51)
I've checked and MyBean class is serializable. It looks like the proxy
of MyBean is not. What can be wrong here? Did I do any mistake?
Everything is fine when I use ordinary beans, not XML beans.
How the mechanism of creating shadow proxies work?
Best regards!
--
Przemysław Różycki
IT Architect
AMG.net, A Bull Group Company
ul. Łąkowa 29
90-554 Łódź
www.amg.net.pl
15 years, 11 months
length property not found on strings
by agori
This MVEL expression doens't compile in Drools 4:
when
MyObject(stringProperty.length == 5)
then
...
So I have to rewrite in
when
obj : MyObject()
String(length == 5) from obj.stringProperty
then
...
I hope that Drools 4 can do it much better that this crap. Is there a
better workaround?
15 years, 11 months