JBoss Drools – Defining business rules

The last two articles focused on some of the current projects that I was working on. So after kick starting Drools(4.0.7), I lost track and wrote some posts on JBoss clustering. Interesting as they were, I want to get back on defining business rules using JBoss Drools. I am just taking up from where I left off in my last Drools post. In my last post, I covered how Drools can use MS Excel spreadsheets to implement decision tables. Now I am going to talk about implementing business rules using a DRL.

The last two articles focused on some of the current projects that I was working on. So after kick starting Drools(4.0.7), I lost track and wrote some posts on JBoss clustering. Interesting as they were, I want to get back on defining business rules using JBoss Drools. I am just taking up from where I left off in my last Drools post. In my last post, I covered how Drools can use MS Excel spreadsheets to implement decision tables. Now I am going to talk about implementing business rules using a DRL. You could treat this as a tutorial.

Please find below a sample DRL file, I have implemented. The idea here is to understand the various elements and operators provided by Drools and how to utilize them in an actual business scenario.

package IssueRules

#list any import classes here.
import com.ins.Policy;
import com.ins.PolicyProduct;
import com.ins.Coverage;
import java.util.ArrayList;

#declare any global variables here
global com.ins.result.PolicyRuleResult result;
#global com.ins.PolicyProduct policyProd;

rule "Determine if any one of coverages are eligible for Issue"
	salience 100
	when
		$policy : Policy()
		exists ($coverage : Coverage(eligible == true) from $policy.coverages)
	then
		result.setEligible(Boolean.TRUE);

end

rule "Determine if all of coverages are eligible for Issue"
	salience 99
	when
		$policy : Policy()
		not (exists(Coverage(eligible == false) from $policy.coverages))

	then
		result.setAllCoveragesAreEligible(Boolean.TRUE);

end

rule "Determine if agent information captured is valid"
	salience 98
	when
		$policy : Policy( agents contains "Bill Smith")

	then
		result.setAgentInformationValid(Boolean.TRUE);

end

rule "Determine if product can be sold in the specific state"
	salience 97
	when
		$policyProd : PolicyProduct()
		Policy(issueState memberOf  $policyProd.states)
	then
		result.setApprovedState(Boolean.TRUE);

end

rule "Check out the soundex function of Drools"
	# check if any insured name matches a particular pattern
	salience 96
	when
		$policy : Policy()
		exists ($coverage : Coverage(insured.firstName soundslike 'Elizabeth') from $policy.coverages)
	then
		result.addSoundMessage("Sound Ex Works!");

end

rule "Check out the soundex function of Drools - minor change"
	# check if any insured name matches a particular pattern with a minor variation
	salience 95
	when
		$policy : Policy()
		$coverage : Coverage(insured.firstName soundslike 'Elizabeth') from $policy.coverages
	then
		result.addSoundMessage("Sound Ex Works!");

end

rule "Check out the collect function of Drools and collect functionality diff from function"
	salience 94
	when
		$policy : Policy()
		$coverages : ArrayList(size == 2)
			from collect($coverage : Coverage(insured.firstName soundslike 'Elizabeth') from $policy.coverages)
	then
		result.setSoundexWorksCollect(Boolean.TRUE);
end

rule "Check if the coverages are valid and satisfy gender, age, faceamount validation rules"
	salience 93
	#no-loop true
	when
		$policy : Policy()
		$coverage : Coverage( (faceAmount < 50000 || faceAmount > 250000) ||
								(	(insured.gender == "M" && (insured.age < 25 || insured.age > 65))
									||
									(insured.gender == "F" && (insured.age < 18 || insured.age > 65))
								)
							)
			from $policy.coverages
	then
		$coverage.setEligible(false);
		//update($policy); #Point to be noted Infinite Loop Refer: http://www.mail-archive.com/rules-users@lists.jboss.org/msg07671.html
end

