Using Drools in Java Applications
package com.sample; import java.io.InputStreamReader;
import java.io.Reader; import org.drools.RuleBase;
import org.drools.RuleBaseFactory; import org.drools.WorkingMemory;
import org.drools.compiler.PackageBuilder; import org.drools.rule.Package;
This main function is an example showing how to use a rule package defined in a rule source file. We will see the definition of the utility method readRule that
opens a rule file and returns an instance of class RuleBase shortly. After creating an instance of RuleBase we create an instance of the M essage class and add it to
open memory:
public class DroolsTest { public static final void mainString[] args {
try { RuleBase ruleBase = readRule;
WorkingMemory workingMemory = ruleBase.newStatefulSession;
Message message = new Message; message.setMessage
Hello World ; message.setStatus Message.HELLO ;
workingMemory.insert message ; workingMemory.fireAllRules;
} catch Throwable t { t.printStackTrace;
} }
The main method creates a new rule base and working memory. Working memory is responsible for maintaining the “facts” in the system – in this case facts are Plain
Old Java Objects POJOs that are maintained in a collection.
An instance of class M essage is created and its status is set to the constant value M essage.HELLO. We saw in the last section how the first example rule has a
condition that allows the rule to “fire” if there is any instance of class M essage that has its status attribute set to this value.
The method f ireAllRules will keep identifying rules that are eligible to fire, choos- ing a rule from this active set using algorithms we will discuss later, and then repeat-
78
ing this process until no more rules are eligible to fire. There are other f ireAllRules methods that have arguments for a maximum number of rules to fire and a filter to
allow only some eligible rules to execute.
Please note that this is the low level rule assembly API.
private static RuleBase readRule throws Exception {
read in the source Reader source =
new InputStreamReader DroolsTest.class.
getResourceAsStreamSample.drl; optionally read in the DSL if you are using one:
Reader dsl = new InputStreamReader
DroolsTest.class. getResourceAsStreammylang.dsl;
The method readRule is a utility for reading and compiling a rule file that was generated automatically by the Eclipse Drools Workbench; in general your projects
will have one or more rules files that you will load as in this example. In method readRule we opened an input stream reader on the source code for the example
Drools rule file Sample.drl. Drools has the ability to modify the rule syntax to create Domain Specific Languages DSLs that match your application or business
domain. This can be very useful if you want domain experts to create rules since they can “use their own language.” We will not cover custom DSLs in this chapter
but the Drools documentation covers this in detail. Here is the rest of the definition of method readRule:
Use package builder to build up a rule package: PackageBuilder builder = new PackageBuilder;
This will parse and compile in one step: builder.addPackageFromDrlsource;
Use the following instead of above if you are using a custom DSL:
builder.addPackageFromDrl source, dsl ;
79
get the compiled package which is serializable Package pkg = builder.getPackage;
add the package to a rulebase deploy the rule package.
RuleBase ruleBase = RuleBaseFactory.newRuleBase; ruleBase.addPackage pkg ;
return ruleBase;
} The readRule utility method can be copied to new rule projects that are not created
using the Eclipse Drools Workbench and modified as appropriate to get you started with the Java “boilerplate” required by Drools. This implementation uses Drools
defaults, the most important being the “conflict resolution strategy” that defaults to first checking the most recently modified working memory POJO objects to see
which rules can fire. This produces a depth first search behavior. We will modify the readRule utility method later in Section 5.4 when we will need to change this
default Drools reasoning behavior from depth first to breadth first search.
We will need a Plain Old Java Object POJO class to represent messages in the example rule set. This demo class was generated by the Eclipse Drools Workbench:
public static class Message { public static final int HELLO = 0;
public static final int GOODBYE = 1; private String message;
private int status; public String getMessage {
return this.message; }
public void setMessageString message { this.message = message;
} public int getStatus {
return this.status; }
public void setStatus int status { this.status = status;
80
} }
}
You might want to review the example rules using this POJO Message class in Sec- tion 5.2. Here is the sample output from running this example code and rule set:
Hello World Goodbye cruel world
A simple example, but it serves to introduce you the Drools rule syntax and required Java code. This is also a good example to understand because when you use the
Eclipse Drools Workbench to create a new Drools rule project, it generates this example automatically as a template for you to modify and re-use.
In the next two sections I will develop two more complicated examples: solving blocks world problems and supporting a help desk system.