Drools Tutorial for Beginners using Drools 6 and Eclipse

Drools Logo

DroolsThis drools tutorial for beginners explains, step by step, how to write first Drools rule, and how to run it. We would be using Drool 6.4.0, Java 1.8, and Drools Eclipse Plugin in this Drools tutorial. Let us keep this first Drools example as standalone Java program i.e. run it using a Java class and park web/enterprise application usage for later.

Before getting into this first Drool example, we try to understand few basic concepts about rules and rule engines. This may not be little boring for developers who already know about rules, but this Drool tutorial targets beginners, hence good to start with elementary concepts. Also, we would keep away from complex and advance concepts of rule and rule engine.

What is a Rule?

In very simple terms, a rule is a condition. For example “If this is true, then do this”. Example – “If employee id is blank, don’t process”, or “if customer type is x, give special discount”. Rules are conditions that are used to make certain decisions based on available data.

Rules will be different in different business context, and off course more complex than above example. But underlying concept remains same, these are just conditions, simple one dimensional or involving multiple dimensions and aspects, variables, and much more data. Here we keep it simple for example implementation purpose – if customer first name is “Deepak”, we return a message – first name is Deepak.

Why do you need a Rule Engine?

Now just imagine, in a business scenario there are few hundred, or a couple of thousands rules, and we want to implement those rules in our program. Code will get flooded with condition statements. As conditions directly contribute to complexity of code, and complex code is less maintainable. It will be nightmare to maintain such code. Hence, it is wise to separate these rules from core functional code. Also, in a complex scenario, it is not only conditional statement that contribute to rules, but data is also an important part. Further management of these rules and data is also very important. Why should these aspects create burden on a developer implementing functionality. Hence all such rule related operations are moved out to a separate application/tool called rule engine. There are many more aspects of rule engine, like what should be execution sequence, how versioning will happen, generally rules are maintained by business users; hence how business user will update and test rules. So many things are there. To address all this, where there are more number of rules involved (no specific number, but something that makes application complex), a rule engine is required. Actually with all these features, a rule engine which manages business rule and rule related aspects, becomes a Business Rule Management i.e. BRM system.

Which are popular Rule Engines?

There are many open source and proprietary rule engines that cost zero to millions of dollars. All these rule engines definitely provide basic feature of rule maintenance. But cost varies with additional sophisticated features and algorithms, etc. Hence one needs to be very careful while taking decision, if one goes for rule engine and which rule engine. I’ll not mention any rule engine name and favor it, instead leave it to readers to search those on Google.

Why and when Drools?

First important reason is – it is free. But free is not the only thing that makes it popular. Drools provides many features that are necessary for business rule management. Drools provides multiple ways maintaining Drools. It has user interface, called as Drools workbench. There are plugins for IDEs like Eclipse. It has robust rule execution algorithm. Also there are multiple architecture patterns in which one can use Drools in enterprise solutions (bit complex for beginner).

When? When you know you have enough number of rules to manage and those will make your code clumsy, go for rule engine. Also if you haven’t got any fancy, necessary requirement of rule management, performance, etc. that can not be fulfilled by Drools, go for any other rule engine. But in general cases Drools is enough to serve simple to certain complex business rule requirements.

Pre Drool Installation Setup

Now let us start with our first drools example. What all we need? Below is the list of software you should have on your machine.

  • JDK (for this example I am using Java 1.8)
  • Eclipse IDE (here latest Eclipse IDE is used Mars), also remember to select Eclipse version suitable for Java and JEE applications.

Download these software and complete set up that includes environments variables i.e. Path and Classpath for Java.

Download Drools Plugin

For a beginner Drools programmer, it is better to start with Drools Plugin for Eclipse. It is available at Drools download page under Drools and jBPM tools heading. Download this zip file from location as shown below.

http://www.drools.org/download/download.html

Drools Plugin Download

Install Drools Plugin for Eclipse

Next step is installing this plugin in Eclipse. If you have done this activity earlier, then there is no difference in steps. Otherwise below are the steps to install Drools Eclipse Plugin.

Extract downloaded Distribution Zip (droolsjbpm-tools-distribution-6.4.0.Final.zip) in a folder. We are going to use Eclipse feature to add new software, which is available at menu link of Eclipse “Help -> Install New Software”. As show below, select “Add” option on this screen to add repository. In add repository screen select Local option and browse to org.drools.updatesite folder in extracted Drools plugin. Complete installation.