rule "Return value identifier sample"
	salience 92
	#no-loop true
	when
		$policy : Policy()
		$coverage1: Coverage (faceAmount == 250000, insured.gender == "F", $age : insured.age) from $policy.coverages
		$coverage2: Coverage (insured.gender == "F", insured.age == ($age+15)) from $policy.coverages
	then
		result.setRetIdentifier(Boolean.TRUE);
		//update($policy); #Point to be noted Infinite Loop Refer: http://www.mail-archive.com/rules-users@lists.jboss.org/msg07671.html
end

rule "Compute the total and average faceamount per coverage"
	salience 91
	when
		$policy : Policy()
		$total : Number()
		from accumulate ( $coverage: Coverage($amt : faceAmount) from $policy.coverages,
							init (double total =0;),
							action (total += $amt;),
							reverse(total -= $amt;),
							result(total)
						)
	then
		result.setTotalFaceAmount(new Integer($total.intValue()));
end

rule "Compute the total in a simpler fashion"
	salience 90
	when
		$policy : Policy()
		$total : Number()
		from accumulate ( $coverage: Coverage($amt : faceAmount) from $policy.coverages,
							sum($amt)
						)
	then
		result.setTotalFaceAmountSimp(new Integer($total.intValue()));
end

rule "Compute the average faceamount per coverage"
	salience 89
	when
		$policy : Policy()
		$total : Number()
		from accumulate ( $coverage: Coverage($amt : faceAmount) from $policy.coverages,
							average($amt)
						)
	then
		result.setAverageFaceAmount(new Double($total.doubleValue()));
end

query "Get Insured details for the policy"
	$policy : Policy()
	$coverages : Coverage($insured: insured ) from $policy.coverages
end

To explain the implementation, I have created some sample Java files, Policy, PolicyProduct, Coverage and PolicyRuleResult.
##Policy.java

package com.ins;

import java.util.ArrayList;
import java.util.List;

public class Policy {

	private List<Coverage> coverages = new ArrayList<Coverage>();

	private List<String> agents = new ArrayList<String>();
	private String issueState = null;
	private List<String> sample = new ArrayList<String>();

	public List<Coverage> getCoverages() {
		return coverages;
	}

	public void setCoverages(List<Coverage> coverages) {
		this.coverages = coverages;
	}

	public void addCoverage(Coverage coverage) {
		this.coverages.add(coverage);
	}

	public List<String> getAgents() {
		return agents;
	}

	public void setAgents(List<String> agents) {
		this.agents = agents;
	}

	public void addAgent(String agentName) {
		this.agents.add(agentName);
	}

	public List<String> getSample() {
		return sample;
	}

	public void setSample(List<String> sample) {
		this.sample = sample;
	}

	public String getIssueState() {
		return issueState;
	}

	public void setIssueState(String issueState) {
		this.issueState = issueState;
	}

}

##Policy.java

##PolicyProduct.java

package com.ins;

import java.util.ArrayList;
import java.util.List;

public class PolicyProduct {

    private List<String> states = new ArrayList<String>();

    {
    	states.add("VA");
    	states.add("WI");
    	states.add("NY");
    }

	public List<String> getStates() {
		return states;
	}

	public void setStates(List<String> states) {
		this.states = states;
	}

}

##PolicyProduct.java
##Coverage.java

package com.ins;

public class Coverage {

	private boolean eligible = false;

	private Insured insured = null;

	private int faceAmount = 0;

	public boolean isEligible() {
		return eligible;
	}

	public void setEligible(boolean eligible) {
		this.eligible = eligible;
	}

	public Insured getInsured() {
		return insured;
	}

	public void setInsured(Insured insured) {
		this.insured = insured;
	}

	public int getFaceAmount() {
		return faceAmount;
	}

	public void setFaceAmount(int faceAmount) {
		this.faceAmount = faceAmount;
	}

}

##Coverage.java

##Insured.java

package com.ins;

public class Insured {

	private String firstName = null;

	private String lastName = null;

	private int age = 0;

	private String gender = null;

