Chapter 22. Hello World Example
22.1. HelloWorld Example: Creating the KnowledgeBase and Session
final KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(); // this will parse and compile in one step kbuilder.add(ResourceFactory.newClassPathResource("HelloWorld.drl", HelloWorldExample.class), ResourceType.DRL); // Check the builder for errors if (kbuilder.hasErrors()) { System.out.println(kbuilder.getErrors().toString()); throw new RuntimeException("Unable to compile \"HelloWorld.drl\"."); } // get the compiled packages (which are serializable) final Collection<KnowledgePackage> pkgs = kbuilder.getKnowledgePackages(); // add the packages to a KnowledgeBase (deploy the knowledge packages). final KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(); kbase.addKnowledgePackages(pkgs); final StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
- A
KnowledgeBuilder
is used to turn a DRL source file intoPackage
objects which the Knowledge Base can consume. - The add method takes a
Resource
interface and a Resource Type as parameters. TheResource
can be used to retrieve a DRL source file from various locations; in this case the DRL file is being retrieved from the classpath using aResourceFactory
, but it could come from a disk file or a URL. - Multiple packages of different namespaces can be added to the same Knowledge Base.
- While the Knowledge Base will validate the package, it will only have access to the error information as a String, so if you wish to debug the error information you should do it on the
KnowledgeBuilder
instance. - Once the builder is error free, get the
Package
collection, instantiate aKnowledgeBase
from theKnowledgeBaseFactory
and add the package collection.
22.2. HelloWorld Example: Event Logging and Auditing
// setup the debug listeners ksession.addEventListener( new DebugAgendaEventListener() ); ksession.addEventListener( new DebugWorkingMemoryEventListener() ); // setup the audit logging KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, "log/helloworld");
- Two default debug listeners are supplied:
DebugAgendaEventListener
andDebugWorkingMemoryEventListener
. These print out debug event information to theSystem.err
stream displayed in the Console window. - The
KnowledgeRuntimeLogger
provides execution auditing which can be viewed in a graphical viewer. This logger is a specialised implementation built on the Agenda and Working Memory listeners. - When the engine has finished executing,
logger.close()
must be called.
22.3. HelloWorld Example: Message Class
public static class Message { public static final int HELLO = 0; public static final int GOODBYE = 1; private String message; private int status; ... }
- The single class used in this example has two fields: the message, which is a String, and the status which can be one of the two integers
HELLO
orGOODBYE
.
22.4. HelloWorld Example: Execution
final Message message = new Message(); message.setMessage("Hello World"); message.setStatus(Message.HELLO); ksession.insert(message); ksession.fireAllRules(); logger.close(); ksession.dispose();
- A single
Message
object is created with the message text "Hello World" and the statusHELLO
and then inserted into the engine, at which pointfireAllRules()
is executed. - All network evaluation is done during the insert time. By the time the program execution reaches the
fireAllRules()
method call the engine already knows which rules are fully matches and able to fire.
Note
To execute the example as a Java application:
- Open the class
org.drools.examples.helloworld.HelloWorldExample
in your Eclipse IDE. - Right-click the class and select
Run as...
and thenJava application
22.5. HelloWorld Example: System.out in the Console Window
Hello Goodbye
==>[ActivationCreated(0): rule=Hello World; tuple=[fid:1:1:org.drools.examples.helloworld.HelloWorldExample$Message@17cec96]] [ObjectInserted: handle=[fid:1:1:org.drools.examples.helloworld.HelloWorldExample$Message@17cec96]; object=org.drools.examples.helloworld.HelloWorldExample$Message@17cec96] [BeforeActivationFired: rule=Hello World; tuple=[fid:1:1:org.drools.examples.helloworld.HelloWorldExample$Message@17cec96]] ==>[ActivationCreated(4): rule=Good Bye; tuple=[fid:1:2:org.drools.examples.helloworld.HelloWorldExample$Message@17cec96]] [ObjectUpdated: handle=[fid:1:2:org.drools.examples.helloworld.HelloWorldExample$Message@17cec96]; old_object=org.drools.examples.helloworld.HelloWorldExample$Message@17cec96; new_object=org.drools.examples.helloworld.HelloWorldExample$Message@17cec96] [AfterActivationFired(0): rule=Hello World] [BeforeActivationFired: rule=Good Bye; tuple=[fid:1:2:org.drools.examples.helloworld.HelloWorldExample$Message@17cec96]] [AfterActivationFired(4): rule=Good Bye]
- By putting a breakpoint on the
fireAllRules()
method and select theksession
variable, you can see that the "Hello World" rule is already activated and on the Agenda, confirming that all the pattern matching work was already done during the insert. - The application print outs go to
System.out
while the debug listener print outs go toSystem.err
.
22.6. HelloWorld Example: Rule "Hello World"
rule "Hello World" dialect "mvel" when m : Message( status == Message.HELLO, message : message ) then System.out.println( message ); modify ( m ) { message = "Goodbye cruel world", status = Message.GOODBYE }; end
- The LHS (after
when
) section of the rule states that it will be activated for eachMessage
object inserted into the Working Memory whose status isMessage.HELLO
. - Two variable bindings are created: the variable
message
is bound to themessage
attribute and the variablem
is bound to the matchedMessage
object itself. - The RHS (after
then
) or consequence part of the rule is written using the MVEL expression language, as declared by the rule's attributedialect
. - After printing the content of the bound variable
message
toSystem.out
, the rule changes the values of themessage
andstatus
attributes of theMessage
object bound tom
. - MVEL's
modify
statement allows you to apply a block of assignments in one statement, with the engine being automatically notified of the changes at the end of the block.
22.7. HelloWorld Example: Using the "Debug as..." Option
Procedure 22.1. Task
- To access this debugging option, open the class
org.drools.examples.HelloWorld
in your Eclipse IDE. - Right-click the class and select "Debug as..." and then "Drools application". The rule will be shown along with information about where it is.
22.8. HelloWorld Example: Rule "Good Bye"
rule "Good Bye" dialect "java" when Message( status == Message.GOODBYE, message : message ) then System.out.println( message ); end
- The "Good Bye" rule, which specifies the "java" dialect, is similar to the "Hello World" rule except that it matches
Message
objects whose status isMessage.GOODBYE