Hi all,
Last week I sent this message asking for some help identifying either an usage error from
us or a possible bug in Drools Fusion 5.1.0, but so far got no answer. If any of you
fellows can find any mistake in our implementation please let me know, otherwise I'll
assume this is indeed a bug in 5.1.0 and proceed to register it. Thanks in advance for any
help.
Carlos
Hi all,
We're evaluating the use of Drools Fusion as rule engine for one
of our
projects, but after updating from version 5.0.1 to 5.1.0 to fix one
persistence issue we faced new errors and some unexpected behavior
changes in already tested parts of our code, and we aren't unsure if
it's our fault due to incorrect assumptions or if it's resulting from a
new bug introduced in last release. Here follows what we are doing:
1) we declared this in our Test_Rules.drl:
declare UserEvent @role( event ) @expires( 30s ) end
query "get user by login" (String login) user :
UserEvent(user.login ==
login) end
2) this is the code we use to retrieve the Drools session
(implemented
in a singleton):
public StatefulKnowledgeSession getKnowledgeSessionInstance() {
if (session == null) { kbase = readKnowledgeBase();
KnowledgeSessionConfiguration conf =
KnowledgeBaseFactory.newKnowledgeSessionConfiguration(); session =
kbase.newStatefulKnowledgeSession(conf, null); }
return session; }
3) that's how we load the rules (some non-pertinent code was
omitted):
private KnowledgeBase readKnowledgeBase() { KnowledgeBuilder kbuilder
=
KnowledgeBuilderFactory.newKnowledgeBuilder();
KnowledgeBaseConfiguration config =
KnowledgeBaseFactory.newKnowledgeBaseConfiguration();
config.setOption(EventProcessingOption.STREAM);
kbuilder.add(ResourceFactory.newClassPathResource("Test_Rules.drl"),
ResourceType.DRL); KnowledgeBuilderErrors errors = kbuilder.getErrors();
if (errors.size() > 0) { // (...) throw new
IllegalArgumentException("Could not parse knowledge."); } KnowledgeBase
kbase = KnowledgeBaseFactory.newKnowledgeBase(config);
kbase.addKnowledgePackages(kbuilder.getKnowledgePackages()); return
kbase; }
(NOTE: Up to this point the code behaves exactly the same way in both
versions and everything works as expected.)
4) in this method we check our event expiration, and that's where
things
starts to behave different. In version 5.0.1, the code always worked in
the same way, returning a null reference to userValidation if the
expiration time is reached. Also, handleQuery is always an instance of
EventFactHandle. Based in userValidation reference being null or not, we
either retrieve it or update it. Again, non-related code was ommited:
private UserTrackForValidation assertDesktopEvent(DesktopDeviceEvent
event) { UserEvent userValidation = null; StatefulKnowledgeSession
session =
sessionFactory.getKnowledgeSessionInstance(createEnviroment());
QueryResults results = session.getQueryResults("get user by login", new
String[] {event.getLogin()});
if (results.size() > 0) { QueryResultsRow row =
results.iterator().next(); FactHandle handleQuery =
row.getFactHandle("user"); userValidation = (UserTrackForValidation)
row.get("user"); }
if (userValidation == null) { try { userValidation =
entityDAO.getUserTrackByLogin(event.getLogin()); } catch (Exception e) {
e.printStackTrace(); }
// (...) } else { // (...) session.update(handleQuery,
userValidation);
session.fireAllRules(); } }
return userValidation; }
However, starting with version 5.1.0, we observed some odd behaviors:
a) after time expiration, we may or may not receive a null reference to
userValidation, which renders the test line "if (userValidation ==
null)" erratic; b) even when we receive a (as far as we can tell) valid
reference to userValidation, sometimes a NullPointerException is raised,
as can be seen in the following stacktrace:
java.lang.NullPointerException at
org.drools.common.AbstractWorkingMemory.update(AbstractWorkingMemory.jav
a:1329) at
org.drools.common.AbstractWorkingMemory.update(AbstractWorkingMemory.jav
a:1288) at
org.drools.impl.StatefulKnowledgeSessionImpl.update(StatefulKnowledgeSes
sionImpl.java:248) at
br.com.todobpo.lam.ejb.session.ContactCenterRuleServiceImpl.assertSimple
Event(ContactCenterRuleServiceImpl.java:191) at
br.com.todobpo.lam.ejb.session.ContactCenterRuleServiceImpl.insertEvent(
ContactCenterRuleServiceImpl.java:89) at
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.jav
a:39) at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessor
Impl.java:25) at java.lang.reflect.Method.invoke(Method.java:597)
at
org.jboss.aop.joinpoint.MethodInvocation.invokeTarget(MethodInvocation.j
ava:122) at
org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.jav
a:111) at
org.jboss.ejb3.EJBContainerInvocationWrapper.invokeNext(EJBContainerInvo
cationWrapper.java:69) at
org.jboss.ejb3.interceptors.aop.InterceptorSequencer.invoke(InterceptorS
equencer.java:73) at
org.jboss.ejb3.interceptors.aop.InterceptorSequencer.aroundInvoke(Interc
eptorSequencer.java:59) at
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.jav
a:39) at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessor
Impl.java:25) at java.lang.reflect.Method.invoke(Method.java:597)
at
org.jboss.aop.advice.PerJoinpointAdvice.invoke(PerJoinpointAdvice.java:1
74) at
org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.jav
a:102) at
org.jboss.ejb3.interceptors.aop.InvocationContextInterceptor.fillMethod(
InvocationContextInterceptor.java:72) at
org.jboss.aop.advice.org.jboss.ejb3.interceptors.aop.InvocationContextIn
terceptor_z_fillMethod_1000702.invoke(InvocationContextInterceptor_z_fil
lMethod_1000702.java) at
org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.jav
a:102) at
org.jboss.ejb3.interceptors.aop.InvocationContextInterceptor.setup(Invoc
ationContextInterceptor.java:88) at
org.jboss.aop.advice.org.jboss.ejb3.interceptors.aop.InvocationContextIn
terceptor_z_setup_1000702.invoke(InvocationContextInterceptor_z_setup_10
00702.java) at
org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.jav
a:102) at
org.jboss.ejb3.connectionmanager.CachedConnectionInterceptor.invoke(Cach
edConnectionInterceptor.java:62) at
org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.jav
a:102) at
org.jboss.ejb3.entity.TransactionScopedEntityManagerInterceptor.invoke(T
ransactionScopedEntityManagerInterceptor.java:56) at
org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.jav
a:102) at
org.jboss.ejb3.AllowedOperationsInterceptor.invoke(AllowedOperationsInte
rceptor.java:47) at
org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.jav
a:102) at
org.jboss.ejb3.tx.StatelessBMTInterceptor.handleInvocation(StatelessBMTI
nterceptor.java:106) at
org.jboss.ejb3.tx.BMTInterceptor.invoke(BMTInterceptor.java:55)
at
org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.jav
a:102) at
org.jboss.ejb3.stateless.StatelessInstanceInterceptor.invoke(StatelessIn
stanceInterceptor.java:68) at
org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.jav
a:102) at
org.jboss.ejb3.tx.NullInterceptor.invoke(NullInterceptor.java:42)
at
org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.jav
a:102) at
org.jboss.aspects.tx.TxPropagationInterceptor.invoke(TxPropagationInterc
eptor.java:76) at
org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.jav
a:102) at
org.jboss.ejb3.tx.NullInterceptor.invoke(NullInterceptor.java:42)
at
org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.jav
a:102) at
org.jboss.ejb3.security.Ejb3AuthenticationInterceptorv2.invoke(Ejb3Authe
nticationInterceptorv2.java:186) at
org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.jav
a:102) at
org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationIntercepto
r.java:41) at
org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.jav
a:102) at
org.jboss.ejb3.BlockContainerShutdownInterceptor.invoke(BlockContainerSh
utdownInterceptor.java:67) at
org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.jav
a:102) at
org.jboss.aspects.currentinvocation.CurrentInvocationInterceptor.invoke(
CurrentInvocationInterceptor.java:67) at
org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.jav
a:102) at
org.jboss.ejb3.stateless.StatelessContainer.dynamicInvoke(StatelessConta
iner.java:421) at
org.jboss.ejb3.session.InvokableContextClassProxyHack._dynamicInvoke(Inv
okableContextClassProxyHack.java:53) at
org.jboss.aop.Dispatcher.invoke(Dispatcher.java:91) at
org.jboss.aspects.remoting.AOPRemotingInvocationHandler.invoke(AOPRemoti
ngInvocationHandler.java:82) at
org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:891)
at
org.jboss.remoting.transport.socket.ServerThread.completeInvocation(Serv
erThread.java:744) at
org.jboss.remoting.transport.socket.ServerThread.processInvocation(Serve
rThread.java:697) at
org.jboss.remoting.transport.socket.ServerThread.dorun(ServerThread.java
:524) at
org.jboss.remoting.transport.socket.ServerThread.run(ServerThread.java:2
32) at
org.jboss.remoting.MicroRemoteClientInvoker.invoke(MicroRemoteClientInvo
ker.java:211) at org.jboss.remoting.Client.invoke(Client.java:1724)
at org.jboss.remoting.Client.invoke(Client.java:629) at
org.jboss.aspects.remoting.InvokeRemoteInterceptor.invoke(InvokeRemoteIn
terceptor.java:60) at
org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.jav
a:102) at
org.jboss.aspects.tx.ClientTxPropagationInterceptor.invoke(ClientTxPropa
gationInterceptor.java:61) at
org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.jav
a:102) at
org.jboss.ejb3.security.client.SecurityClientInterceptor.invoke(Security
ClientInterceptor.java:65) at
org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.jav
a:102) at
org.jboss.ejb3.remoting.IsLocalInterceptor.invoke(IsLocalInterceptor.jav
a:74) at
org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.jav
a:102) at org.jboss.aspects.remoting.PojiProxy.invoke(PojiProxy.java:62)
at $Proxy7.invoke(Unknown Source) at
org.jboss.ejb3.proxy.impl.handler.session.SessionProxyInvocationHandlerB
ase.invoke(SessionProxyInvocationHandlerBase.java:207)
at
org.jboss.ejb3.proxy.impl.handler.session.SessionProxyInvocationHandlerB
ase.invoke(SessionProxyInvocationHandlerBase.java:164)
at $Proxy6.insertEvent(Unknown Source) at
br.com.todobpo.lam.ejb.test.Authenticate.authenticationOk(Authenticate.j
ava:70) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.jav
a:39) at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessor
Impl.java:25) at java.lang.reflect.Method.invoke(Method.java:597)
at
org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMet
hod.java:44) at
org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallab
le.java:15) at
org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMetho
d.java:41) at
org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod
.java:20) at
org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner
.java:76) at
org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner
.java:50) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at
org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4Tes
tReference.java:46) at
org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.ja
va:38) at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTe
stRunner.java:467) at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTe
stRunner.java:683) at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRun
ner.java:390) at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRu
nner.java:197) at
org.jboss.aspects.remoting.InvokeRemoteInterceptor.invoke(InvokeRemoteIn
terceptor.java:72) at
org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.jav
a:102) at
org.jboss.aspects.tx.ClientTxPropagationInterceptor.invoke(ClientTxPropa
gationInterceptor.java:61) at
org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.jav
a:102) at
org.jboss.ejb3.security.client.SecurityClientInterceptor.invoke(Security
ClientInterceptor.java:65) at
org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.jav
a:102) at
org.jboss.ejb3.remoting.IsLocalInterceptor.invoke(IsLocalInterceptor.jav
a:74) at
org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.jav
a:102) at org.jboss.aspects.remoting.PojiProxy.invoke(PojiProxy.java:62)
at $Proxy7.invoke(Unknown Source) at
org.jboss.ejb3.proxy.impl.handler.session.SessionProxyInvocationHandlerB
ase.invoke(SessionProxyInvocationHandlerBase.java:207)
at
org.jboss.ejb3.proxy.impl.handler.session.SessionProxyInvocationHandlerB
ase.invoke(SessionProxyInvocationHandlerBase.java:164)
at $Proxy6.insertEvent(Unknown Source) at
br.com.todobpo.lam.ejb.test.Authenticate.authenticationOk(Authenticate.j
ava:70) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.jav
a:39) at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessor
Impl.java:25) at java.lang.reflect.Method.invoke(Method.java:597)
at
org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMet
hod.java:44) at
org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallab
le.java:15) at
org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMetho
d.java:41) at
org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod
.java:20) at
org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner
.java:76) at
org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner
.java:50) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at
org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4Tes
tReference.java:46) at
org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.ja
va:38) at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTe
stRunner.java:467) at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTe
stRunner.java:683) at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRun
ner.java:390) at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRu
nner.java:197)
c) handleQuery can either receive an EventFactHandle or a
DisconnectedFactHandle, without no apparent pattern. For the later case
(DisconnectedFactHandle), the returned class lacks a useful isValid()
method (the current implementation only throws an exception), thus we
are unable to check the returned object before using it;
d) finally, we noticed that all mentioned errors happens only when we
set the real time clock in the KnowledgeSessionConfiguration object.
Using the pseudo clock, there are no runtime errors and the object
expiration behavior appears to be correct, like in 5.0.1.
So, after all this information, we have a couple questions:
1) Is really correct to assume that after an event expiration the
object
reference will always be null (as observed up to version 5.0.1) ? If
not, how can we determine the event associated object sanity ? 2) Why
starting from version 5.1.0 we started to observe the occurrence of
DisconnectedFactHandle ? Can this detail be safely ignored, or is this a
sign that something went wrong when trying to retrieve the event ?
3) Is there something flawed in our presented approach ? Or did we bump
into a new bug ?
Any help is apreciated.
Carlos
Esta mensagem pode conter informa??o confidencial e/ou privilegiada, sendo seu sigilo
protegido por lei. Se voc? n?o for o destinat?rio ou a pessoa autorizada a receber esta
mensagem, n?o pode usar, copiar ou divulgar as informa??es nela contidas ou tomar qualquer
a??o baseada nessas informa??es. Se voc? recebeu esta mensagem por engano, por favor avise
imediatamente ao remetente, respondendo o e-mail e em seguida apague-o. Agradecemos sua
coopera??o.
This message may contain confidential and/or privileged information, being the sigil
protected by law. If you are not the addressee or authorized to receive this for the
addressee, you must not use, copy, disclose or take any action based on this message or
any information herein. If you have received this message in error, please advise the
sender immediately by reply e-mail and delete this message. Thank you for your
cooperation.