	public static final String GENDER_MALE = "M";
	public static final String GENDER_FEMALE = "F";

	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 int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String getGender() {
		return gender;
	}

	public void setGender(String gender) {
		this.gender = gender;
	}

}

##Insured.java

##PolicyRuleResult.java

package com.ins.result;

import java.util.ArrayList;
import java.util.List;

public class PolicyRuleResult {

	private boolean eligible = false;
	private boolean allCoveragesAreEligible = false;
	private boolean agentInformationValid = false;
	private boolean approvedState = false;
	private List<String> soundMessages = new ArrayList<String>();
	private boolean soundexWorksCollect = false;
	private boolean retIdentifier = false;
	private Integer totalFaceAmount = null;
	private Integer totalFaceAmountSimp = null;
	private Double averageFaceAmount = null;

	public boolean isAllCoveragesAreEligible() {
		return allCoveragesAreEligible;
	}

	public void setAllCoveragesAreEligible(boolean allCoveragesAreEligible) {
		this.allCoveragesAreEligible = allCoveragesAreEligible;
	}

	public boolean isEligible() {
		return eligible;
	}

	public void setEligible(boolean eligible) {
		this.eligible = eligible;
	}

	public boolean isAgentInformationValid() {
		return agentInformationValid;
	}

	public void setAgentInformationValid(boolean agentInformationValid) {
		this.agentInformationValid = agentInformationValid;
	}

	public boolean isApprovedState() {
		return approvedState;
	}

	public void setApprovedState(boolean approvedState) {
		this.approvedState = approvedState;
	}

	public void addSoundMessage(String msg) {
		this.soundMessages.add(msg);
	}

	public List<String> getSoundMessages() {
		return this.soundMessages;
	}

	public boolean isSoundexWorksCollect() {
		return soundexWorksCollect;
	}

	public void setSoundexWorksCollect(boolean soundexWorksCollect) {
		this.soundexWorksCollect = soundexWorksCollect;
	}

	public boolean isRetIdentifier() {
		return retIdentifier;
	}

	public void setRetIdentifier(boolean retIdentifier) {
		this.retIdentifier = retIdentifier;
	}

	public Integer getTotalFaceAmount() {
		return totalFaceAmount;
	}

	public void setTotalFaceAmount(Integer totalFaceAmount) {
		this.totalFaceAmount = totalFaceAmount;
	}

	public Integer getTotalFaceAmountSimp() {
		return totalFaceAmountSimp;
	}

	public void setTotalFaceAmountSimp(Integer totalFaceAmountSimp) {
		this.totalFaceAmountSimp = totalFaceAmountSimp;
	}

	public Double getAverageFaceAmount() {
		return averageFaceAmount;
	}

	public void setAverageFaceAmount(Double averageFaceAmount) {
		this.averageFaceAmount = averageFaceAmount;
	}

}

##PolicyRuleResult.java

A typical rule in Drools is specified in the following format
   rule
	salience <integer value>
	when
		<CONDITION>
	then
		<ACTION>

The salience attribute defines the priority, in case there are two rules that satisfy a given condition, the rule with higher salience value is given priority over the other. The “when” clause contains the condition to be evaluated and the “then” clause retains the action to be taken in case the condition is satisfied. There are other attributes in the Drools format, however I am restricting to the ones I have used in my example.
Let’s consider the first rule defined in the drl file.
 rule "Determine if any one of coverages are eligible for Issue"
	salience 100
	when
		$policy : Policy()
		exists ($coverage : Coverage(eligible == true) from $policy.coverages)
	then
		result.setEligible(Boolean.TRUE);
 end