Install Drools Plugin

Creating First Drools Project

Now let us create our first Drools project in Eclipse. Before that, let us switch to Drools perspective in Eclipse. It will display Eclipse view suitable for Drools and Java development. Drools perspective can be changed at top right corner of Eclipse by selecting Drools option from “Open Perspective” menu as shown below.

Open Drools Perspective

From File menu of Eclipse, select New option, and create a Drools Project. On clicking New -> Drools Project link, it will open following screen.

Creat Drools Project

This screen shows three self-explanatory options. As a beginner, second option is better. Why? It creates working examples along with a working project. Not only that, it does complete set up required to run these examples. What all it does for you?

  • Creating directory structure required for a Java project
  • Creating directory structure required for a Drools program
  • Including all libraries required to create, compile and run rules
  • A kmodule XML required define Drools rule environment and to create kSession to execute rules
  • Maven structure to run this program as a Maven project (we are not going to use it here)

In short, it makes a beginners life very easy. Otherwise, one will end up spending hours to sort out all these things and going through many pages of documentation.

Below is the screen, with example data to be filled while creating a Drools project. We are adding just a Drools rule example for now. Hence decision table and process option is not selected.

Create Drools Project

Once the project is created, you can delete the .drl file created under src/main/resources and Java files created along with java package.

And we are going to add two new Java files and one rule file as below as a part of our example. Location of these files can be seen in image below.

  • Create a java package you require
  • java – Customer object to be used to exchange data with rule
  • java – containing main method to run rule
  • CustomerRule.drl – contains actual rule

Drools Project Structure

Let us take a closer look at these files.

CustomerRuleObject.java

package net.deepakgaikwad.drools;

public class CustomerRuleObject {
	
	private String firstName;
	
	private String lastName; 
	
	private String message = "";
	
	public String getFirstName() {
		return firstName;
	}
	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}
	public String getLastName() {
		return lastName;
	}
	public void setLastName(String lastName) {
		this.lastName = lastName;
	}
	public String getMessage() {
		return message;
	}
	public void setMessage(String message) {
		this.message = message;
	}
	

}

In this file, we have three attributes, first two are related to Customer name and remaining attribute “message”, to be used to exchange data between rule and Java program.

RunRule.java

package net.deepakgaikwad.drools;

import org.kie.api.KieServices;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;

public class RunRule {

