[rules-users] Question about Drools Spring, StatelessKnowledgeSession and globals

Patrick van Kann pvankann at gmail.com
Sun Nov 7 06:48:53 EST 2010


Hello fellow Droolers,

A while ago I asked why the <drools:batch> element seemed to work
differently in the case of a StatelessKnowledgeSession and a
StatefulKnowedgeSession (see below).

I just wanted to update those interested with the answer and ask some
further questions, probably aimed at any developers who happen to be
reading.

I checked out the 5.1.1.34858 tag and had a look at how the Spring
integration works. I found that the reason that the global is not set in the
case of a StatelessKnowledgeSession is because the <spring:batch> element is
effectively ignored in the StatelessKnowledgeSessionBeanFactory, which lacks
the following code present in the StatefulKnowledgeSessionBeanFactory (in
the internalAfterPropertiesSet() method):

if ( getBatch() != null && !getBatch().isEmpty()) {
    for ( Command<?> cmd : getBatch() ) {
        ksession.execute( cmd );
    }
}

So, either by accident or design the <spring:batch> element has no effect
when using a StatelessKnowledgeSession (but is perfectly allowable in the
XSD/Spring namespace).

So my questions are:
1) Is this the intended behaviour or a bug? On reflection, I am now not sure
the idea of a "batch/script" makes sense for a StatelessKnowledgeSession
since execute() is a one-shot method and any globals set this way would not
be available to later executions, which is what I was looking for.
2) If so, should the XSD be changed to disallow the batch element within a
stateless session (difficult, given that this is determined via the "type"
attribute) or should the documentation simply warn people that the
<spring:batch> element doesn't do anything if you set the type attribute to
stateless (somewhat confusing, I suppose)
3) If not, should the code above be added to the
StatelessKnowledgeSessionBeanFactory.internalAfterPropertiesSet() method?
4) Should there be another way to declare a global that isn't through the
batch element (one that would cause globals to be set via the
setGlobal(String, Object) method rather than using the SetGlobalCommand via
the execute() method.

I am happy to try and contribute something along these lines if I can get
some guidance as to what was actually intended.

Hope this helps and thanks again for Drools.

Patrick

=====================================
Hello,

I've been trying out the Spring integration package in Drools 5.1.1 and it
works really well, but I have run into one issue I can't figure out.

I've defined 2 knowledge sessions from the same knowledge base in the app
context - one stateless, one stateful but otherwise identical. They both
refer to a collaborator defined as a bean in the app context which is to be
used as a global in my rules. This is just an excerpt of my full Spring
context, the kbase definition itself is not an issue.

<bean id="applicantDao" class="com.acme.app.dao.impl.ApplicantDaoImpl" />

<drools:ksession id="statelessKSession" type="stateless"
name="statelessKSession" kbase="kbase">
      <drools:batch>
          <drools:set-global identifier="applicantDao" ref="applicantDao" />
      </drools:batch>
  </drools:ksession>

   <drools:ksession id="statefulKSession" type="stateful"
name="statefulKSession" kbase="kbase">
      <drools:batch>
          <drools:set-global identifier="applicantDao" ref="applicantDao" />
      </drools:batch>
  </drools:ksession>

The issue is that this configuration works for the stateful but not the
stateless session, in the sense that the stateful session appears to have a
valid reference to the applicantDao object in the Globals object but the
stateless session doesn't.

<at> Test
public void testStatelessGlobal() {
        Globals globals = statelessKSession.getGlobals();
        Object global = globals.get("applicantDao");
        Assert.assertNotNull(global);
 }

<at> Test
public void testStatefulGlobal() {
        Globals globals = statefulKSession.getGlobals();
        Object global = globals.get("applicantDao");
        Assert.assertNotNull(global);
}

The first test fails (the global variable is null) but the second passes. No
errors are thrown by Drools during the setup of the Spring container.

What am I doing wrong? Should I be able to define globals in this way for
stateless sessions? The XSD seems to indicate this is a valid configuration,
but it just doesn't work.

Is anyone else working with the Spring integration that can point out my
error here?

Many thanks,

Patrick
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/rules-users/attachments/20101107/27f0a21d/attachment.html 


More information about the rules-users mailing list