The rule is essentially checking if any of the policy’s coverages are eligible to be provided cover. The Policy class has an attribute coverages whose data type is a List. Therefore, as per the rule we need to iterate over all the Coverage objects present in the policy and check if the attribute eligible within the Coverage object is set to true. From a rules point of view, we instantiate a variable reference to the Policy object by declaring line 4. We have declared a variablenamed $policy for Policy object. There no specific naming convention. policy : Policy() would have also sufficed. However $policy provides better legibility by clearly demarking policy as a variable reference. Now to iterate over the collection we add the following line:
from $policy.coverages
By using $policy.coverages, we are specifying that within the policy variable we are looking at the coverages attribute. “from” clause means we are handling a collection. We need to find out if any of the coverages has its eligible attribute set to “true” we use the following clause:

$coverage : Coverage(eligible == true) from $policy.coverages

This clause helps retrieve all coverages where eligible attribute is set to true. To confirm via a boolean condition we add the exists conditional element. So the complete clause becomes

exists($coverage : Coverage(eligible == true) from $policy.coverages)

Note all java classes referenced in the rule are added in the drl file import statements. Now that we have defined the condition let’s define the action. Apparently only global variables can be accessed in the action block. We have defined a global variable acroynmed ‘result’. As a an action we set its eligible attribute to true via line 7.

Great we are done with our first rule. Let’s write some test code to validate if it runs successfully.

package com.ins.test;

import java.io.FileReader;
import java.net.URL;
import java.util.Iterator;

import org.drools.QueryResult;
import org.drools.QueryResults;
import org.drools.RuleBase;
import org.drools.RuleBaseFactory;
import org.drools.WorkingMemory;
import org.drools.audit.WorkingMemoryFileLogger;
import org.drools.compiler.PackageBuilder;
import org.drools.rule.Package;

import com.ins.Coverage;
import com.ins.Insured;
import static com.ins.Insured.*;
import com.ins.Policy;
import com.ins.PolicyProduct;
import com.ins.result.PolicyRuleResult;

public class IssueTest {

	public static void main(String args[]) {
        try {

        	//load up the rulebase
            RuleBase ruleBase = readDRL();
            WorkingMemory workingMemory = ruleBase.newStatefulSession();

            WorkingMemoryFileLogger logger = new WorkingMemoryFileLogger(workingMemory);
            logger.setFileName("C:/drools-audit");

            Policy policy = new Policy();
            policy.addAgent("Bill Smith");
            Coverage coverage1 = new Coverage();
            coverage1.setEligible(true);
            coverage1.setFaceAmount(250000);

            Coverage coverage2 = new Coverage();
            coverage2.setEligible(true);
            coverage2.setFaceAmount(1500000);

            policy.addCoverage(coverage1);
            policy.addCoverage(coverage2);
            policy.setIssueState("CO");

            Insured insured1 = new Insured();
            insured1.setFirstName("Elizabeth");
            insured1.setAge(30);
            insured1.setGender(GENDER_FEMALE);
            coverage1.setInsured(insured1);

            Insured insured2 = new Insured();
            insured2.setFirstName("Elizabeth");
            insured2.setAge(45);
            insured2.setGender(GENDER_FEMALE);
            coverage2.setInsured(insured2);

            PolicyRuleResult result = new PolicyRuleResult();
            PolicyProduct policyProd = new PolicyProduct();

            workingMemory.insert(policy);
            workingMemory.insert(policyProd);
            workingMemory.setGlobal("result", result);
            workingMemory.fireAllRules();
            logger.writeToDisk();

            System.out.println(result.isEligible());
            System.out.println(result.isAllCoveragesAreEligible());
            System.out.println(result.isAgentInformationValid());
            System.out.println(result.isApprovedState());
            System.out.println(result.getSoundMessages());
            System.out.println(result.isSoundexWorksCollect());

            System.out.println("Cov1: " + coverage1.isEligible());
            System.out.println("Cov2: " + coverage2.isEligible());

            System.out.println("Ret Id: " + result.isRetIdentifier());
            System.out.println("Total Face Amount: " + result.getTotalFaceAmount());
            System.out.println("Total Face Amount Simp: " + result.getTotalFaceAmountSimp());
            System.out.println("Ave. Face Amount: " + result.getAverageFaceAmount());

            //Query Results
            QueryResults results = workingMemory.getQueryResults("Get Insured details for the policy");
            System.out.println( "we have " + results.size() + " insured(s)" );

            for ( Iterator it = results.iterator(); it.hasNext(); ) {
                QueryResult qResult = (QueryResult)it.next();
                Insured insured = (Insured) qResult.get( "$insured" );
                System.out.println( insured.getFirstName() + "\n" );
            }

        } catch (Throwable t) {
            t.printStackTrace();
        }
	}