	public static void main(String[] args) {
		
        try {
            // load up the knowledge base
	        KieServices ks = KieServices.Factory.get();
    	    KieContainer kContainer = ks.getKieClasspathContainer();
        	KieSession kSession = kContainer.newKieSession("ksession-rules");
        	
        	CustomerRuleObject customerRuleObject = new CustomerRuleObject();
        	customerRuleObject.setFirstName("Deepak");
            kSession.insert(customerRuleObject);
            kSession.fireAllRules();
            
            System.out.println(customerRuleObject.getMessage());
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

}

We are keeping focus on executing the rule. If we take a look at this file in detail you can see following steps implemented in code –

  • Create KieSession using few other classes provided by Drools starting name with “Kie”
  • This session is created using the rule configuration in kmodule.xml. kmodule.xml given below defines rule kbase (knowledge base earlier version name) comprising “rules” package and has session name as “ksession-rules”. One can control many things in Drools rule configuration and execution using this file. For now it is an advance topic.
  • Create CustomerRuleObject and set first name attribute which is required for our rule test
  • Add this object to KSession. This object is going to be used to exchange information between rule and Java program. This is also containing the data required to execute rule
  • Fire all rules using KSession
  • Print result from message attribute

 

kmodule.xml

<?xml version="1.0" encoding="UTF-8"?>
<kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule">
    <kbase name="rules" packages="rules">
        <ksession name="ksession-rules"/>
    </kbase>
</kmodule>

CustomerRule.drl

package rules

import net.deepakgaikwad.drools.CustomerRuleObject;

dialect "java" 

rule "CustomerRule"

    when
        customerRuleObject:CustomerRuleObject (getFirstName() == 'Deepak' )
    then
        customerRuleObject.setMessage(customerRuleObject.getMessage()+'First Name is ' + customerRuleObject.getFirstName());
end

Let us understand details of this rule file.

  • First line is package matching to package defined in kmodule.xml or vice versa
  • “import” is used to import the Java classes required in rule below
  • “dialect” is syntax used for rule writing below. Default is “java”, hence we could have run this program by excluding dialect line, but it is written to make things explicit. Other dialect is “mvel” which is for Drools expression language used to define rules.
  • Next we are writing actual condition. Just take a closer look at how we are using the input object getter and setter methods. If we would have declared attributes public then we could have used those directly.

Finally, if you run this program, i.e. main method of RunRule.java class, it will print message “First Name is Deepak” on console as the input object contain firstName attribute set to “Deepak” and in rule, we are checking if the firstName is “Deepak”, then return this message, which we are printing in main method last line.

That’s it. Your basic set up to write Java based Drools rules is ready. Now you can go for complex rules from this Drools Tutorial for Beginners.

3 Comments

  1. Hi ,I am new to this so can you please help me out in step by step to create and consume the drools in asp.net MVC project??

  2. Nice article!

    I am trying the steps for the first drool project, and run into the following issues:

    1. in CustomerRule.drl, it highlights the following errors at Line 7 i.e. rule “CustomerRule”
    Rule Compilation error Only a type can be imported. com.sample.CustomerRuleObject resolves to a package
    Only a type can be imported. org.drools.core.spi.KnowledgeHelper resolves to a package
    KnowledgeHelper cannot be resolved to a type
    com.sample.CustomerRuleObject cannot be resolved to a type
    org.kie.api.runtime.rule.FactHandle cannot be resolved to a type
    java.lang.Exception cannot be resolved to a type
    org.kie.api.runtime.rule.RuleContext cannot be resolved to a type

    I am able to resolve the errors by change dialect from “java” to “mvel”. Why does it have to be “mvel”?

    How to specify dialect in Excel spreadsheet? (I am asking since I saw the same errors in Sample.xls in the generated spreadsheet example.

    2. when I set a breakpoint in CustomerRule.drl (i.e. Line 12), and debug RunRule.java as Drools Application, it threw the error:

    java.lang.RuntimeException: no debugger registered to handle breakpoint
    at org.mvel2.debug.DebuggerContext.checkBreak(DebuggerContext.java:98)
    at org.mvel2.MVELRuntime.execute(MVELRuntime.java:76)
    at org.mvel2.compiler.CompiledExpression.getDirectValue(CompiledExpression.java:123)
    at org.mvel2.compiler.CompiledExpression.getValue(CompiledExpression.java:119)
    at org.mvel2.compiler.CompiledExpression.getValue(CompiledExpression.java:113)
    at org.mvel2.MVEL.executeExpression(MVEL.java:929)
    at org.drools.core.util.MVELSafeHelper$RawMVELEvaluator.executeExpression(MVELSafeHelper.java:496)
    at org.drools.core.rule.constraint.MvelConditionEvaluator.evaluate(MvelConditionEvaluator.java:114)
    at org.drools.core.rule.constraint.MvelConditionEvaluator.evaluate(MvelConditionEvaluator.java:89)
    at org.drools.core.rule.constraint.MvelConstraint.evaluate(MvelConstraint.java:258)
    at org.drools.core.rule.constraint.MvelConstraint.isAllowed(MvelConstraint.java:214)
    at org.drools.core.reteoo.AlphaNode.assertObject(AlphaNode.java:131)
    at org.drools.core.reteoo.SingleObjectSinkAdapter.propagateAssertObject(SingleObjectSinkAdapter.java:63)
    at org.drools.core.reteoo.ObjectTypeNode.propagateAssert(ObjectTypeNode.java:300)
    at org.drools.core.phreak.PropagationEntry$Insert.execute(PropagationEntry.java:93)
    at org.drools.core.phreak.SynchronizedPropagationList.flush(SynchronizedPropagationList.java:78)
    at org.drools.core.phreak.SynchronizedPropagationList.flush(SynchronizedPropagationList.java:73)
    at org.drools.core.impl.StatefulKnowledgeSessionImpl.flushPropagations(StatefulKnowledgeSessionImpl.java:2017)
    at org.drools.core.common.DefaultAgenda.fireLoop(DefaultAgenda.java:1334)
    at org.drools.core.common.DefaultAgenda.fireAllRules(DefaultAgenda.java:1288)
    at org.drools.core.impl.StatefulKnowledgeSessionImpl.internalFireAllRules(StatefulKnowledgeSessionImpl.java:1306)
    at org.drools.core.impl.StatefulKnowledgeSessionImpl.fireAllRules(StatefulKnowledgeSessionImpl.java:1297)
    at org.drools.core.impl.StatefulKnowledgeSessionImpl.fireAllRules(StatefulKnowledgeSessionImpl.java:1278)
    at com.sample.RunRule.main(RunRule.java:20)

    Do I need to register a debugger manually?

    p.s. I installed drools plugin in Eclipse Neon, and use 6.4.0.Final as Drools runtime. No errors during the installation.

    Thanks!

  3. Nice article!
    I am trying the steps for the first drool project, and run into the following issues:
    1. in CustomerRule.drl, it highlights the following errors at Line 7 i.e. rule “CustomerRule”
    Rule Compilation error Only a type can be imported. com.sample.CustomerRuleObject resolves to a package
    Only a type can be imported. org.drools.core.spi.KnowledgeHelper resolves to a package
    KnowledgeHelper cannot be resolved to a type
    com.sample.CustomerRuleObject cannot be resolved to a type
    org.kie.api.runtime.rule.FactHandle cannot be resolved to a type
    java.lang.Exception cannot be resolved to a type
    org.kie.api.runtime.rule.RuleContext cannot be resolved to a type
    I am able to resolve the errors by change dialect from “java” to “mvel”. Why does it have to be “mvel”?
    How to specify dialect in Excel spreadsheet? (I am asking since I saw the same errors in Sample.xls in the generated spreadsheet example.
    2. when I set a breakpoint in CustomerRule.drl (i.e. Line 12), and debug RunRule.java as Drools Application, it threw the error:
    java.lang.RuntimeException: no debugger registered to handle breakpoint
    at org.mvel2.debug.DebuggerContext.checkBreak(DebuggerContext.java:98)
    at org.mvel2.MVELRuntime.execute(MVELRuntime.java:76)
    at org.mvel2.compiler.CompiledExpression.getDirectValue(CompiledExpression.java:123)
    at org.mvel2.compiler.CompiledExpression.getValue(CompiledExpression.java:119)
    at org.mvel2.compiler.CompiledExpression.getValue(CompiledExpression.java:113)
    at org.mvel2.MVEL.executeExpression(MVEL.java:929)
    at org.drools.core.util.MVELSafeHelper$RawMVELEvaluator.executeExpression(MVELSafeHelper.java:496)
    at org.drools.core.rule.constraint.MvelConditionEvaluator.evaluate(MvelConditionEvaluator.java:114)
    at org.drools.core.rule.constraint.MvelConditionEvaluator.evaluate(MvelConditionEvaluator.java:89)
    at org.drools.core.rule.constraint.MvelConstraint.evaluate(MvelConstraint.java:258)
    at org.drools.core.rule.constraint.MvelConstraint.isAllowed(MvelConstraint.java:214)
    at org.drools.core.reteoo.AlphaNode.assertObject(AlphaNode.java:131)
    at org.drools.core.reteoo.SingleObjectSinkAdapter.propagateAssertObject(SingleObjectSinkAdapter.java:63)
    at org.drools.core.reteoo.ObjectTypeNode.propagateAssert(ObjectTypeNode.java:300)
    at org.drools.core.phreak.PropagationEntry$Insert.execute(PropagationEntry.java:93)
    at org.drools.core.phreak.SynchronizedPropagationList.flush(SynchronizedPropagationList.java:78)
    at org.drools.core.phreak.SynchronizedPropagationList.flush(SynchronizedPropagationList.java:73)
    at org.drools.core.impl.StatefulKnowledgeSessionImpl.flushPropagations(StatefulKnowledgeSessionImpl.java:2017)
    at org.drools.core.common.DefaultAgenda.fireLoop(DefaultAgenda.java:1334)
    at org.drools.core.common.DefaultAgenda.fireAllRules(DefaultAgenda.java:1288)
    at org.drools.core.impl.StatefulKnowledgeSessionImpl.internalFireAllRules(StatefulKnowledgeSessionImpl.java:1306)
    at org.drools.core.impl.StatefulKnowledgeSessionImpl.fireAllRules(StatefulKnowledgeSessionImpl.java:1297)
    at org.drools.core.impl.StatefulKnowledgeSessionImpl.fireAllRules(StatefulKnowledgeSessionImpl.java:1278)
    at com.sample.RunRule.main(RunRule.java:20)
    Do I need to register a debugger manually?
    p.s. I installed drools plugin in Eclipse Neon, and use 6.4.0.Final as Drools runtime. No errors during the installation.
    Thanks!

Leave a Reply

Your email address will not be published.


*