1
votes

I am very new to Drools and I have completed some of the tutorials found online and read the docs. I am sure what I am about to explain has a trivial solution that I have missed but I will lay it out regardless.

I have a single rule in my drools file and an object that reads its info from a text file.

The code looks similar to this:

   public static final void main(String[] args) {
        try {
            ObjectArchive arch = ArchiveFactory.openArchive(new File("dwc.txt"));
            Iterator<Object> iter = arch.iteratorDwc();

            // load up the knowledge base
            KnowledgeBase kbase = readKnowledgeBase();
            StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
            KnowledgeRuntimeLogger logger =  KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, "test");
            while(iter.hasNext()) {
                Object dwcRecord = iter.next();
                ksession.insert(dwcRecord);
            }
            System.out.println(ksession.getFactCount());
            ksession.fireAllRules();
            logger.close();
        } catch (Throwable t) {
            t.printStackTrace();
        }
    }

    private static KnowledgeBase readKnowledgeBase() throws Exception {
        KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
        kbuilder.add(ResourceFactory.newClassPathResource("dwcrules.drl"), ResourceType.DRL);
        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;
    }

I have a simple rules file that checks if a property of said object is not null and prints out the object if this is true.

Now, the problem.

If I add one object (no while loop) then the rule is fired and all is well. However, if I add multiple objects to the session and then fire the rules it tends to just grab the last one, or fire but print out a single null.

So, why is it that I am unable to add multiple facts of the same type? Or what am I missing that stops me from being able to fire the same rule on multiple facts?

Thanks in advance.

EDIT: Sorry, here is the rule:

rule "Scientific Name"
when 
    dwc : Object(dwc.getScientificName != null)
then
    System.out.println(dwc);
 end
1
Can you please paste your rule?Edson Tirelli
Small update, created another class just to test (basic class with one string property) and it works fine. Seems like there could be something to do with that particular class that prevents having multiple in the session?Christopher Gwilliams
By default, Drools uses identity to store objects in the working memory. Unless you changed the configuration option to use equality, you can have as many instances of the same class as you want/need. Suggestion: run your test using the WorkingMemoryConsoleLogger to print out your audit log into the console and paste the console log in here... it would also be good to print your object's scientificName property for each object before inserting them into working memory just to be sure they are not null.Edson Tirelli

1 Answers

1
votes

I don't know exactly what is happening, as I don't have your object file to run the test, but just open your log file in the eclipse audit view and you will immediately see the objects that were inserted and which ones activate the rule.

The rule will fire once for each object that have scientificName != null.

Also, your rule should not be trying to match Object if you have a more specialized class/interface that define the getScientificName() method. For instance, if you have a class named "MyDwcClass", you should write the rule like this:

rule "Scientific Name"
when 
    dwc : MyDwcClass( scientificName != null )
then
    System.out.println(dwc);
end