	private static RuleBase readDRL() throws Exception {
		PackageBuilder builder = new PackageBuilder();
		builder.addPackageFromDrl( new FileReader(getDRLFilePath()));
		Package pkg = builder.getPackage();
		RuleBase ruleBase = RuleBaseFactory.newRuleBase();
		ruleBase.addPackage( pkg );
		return ruleBase;
	}

	private static String getDRLFilePath() {
		ClassLoader loader = Policy.class.getClassLoader();
		URL url = loader.getResource("IssueRules.drl");
		return url.getPath();
	}
}
Note that this test client covers a lot more than what is required for our current requirement, however I wanted test code to be put in once and reused for subsequent rules. Here we need to focus on the result of this line:
System.out.println(result.isEligible());
That’s all.Now let’s further enhance the rule to ensure that none of the coverages are ineligible for risk cover. Here’s the rule:

rule "Determine if all of coverages are eligible for Issue"
	salience 99
	when
		$policy : Policy()
		not (exists(Coverage(eligible == false) from $policy.coverages))

	then
		result.setAllCoveragesAreEligible(Boolean.TRUE);

end
The condition exists(Coverage(eligible == false) from $policy.coverages) checks if any one of the coverage has its eligible attribute set to false. The not conditional element makes sure that not even one of the coverage has its eligible attribute set to false.Now let’s look at two operators at the same time.

rule "Determine if agent information captured is valid"
	salience 98
	when
		$policy : Policy( agents contains "Bill Smith")

	then
		result.setAgentInformationValid(Boolean.TRUE);

end

rule "Determine if product can be sold in the specific state"
	salience 97
	when
		$policyProd : PolicyProduct()
		Policy(issueState memberOf  $policyProd.states)
	then
		result.setApprovedState(Boolean.TRUE);

end
The policy has an attribute agents of the type List. We want to verify if an agent named Bill Smith is affiliated to this policy. We verify that using the contains operator. What if its the other way around? I need to determine if a given String exists within a Collection. This is exactly the issue handled in the second rule using memberof operator. The issueState is a String attribute of Policy. There is a PolicyProduct class which maintains all the valid states for a given product. The memberof operator verifies if the specified String is present in the PolicyProduct’s Collection of states.Sometimes one needs to compare Strings on the basis of the soundex algorithm. Below are two examples using the soundslike operator provided by Drools.

rule "Check out the soundex function of Drools"
	# check if any insured name matches a particular pattern
	salience 96
	when
		$policy : Policy()
		exists ($coverage : Coverage(insured.firstName soundslike 'Elizabeth') from $policy.coverages)
	then
		result.addSoundMessage("Sound Ex Works!");

end

rule "Check out the soundex function of Drools - minor change"
	# check if any insured name matches a particular pattern with a minor variation
	salience 95
	when
		$policy : Policy()
		$coverage : Coverage(insured.firstName soundslike 'Elizabeth') from $policy.coverages
	then
		result.addSoundMessage("Sound Ex Works!");

end
I do not believe I need to elaborate, the example is self-explanatory. Now let’s understand the collect conditional element.
rule "Check out the collect function of Drools and collect functionality diff from function"
	salience 94
	when
		$policy : Policy()
		$coverages : ArrayList(size == 2)
			from collect($coverage : Coverage(eligibility == false) from $policy.coverages)
	then
		result.setSoundexWorksCollect(Boolean.TRUE);
