Re: [rules-users] Question about Drools Spring, StatelessKnowledgeSession and globals
by Patrick van Kann
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
12 years, 11 months
Drools: Using Declared Types in Decision Tables
by David Smith
Hi,
I am trying to use a declared type in a decision table
but get an "Unable to resolve ObjectType" message.
The declared type is in a file types.drl,
I have a spreadsheet test.xls that has a Ruleset with
an import line for the declared type.
Is it possible to reference a declared type from a decision table?
Is it possible to declare a type in a decision table?
Thanks
David
13 years
Drools Guvnor API information?
by Vikas Hazrati
Hi,
I am looking at using Guvnor for our project where users would be creating
rules using our UI. For this i need to add / modify rule or any asset for
that matter using an api.
Unfortunately, i could not find enough documentation to suggest the best way
to use the REST api, which I guess is provided by Guvnor. Could someone let
me know the location of where i can get some information for this api. I
also see that the issue GUVNOR-1080
(https://issues.jboss.org/browse/GUVNOR-1080) is marked resolved so the api
should exist right? or that we cannot access it remotely until we have the
Atom Pub Interface done?
Help appreciated .
--
View this message in context: http://drools-java-rules-engine.46999.n3.nabble.com/Drools-Guvnor-API-inf...
Sent from the Drools - User mailing list archive at Nabble.com.
13 years, 2 months
java.lang.OutOfMemoryError: Java heap space
by vdelbart
Hello,
In my tests of the 4.0.3, I have some : java.lang.OutOfMemoryError.
So, I try a simple test with 10.000 sequential execution of 1 rule with no
context and just a workingmemorylogger and I have the error :
java.lang.OutOfMemoryError: Java heap space
My code is :
public class ExecReglesMemotyTest
{
private static final Reader DRL = new
InputStreamReader(ExecReglesMemotyTest.class
.getResourceAsStream("/rules/exemple.drl"));
private static final String FICHIER_LOG = "session";
/**
* @param args
*/
public static void main(String[] args)
{
try
{
PackageBuilder builder = new PackageBuilder();
builder.addPackageFromDrl(DRL);
RuleBase ruleBase = RuleBaseFactory.newRuleBase();
ruleBase.addPackage(builder.getPackage());
for (int i = 0; i < 10000; i++)
{
StatefulSession session = ruleBase.newStatefulSession();
WorkingMemoryFileLogger logger = new WorkingMemoryFileLogger(session);
logger.setFileName(FICHIER_LOG);
session.fireAllRules();
logger.writeToDisk();
session.dispose();
}
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
with this rule (doesn't matter):
#created on: Fri Nov 09 15:48:45 CET 2007
package initPackage
#list any import classes here.
rule "ERG9"
when
then
end
I try this in 4.0.1, and it's working (no OutOfMemoryError)
What's the problem ?
thanks for any information,
V.
--
View this message in context: http://www.nabble.com/java.lang.OutOfMemoryError%3A-Java-heap-space-tf477...
Sent from the drools - user mailing list archive at Nabble.com.
13 years, 2 months
Unable to find implementation for BusinessRuleProvider
by John Peterson
Hi,
I've been experimenting with the Guided Rule Editor plug-in in Eclipse.
I've built a Drools Project using the default Hello World sample
application. I've created a new "Guided Rule" in my project called
"GuidedRule.brl" and get the associated "drools.package" with it. The
rule is simple:
WHEN
THEN
System.out.println("Rule has fired");
I build the knowledge base as follows:
private static KnowledgeBase readKnowledgeBase() throws
Exception {
KnowledgeBuilder kbuilder =
KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add(ResourceFactory.newClassPathResource("SampleGuided.drl"),
ResourceType.BRL);
KnowledgeBuilderErrors errors = kbuilder.getErrors();
if (errors.size() > 0) {
for (KnowledgeBuilderError error: errors) {
System.err.println(error);
}
throw new IllegalArgumentException("Could not
parse knowledge.");
}
KnowledgeBase kbase =
KnowledgeBaseFactory.newKnowledgeBase();
kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
return kbase;
}
The only line changed is adding the resource of type BRL.
When I try to run, I get the following error:
java.lang.RuntimeException: org.drools.compiler.DroolsParserException:
org.drools.CheckedDroolsException: Unable to find implementation for
BusinessRuleProvider
at
org.drools.compiler.PackageBuilder.addKnowledgeResource(PackageBuilder.j
ava:544)
at
org.drools.builder.impl.KnowledgeBuilderImpl.add(KnowledgeBuilderImpl.ja
va:28)
at com.sample.DroolsTest.readKnowledgeBase(DroolsTest.java:41)
at com.sample.DroolsTest.main(DroolsTest.java:23)
Caused by: org.drools.compiler.DroolsParserException:
org.drools.CheckedDroolsException: Unable to find implementation for
BusinessRuleProvider
at
org.drools.compiler.PackageBuilder.addPackageFromBrl(PackageBuilder.java
:386)
at
org.drools.compiler.PackageBuilder.addKnowledgeResource(PackageBuilder.j
ava:470)
... 3 more
Caused by: org.drools.CheckedDroolsException: Unable to find
implementation for BusinessRuleProvider
at
org.drools.compiler.BusinessRuleProviderFactory.throwNoImplementationFou
nd(BusinessRuleProviderFactory.java:66)
at
org.drools.compiler.BusinessRuleProviderFactory.loadProvider(BusinessRul
eProviderFactory.java:42)
at
org.drools.compiler.BusinessRuleProviderFactory.getProvider(BusinessRule
ProviderFactory.java:25)
at
org.drools.compiler.PackageBuilder.addPackageFromBrl(PackageBuilder.java
:366)
... 4 more
I've tried variations to add the drools.package as a PKG type, I've had
the rules (and package) in both "com.sample" and /src/main/rules, but I
can't seem to resolve the problem. "drools.package" has been updated to
include the package name (package com.sample;) and I import the message
class as well (even though it isn't being used currently).
I suspect the issue is simple, but I haven't been able to figure it out.
Any help would be appreciated.
13 years, 3 months
Drools verifier
by FrankVhh
Hi all,
Triggered by a post on this forum, I decided to try a testcase
implementation of Drool Verifiier.
I manage to write some code that does not produce any errors at runtime,
which is good. Unfortunately, it doesn't produce any errors/warnings/notes
on my rulefile either, which isn't good.
The drl file consists of some duplicate rules, and since the file is only
part of a ruleset, there might be some gaps as well.
I pasted the java-code below. Does anyone see where I am going wrong?
Thanks in advance!
Regards,
Frank
VerifierBuilder vBuilder =
VerifierBuilderFactory.newVerifierBuilder();
Verifier verifier = vBuilder.newVerifier();
String ruleText =
"C:\\Users\\Frank\\Documents\\DroolsWorkSpaces\\EmpiricalExperiments\\Financial
Rules\\src\\main\\rules\\clearancerules.drl";
verifier.addResourcesToVerify( ResourceFactory.newReaderResource(
new StringReader( ruleText ) ), ResourceType.DRL );
verifier.fireAnalysis();
VerifierReport result = verifier.getResult();
for(VerifierMessageBase base: result.getBySeverity(
Severity.ERROR ) ){
System.out.println( base );
}
for(VerifierMessageBase base: result.getBySeverity(
Severity.WARNING ) ){
System.out.println( base );
}
for(VerifierMessageBase base: result.getBySeverity( Severity.NOTE )
){
System.out.println( base );
}
--
View this message in context: http://drools-java-rules-engine.46999.n3.nabble.com/Drools-verifier-tp268...
Sent from the Drools - User mailing list archive at Nabble.com.
13 years, 6 months
Challenge! Using javassist and drools presents an issue with drl
by markricard
In order to make writing drl files easy and not requiring writers to be
developers, I have written some JavaAssist code that dynamically creates a
subclass and new methods in memory.
If for example there is a REAL java class called 'com.foo.Instance'. Via
javasssist, I create a new in-memory subclass called 'com.foo.InstanceEx'.
The new class dynamically creates a new getter called getFoo(). The drl
writer would like to directly reference 'foo' in the drl file like so:
when
i : Instance(foo == 'fee')
The problem is, in order to reference foo, I would need the drl file to do
this:
import com.rrd.xspace.drools.InstanceEx;
But I cannot do that because InstanceEx does not exist at runtime. The
error I get, which is an obvious one, is "Unable to create Field Extractor
for 'foo' of '[ClassObjectType class=com.foo.Instance]' in rule 'Test' :
[Rule name='Test']"
Is there a way to include a dynamic import of a JavaAssist class while I am
constructing the KnowledgeBase instances to run the rules so that I can
reference that new method?
I would hope to have something similar to:
KnowledgeBuilder kbuilder = ....
kbuilder.addImport("com.foo.InstanceEx")
or
kbuilder.addClass(Class.forName("com.foo.InstanceEx"))
Any help GREATLY appreciated.
--
View this message in context: http://drools-java-rules-engine.46999.n3.nabble.com/Challenge-Using-javas...
Sent from the Drools - User mailing list archive at Nabble.com.
13 years, 7 months