Bugs in Drools 5.3.0 break Fusion event processing
by Richard Calmbach
I am making extensive use of the event processing features of the Drools
rule engine. Upgrading from Drools 5.2.0.Final to Drools 5.3.0.Final broke
47 of my unit tests and also broke my functional tests. There seem to be
multiple changes in Drools 5.3.0 that cause incorrect behavior and/or break
backward compatibility. Here are the results of my investigation so far.
Issue F1:
While tracking down the failures of my unit tests, I experimented with the
Broker example, and while probably not finding the root cause of the broken
unit tests, I nonetheless came across what clearly seems to be incorrect
behavior in the DefaultTimerJobInstance.call() method. The bug only reveals
itself after all input has been processed, so it is masked by the fact that
running the Broker demo through the entire sequence in stocktickstream.dat
(1100 lines) takes a long time. In order to reveal the problem more
quickly, run the demo with only the first 14 lines in stocktickstream.dat.
Do so for both the 5.2.0 Broker demo (against Drools 5.2.0) and the 5.3.0
Broker demo (against Drools 5.3.0). The Broker example code in both
versions is identical, so only the Drools-internal code changes matter.
When running the 5.2.0 Broker demo to the end, you get one
java.text.ParseException (given the structure of the example code, that's
expected, albeit not elegant, and not the focus of our investigation). In
particular, no matter how many lines stocktickstream.dat contains, you
always get exactly one ParseException at the end.
Contrast this with running the 5.3.0 Broker demo: At the end you get N
occurrences of java.text.ParseException, where N is the number of lines in
stocktickstream.dat. So for 14 lines you get 14 occurrences of
ParseException. Looking at two specific methods shows us why:
Method
org.drools.examples.broker.events.EventFeeder.FeedJob.execute(JobContext):
public void execute(JobContext context) {
this.sink.receive( ((FeedContext) context).event );
if ( this.source.hasNext() ) {
((FeedContext) context).setEvent( this.source.getNext() );
this.trigger.setNextFireTime( ((FeedContext)
context).getEvent().getDate() );
clock.scheduleJob( this,
context,
trigger );
}
}
Note in particular how this method already takes care of scheduling the
next job execution by updating the next fire time of the job's existing
FeedTrigger instance. Unfortunately, in Drools 5.3.0,
DefaultTimerJobInstance.call() does a duplicate scheduling of the same job:
Method org.drools.time.impl.DefaultTimerJobInstance.call():
public Void call() throws Exception {
this.trigger.nextFireTime(); // need to pop
if ( handle.isCancel() ) {
return null;
}
this.job.execute( this.ctx );
if ( handle.isCancel() ) {
return null;
}
// our triggers allow for flexible rescheduling
Date date = this.trigger.hasNextFireTime();
if ( date != null ) {
scheduler.internalSchedule( this );
}
return null;
}
So, every job is duplicated and that's why there are 2*N calls to
org.drools.examples.broker.events.StockTickPersister.load() instead of N.
I think the rescheduling inside DefaultTimerJobInstance.call() is
incorrect. For one, it breaks backward compatibility, and it is unexpected.
The job should be in charge of deciding whether there is another job to
schedule or what to do. Implicitly scheduling the next job just by updating
the trigger time is a little too much magic.
Issue F2:
This is the bug that causes my unit tests to fail. I have not pinpointed
the root cause, but it seems to have to do with the event scheduling Drools
does as part of its job execution mechanism. Its symptom is a
NullPointerException during insertion of an event. What makes it so tricky
is that with the out-of-the-box configuration, Drools catches such
exceptions in org.drools.time.impl.PseudoClockScheduler.runCallBacks() and
passes them to the aptly named "DoNothingSystemEventListener", which
literally does nothing, not so much as logging (the methods are empty). So
you don't actually know that the event insertion failed, you only wonder
why your mock WorkingMemoryEventListener is telling you that your
expectations are not met. The stack trace (as copied from the Eclipse Debug
view, hence the unusual formatting) inside Drools is:
Date.getMillisOf(Date) line: 939
Date.compareTo(Date) line: 959
DefaultTimerJobInstance.compareTo(DefaultTimerJobInstance) line: 38
DefaultTimerJobInstance.compareTo(Object) line: 13
PriorityQueue<E>.siftUpComparable(int, E) line: 582
PriorityQueue<E>.siftUp(int, E) line: 574
PriorityQueue<E>.offer(E) line: 274
PriorityQueue<E>.add(E) line: 251
PseudoClockScheduler.internalSchedule(TimerJobInstance) line: 136
PseudoClockScheduler.scheduleJob(Job, JobContext, Trigger) line: 126
ObjectTypeNode.assertObject(InternalFactHandle, PropagationContext,
InternalWorkingMemory) line: 230
EntryPointNode.assertObject(InternalFactHandle, PropagationContext,
ObjectTypeConf, InternalWorkingMemory) line: 244
NamedEntryPoint.insert(InternalFactHandle, Object, Rule, Activation,
ObjectTypeConf) line: 330
NamedEntryPoint.insert(Object, boolean, boolean, Rule, Activation) line: 291
NamedEntryPoint.insert(Object) line: 116
NamedEntryPoint.insert(Object) line: 48
<my code calling into Drools>
Here is method
org.drools.time.impl.DefaultTimerJobInstance.compareTo(DefaultTimerJobInstance):
public int compareTo(DefaultTimerJobInstance o) {
return this.trigger.hasNextFireTime().compareTo(
o.getTrigger().hasNextFireTime() );
}
Essentially, this method calls java.util.Date.compareTo(Date) with a null
argument, which, as documented, causes a NullPointerException. Sometimes,
this.trigger.hasNextFireTime() already returns null, and then the NPE gets
thrown in DefaultTimerJobInstance.compareTo() itself.
I've seen different stack traces leading to this NPE, so this must be
affecting scheduling and job execution quite broadly.
Issue F3:
It is debatable whether this is a bug, but it is a backward-compatibility
breaking change. Previously, when scheduling a job with
org.drools.time.TimerService.scheduleJob(Job job, JobContext ctx, Trigger
trigger) (for both real-time and pseudo clock), you could pass a null
JobContext (say, because you didn't need one), and it would work. However,
in Drools 5.3.0, this causes a NullPointerException at:
org.drools.time.impl.DefaultTimerJobFactoryManager.createTimerJobInstance(Job,
JobContext, Trigger, JobHandle, InternalSchedulerService) line: 25
I realize that if it's not in knowledge-api-<version>.jar, it's not an
official API, but the available interfaces and classes in
org.drools.time.** (as used in the Broker example) are *very* useful for
test harnesses *and* for production code (for implementing dynamic timers,
for instance). So, this is more of a heads-up: If you are suddenly getting
an NPE, this might be the cause.
Please let me know whether I should create JIRA bug reports for issues F1
and F2. Also, I'd be interested to hear whether others have run into issues
with Fusion in Drools 5.3.0.
13 years, 2 months
A little suggestion about the 'ResourceFactory', 'DrlParser' API
by Miles Wen
Would you please provide a method in 'org.drools.io.ResourceFactory' like
this:
public static Resource newReaderResource(InputStream stream, String
encoding);
then I can use this method to load drl files as a stream while explicitly
specify its ecoding?
And in line: 287 of class 'org.drools.compiler.DrlParser':
lexer = new DRLLexer( new ANTLRInputStream( is ) );
no encoding specified as well. The ANTLRInputStream has constructors which
allows you to specify the encoding, otherwise it would figure out the
encoding according to the environment, which is unpredictable some times.
I'm using drools 5.3.0, the newest version. Thosse problems exists for
quite a while during previous versions. I'm fainting to see they are almost
there after upgraded to the new version.
--
Regards.
Miles. Wen
13 years, 2 months
NPE while creating Session using SimpleCredentials
by Praveen
Hi,
I am getting NPE at line 3, I doubt if SimpleCredentials is an issue over
here.
Please provide inputs if someone has faced the same.
try {
Repository repository = configurator.getJCRRepository(
repositoryHomeDirectory );
Credentials credentials = new SimpleCredentials("admin",
"admin".toCharArray());
//line 3 Session session = repository.login(credentials,
"production");
Node node = session.getRootNode();
System.out.println("root node path: " + node.getPath());
} catch (Exception e) {
e.printStackTrace();
}
TIA.
Regards,
Praveen.
--
View this message in context: http://drools.46999.n3.nabble.com/NPE-while-creating-Session-using-Simple...
Sent from the Drools: User forum mailing list archive at Nabble.com.
13 years, 2 months
Writing complicated rules - consecutive number problem
by LCode
I am trying to write a rather complicated rule via the guided rule editor and
I wonder if it is indeed possible.
The following is a simplified explanation of my scenario:
A 'person' has a numerical property 'age'
In a hypothetical world the following is allowed because the ages of the
people are consecutive:
Person A age = 24
Person B age = 25
Person C age = 26 OK
Person D age = 27
However I would like to write a rule that fires if the ages are not
consecutive, something like this:
Person A age = 24
Person B age = 25
Person C age = 29 NOT OK
Person D age = 27
I am starting with 'From collect all people [p]'.
Any thoughts, comments or similar experiences much apprieciated as I am
pulling my hair out!
Jen
--
View this message in context: http://drools.46999.n3.nabble.com/Writing-complicated-rules-consecutive-n...
Sent from the Drools: User forum mailing list archive at Nabble.com.
13 years, 2 months
Data Modeling for medical expert system
by Dirk Conzelmann
Hi everybody,
I am using Drools as a part of my Bachelor Thesis.
My job is to build an expert system for medical diagnoses.
My Question:
Is there a best practice known in modeling a variable
list of questions and answers in Drools?
Up to now I modeled the list of questions implementing
Java Classes and Enums for each question/answer pair.
But to be able to change those options easyly I need
a higher abstraction level than simple Java Classes and Enums.
Could someone show me an example how to implement this?
I hope I have explained my question understandable :)
--
Dirk Conzelmann
IT-Services
Telefon: +49.179.2237995
Email: info(a)dirk-conzelmann.de
Web: www.dirk-conzelmann.de
13 years, 2 months
Security test cases for Drools
by kapokfly
Not sure if anyone can share their experiences what kind of test cases on
Drools security should be developed and ensured?
As the rule is just a piece of codes in String format which can be hooked
into JVM, we can assume that might open some holes and necessary security
test cases need to be designed against.
Anyone can share their experiences on this?
Thanks...
--
View this message in context: http://drools.46999.n3.nabble.com/Security-test-cases-for-Drools-tp349407...
Sent from the Drools: User forum mailing list archive at Nabble.com.
13 years, 2 months
rule does not fire at first event
by ukriegel
Hi there,
we use drools fusion 5.3. Final.
In a drl-file, a fact and an event and the following rules are declared
package ... etc
declare ActivityState
@role(fact)
state : StateType
end
rule "set initial state"
dialect "java"
salience 100
when not (exists KFActivityState())
then
ActivityState $actState = new ActivityState();
$actState.setState(StateType.STANDBY);
insert($actState);
System.out.println("ActivityState inserted "+ new Date());
end
declare Command
@role (event)
end
rule "request information"
dialect "java"
when Command(commandType == CommandType.REQUEST_INFORMATION) from
entry-point "XXX"
$s: ActivityState(state == ComponentStateType.ACTIVE||state ==
ComponentStateType.PASSIVE||state == ComponentStateType.STANDBY)
then
System.out.println("Send Report");
end
The rule request information doesn't fire with the first command event, but
from the second one it fires always.
What's wrong with my code?
Thanks in advance
Ulrich
--
View this message in context: http://drools.46999.n3.nabble.com/rule-does-not-fire-at-first-event-tp349...
Sent from the Drools: User forum mailing list archive at Nabble.com.
13 years, 2 months
Re: [rules-users] Where in DB does Guvnor store "description" of rules?
by GPatel@tsys.com
Take a look at the guvnor rest api
----- Original Message -----
From: Praveen [praveen.sanju(a)gmail.com]
Sent: 11/08/2011 02:11 AM PST
To: rules-users(a)lists.jboss.org
Subject: [rules-users] Where in DB does Guvnor store "description" of rules?
Hi,
Our application expects rule name and its description to be displayed in the
UI and both of
these are to be retrieved from DB.
We are aware that Guvnor stores rules in DB, not sure of the description
part.
If someone could throw light on how to get description/comments (that was
entered through Guvnor)
in UI would be great.
Initially we had the idea of parsing comments in drl.
However we saw that the description entered through Guvnor while writing a
rule does not show up in the generated source code.
TIA.
Regards,
Praveen.
--
View this message in context: http://drools.46999.n3.nabble.com/Where-in-DB-does-Guvnor-store-descripti...
Sent from the Drools: User forum mailing list archive at Nabble.com.
_______________________________________________
rules-users mailing list
rules-users(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users
-----------------------------------------
The information contained in this communication (including any
attachments hereto) is confidential and is intended solely for the
personal and confidential use of the individual or entity to whom
it is addressed. If the reader of this message is not the intended
recipient or an agent responsible for delivering it to the intended
recipient, you are hereby notified that you have received this
communication in error and that any review, dissemination, copying,
or unauthorized use of this information, or the taking of any
action in reliance on the contents of this information is strictly
prohibited. If you have received this communication in error,
please notify us immediately by e-mail, and delete the original
message. Thank you
13 years, 2 months
variables confusion Java/MVEL
by elsdestickere
Hi,
I'm confused about when en where to use Java or MVEL in a rule.
In the example below I want to replace "
openRes.getMasterExemplaar().getBruikbareExemplaren()" with a variable.
RHD: works with JAva expression:
List<Exemplaar> bruikEx =
openRes.getMasterExemplaar().getBruikbareExemplaren();
but I prefer to create the variable in the LHS, but Java doesn't work here.
Should this be a MVEL expression or should JAVA allways be possible?
rule "GarandeerReservaties"
when
garRes : GarandeerReservatieTaak();
openRes : Reservatie() from
repFact.getReservatieRepository().findVandaagOpenstaandeReservaties();
List<Exemplaar> bruikEx
=openRes.getMasterExemplaar().getBruikbareExemplaren();
eval(Reservatie.getVandaagOpenstaandeReservaties().size() > 0 &&
openRes.getMasterExemplaar().getBruikbareExemplaren().size() != 0)
then
//List<Exemplaar> bruikEx =
openRes.getMasterExemplaar().getBruikbareExemplaren();
bruikEx.get(0).setStatus(ExemplaarStatus.MOMENTEEL_GERESERVEERD);
openRes.setStatus(ReservatieStatus.GEGARANDEERD);
System.out.println( "Drools "+drools.getRule().getName()+": ocr:
"+openRes.getAantalVandaagOpenstaandeConcurReservaties() + " bruikex: "
+bruikEx.size() );
end
(written in Dutch, but I think it will be ok to understand)
br,
Els
--
View this message in context: http://drools.46999.n3.nabble.com/variables-confusion-Java-MVEL-tp3493632...
Sent from the Drools: User forum mailing list archive at Nabble.com.
13 years, 2 months