end
Sometimes as a rules implementation we need to count the occurences of a particular event and based on the number of occurences that some action. For example, in case more than one coverages are ineligible, then take some action. To get the count we add collect conditional element after the from element and capture the objects matching the criteria in a Collection object. The Collection object size attribute is used to compare with the operational parameters.Note that unless specified otherwise the operator acting on two rules clauses is an AND operator. If we want to specify an OR operator we need to specify it explicitly. Here’s an example of an OR operator usage.

rule "Check if the coverages are valid and satisfy gender, age, faceamount validation rules"
	salience 93
	#no-loop true
	when
		$policy : Policy()
		$coverage : Coverage( (faceAmount < 50000 || faceAmount > 250000) ||
								(	(insured.gender == "M" && (insured.age < 25 || insured.age > 65))
									||
									(insured.gender == "F" && (insured.age < 18 || insured.age > 65))
								)
							)
			from $policy.coverages
	then
		$coverage.setEligible(false);
end
The condition defined above is as follows: If the faceamount is less than 50K or greater than 250K or a male insured whose age is greater than 65 or less than 25 or a female whose age is less than 18 or greater than 56, declare the coverage as ineligible.
rule "Return value identifier sample"
	salience 92
	#no-loop true
	when
		$policy : Policy()
		$coverage1: Coverage (faceAmount == 250000, insured.gender == "F", $age : insured.age) from $policy.coverages
		$coverage2: Coverage (insured.gender == "M", insured.age == ($age+15)) from $policy.coverages
	then
		result.setRetIdentifier(Boolean.TRUE);
end
Sometimes one needs to dynamically add values or compute results based on present evaluation data available within the rule condition. Drools provides the return value identifier to handle such scenarios. An example is provided below:
The condition been evaluated is that a female insured has coverage face amount == 250K and age is 15 years lesser than the male insured’s age, then the RETIdentifier is set to true.Some business rules need value computations to be done as a part of the business rules condition. Drools supports such requirements too. Here are some samples of implementations using the accumulate conditional element.

rule "Compute the total and average faceamount per coverage"
	salience 91
	when
		$policy : Policy()
		$total : Number()
		from accumulate ( $coverage: Coverage($amt : faceAmount) from $policy.coverages,
							init (double total =0;),
							action (total += $amt;),
							reverse(total -= $amt;),
							result(total)
						)
	then
		result.setTotalFaceAmount(new Integer($total.intValue()));
end

rule "Compute the total in a simpler fashion"
	salience 90
	when
		$policy : Policy()
		$total : Number()
		from accumulate ( $coverage: Coverage($amt : faceAmount) from $policy.coverages,
							sum($amt)
						)
	then
		result.setTotalFaceAmountSimp(new Integer($total.intValue()));
end

rule "Compute the average faceamount per coverage"
	salience 89
	when
		$policy : Policy()
		$total : Number()
		from accumulate ( $coverage: Coverage($amt : faceAmount) from $policy.coverages,
							average($amt)
						)
	then
		result.setAverageFaceAmount(new Double($total.doubleValue()));
end
Basically accumulate is an advanced form of the collect conditional element. The collect conditional element allowed us to collate objects in a collection satisfying certain conditions. The accumulate conditional element moves a bit further and allows us to implement computational logic on the objects. The condtional element has four portions i.e. init, action, reverse and result. In our implementation in init we have initialized our variable, in action we are incrementing the variable with the coverage’s face amount and passing the final result to the $total variable. The value of $total variable is sent to the invoking application using the result global variable. The other two examples showcase how the sum and average functions can be used within the context of accumulate conditional element.

The final feature of Drools I am going to cover is query. Drools also provides you with the ability to query the input objects. Please find below a sample code for the same.

query "Get Insured details for the policy"
	$policy : Policy()
	$coverages : Coverage($insured: insured ) from $policy.coverages
end

Please find below the snippet of Java code to retrieve the results.

            //Query Results
            QueryResults results = workingMemory.getQueryResults("Get Insured details for the policy");
            System.out.println( "we have " + results.size() + " insured(s)" );

            for ( Iterator it = results.iterator(); it.hasNext(); ) {
                QueryResult qResult = (QueryResult)it.next();
                Insured insured = (Insured) qResult.get( "$insured" );
                System.out.println( insured.getFirstName() + "\n" );
            }
I am still not sure how in real life scenarios this feature can be utilized. That’s all from the Drools desk. The only topic left to cover is Rules flow. However I will not be covering that as it needs to be explained using a pictorial representation and I just do not have the patience.
Advertisements

17 thoughts on “JBoss Drools – Defining business rules

  1. Thanks for posting your code. I came across it while searching for some Drools examples, and your code helped get me pointed in the direction I needed to go.

    Keep up the good blogging!

  2. hi

    i am using drools in my project. i came across ur blog when i wanted to learn something about drools. i tried this example and came up with the following error:

    java.lang.NullPointerException
    at com.ins.test.IssueTest.getDRLFilePath(IssueTest.java:118)
    at com.ins.test.IssueTest.readDRL(IssueTest.java:104)
    at com.ins.test.IssueTest.main(IssueTest.java:30)

    so, plz help me.

    thanks for ur kind help

    1. I think the problem should be because of the way you have set up your Drools project. Refer my previous post on Drools for the proper way of setting up Drools project.

      The DRL files should be located in the src/main/rules folder.

  3. ya. i have placed my drl file in the src/main/rules folder only. Even then it shows that error. plz suggest wat i should do?

  4. It shows the following error now: java.io.FileNotFoundException: C:\Documents and Settings\user\workspace\Policy\IssueRules.drl (The system cannot find the file specified)
    at java.io.FileInputStream.open(Native Method)
    at java.io.FileInputStream.(Unknown Source)
    at java.io.FileInputStream.(Unknown Source)
    at java.io.FileReader.(Unknown Source)
    at com.ins.test.IssueTest.readDRL(IssueTest.java:108)
    at com.ins.test.IssueTest.main(IssueTest.java:32)

    1. Jayanti,

      Please verify if you have installed the Drools Eclipse plugin and set up a Drools project. Secondly on compiling check if the drl file is copied in the bin folder or whatever folder you have specified as output. In case everything else fails provide the complete file path to load the drl file.

  5. Pingback: JavaPins
  6. Hi ,
    This very useful article on drools.I had a doubt in drools flow.

    I have two rules in my drool file one with salience 10 and other with 5.Both the rules satisfy the given condition.So, as per the drools engine the rule with highest priority will be given priority.

    My Question here is ,if the rule with salience 10 gets executed will control returns or it will execute the next rule with salience 5 and return?
    As both the rules are getting satisfied will the result of the rule with highest salience will be overrided by the the rule which gets executed next.

    Please help me on understanding how the flow will be.
    I am stuck with major issue in my project.
    Thanks in Advance.

    Lalitha.

    1. Hi Pratibha,

      The whole point of putting together the DRL tutorial is to cover business rule modeling which cannot be supported in a decision table structure. Therefore, it would be not possible to cover this DRL implementation into a decision table.

  7. Hi,

    This was a well explained tutorial which kick started my drool’s understanding. I just wanted to know how can we apply rules if a object hierarchy is like this
    PersonList class has list of persons
    Person Class has list of Addresses
    Address Class have just instance variables.
    i mean list of objects contains a class whose instance variable is a list.
    and we want ot check for a person who has address … say london

    I have gone trough lot of posts but could not find anything concrete
    however i have managed to do
    PersonList class has list of persons
    Person has just Address class but not list of addresses.

  8. This is very helpful , well explained tutorials thanks a lot.. can you give some pointers for
    drools JMX

  9. I have a list object with 5 attributes and I need to filter the entries based on conditions on certain attributes. Then apply this filtered list to another list object with each attribute from listA object is mapped to attributes in listB Object. Can you please give me an example how to implement this?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s