ILOG JRules User Guide > Executing Rules > Tasks > Executing a Ruleset Using a Native Rule Engine > Writing a Ruleset Execution Method

This section describes how to write a ruleset execution method. It also describes how you can execute rules and get the number of rules fired, get the output ruleset parameters for all output parameter pairs, set an exception handler to treat user code exceptions that may be thrown during rule execution and add the root object of an XML data file.

To write a ruleset execution method, you need to create a main class file then edit it.

To write a ruleset execution method:

  1. Load the ruleset:
    Notes
    If you have created your rules in a rule project, you will find the generated ruleset archive at the root of the Java Project for Rules (default: ruleArchive1.jar).

    Sequential debugging must be enabled before rule parsing.

try {
     // --------------------------------------------------------------------
     // Retrieve the ruleset archive JAR file using the Java I/O API.
     // --------------------------------------------------------------------
   FileInputStream fileStream = 
      new FileInputStream(the_archive_rule_name);
   JarInputStream jarStream = new JarInputStream(fileStream);
     // ----------------------------------------------
     // Create the ruleset archive parsing objects.
     // ----------------------------------------------
   IlrJarArchiveLoader loader = 
      new IlrJarArchiveLoader(jarStream);
   IlrRulesetArchiveParser parser = 
      new IlrRulesetArchiveParser();
     // ----------------------------------------------
     // Create a ruleset to store the parsed rules.
     // ----------------------------------------------
   IlrRuleset ruleset = new IlrRuleset();
     // -----------------------------------------------------------------
     // Connect the Ruleset to the Ruleset Archive parser so that
     // the parsed rules are accumulated in the Ruleset as the parsing
     // is peformed.
     // -----------------------------------------------------------------
   parser.setRuleset(ruleset);
     // ---------------------------------------------
     // Launch the parsing of the Ruleset Archive:
     // ---------------------------------------------
   if (! parser.parseArchive(loader)) {
         // -----------------------------------
         // In case of errors, list the errors.
         // -----------------------------------
       String[] errors = parser.getErrors();
       for (int i = 0; i < errors.length; i++) {
            String error = errors[i];
            System.err.println("Error while parsing Ruleset Archive:" 
                                + error);
       }
   }
   else {
       // ----------------------------------------------------------------
       // [Optional] Optimize the ruleset if in RETE and if runtime
       // resources (time) permit.
       // ----------------------------------------------------------------
       IlrRulesetOptimConfig config = new IlrRulesetOptimConfig();
       config.hasherGeneration = true;   
       
       // adapt the optimization to your needs
       config.wmModifiedByCode = false;  
       
       // adapt the optimization to your needs
       ruleset.optimize(config);
   }
catch (Exception exception) {
exception.printStackTrace(System.err);
}
  1. Create an engine based on the ruleset:
IlrContext engine = new IlrContext(ruleset);
  1. Set ruleset parameter values and insert objects in the working memory:
engine.setParameterValue("myParam",myValue);
// and so on
engine.insert(myObject);
// and so on
  1. Run the engine:
engine.execute();
  1. Prepare the rule engine for another execution:
// Retrieve objects after modification by the rule engine.
engine.retractAll();
// Clean ruleset parameter values.
engine.cleanRulesetVariables();
// Reset the ruleflow.
engine.resetRuleflow();
  1. Terminate the rule engine and free the memory (recommended):
engine.end();

Note
A parsed ruleset is not necessarily empty when the parsing occurs. If a ruleset already exists in the engine, a merge silently occurs to take into account the latest version of the rules, functions, tasks, and so on in the case of conflicts.

You can execute the rules and get the number of rules fired.

To get the number of rules fired:

IlrParameterMap output = engine.execute();
// get the number of fired rules
int ruleNumber = output.getIntValueGetting Output Parameter Values

You can get the output ruleset parameters for all output parameter pairs (String key, <type>).

To get the output ruleset parameters for all output parameter pair:

<type> value = output.get<type>Value(key);
For example: String string = output.getStringValue(key);

You can set an exception handler to treat user code exceptions that may be thrown during rule execution.

To set an exception handler:

IlrExceptionHandler exceptionHandler = new IlrExceptionHandler()
        {
            public boolean handleException(IlrUserRuntimeException ex)
            {
                if (ex.isInConditions())
                    return false;
                else
                    throw ex;
            }
        };
        engine.setExceptionHandler(exceptionHandler);
        engine.setRuleflowExceptionHandler(exceptionHandler);

This exception handler silently catches all exceptions raised during condition evaluation. All other cases (actions, and ruleflow execution) are thrown back to the engine caller, as if there were no exception handler.

If the exception handler is set for the ruleflow. For example:

?context.ruleflowExceptionHandler = new MyExceptionHandler();

the exception handler is also available in the Sequential and Fastpath algorithms.

To can also add the root object of an XML data file.

To add the root object of an XML data file:

IlrXmlObject obj = engine.loadXMLFile(xmlFileName);
engine.assert(obj);

By default, adding the root object does not do a recursive add. If you want to process rules on the other objects, therefore, you must use the in and from keywords in your rules to reach the non-added objects.

Note
The function ilrmain is not invoked when you use Rule Execution Server. If you want to add objects or parameters to the working memory, add the code in the initial actions of the ruleflow to be sure it will be invoked no matter how the ruleset is executed.

Here is an extract from a rule named MatchSession1 to illustrate the use of these keywords:

rule MatchSession1
{
when
{
?c: Conference();
?s: Session(?t: title.toLowerCase()) in ?c.sessionList;
?p: Participant() in ?c.participantList;
collect String(?t.indexOf(toLowerCase()) != -1) in ?p.interestList
where (size() >= 2);
}
...

Using an IlrXmlObjectAsserter object, you can add the following lines:

IlrXmlObjectAsserter asserter = new IlrXmlObjectAsserter(engine);
asserter.registerAllXmlClasses(); 
// Add all the objects
asserter.exploreObject (obj);

Using an IlrXmlObjectAsserter, it is possible to `filter' the objects added in the working memory. Here, all the objects have been added so there is no need to use the in or from in your rules.

Here is an extract from a rule that does not use these keywords:

rule processValidItem
{
priority=high;
when {
item: Item ( "waiting".equals(state) );
product: Product ( id.equals(item.product); stock >= item.quantity );
}
...

Use the ILOG utility classes as follows to pass a ruleset parameter as an instance of the class .w3c.dom.Element:

helper.addXMLDocumentAsParameter("Data", string, IlrRuleSessionHelper.getXmlBindingType());

The string representation can be built from an XML file by using the static method IlrUtil.getContentsAsText(FileReader file).

The following code provides an example of a complete ruleset execution class. This class is used in the code sample: samples > architecture > xmlbinding:

import ilog.rules.archive.IlrJarArchiveLoader;
import ilog.rules.archive.IlrRulesetArchiveLoader;
import ilog.rules.engine.IlrContext;
import ilog.rules.engine.IlrParameterMap;
import ilog.rules.engine.IlrRulesetArchiveParser;
import ilog.rules.xml.IlrXmlErrorException;
import ilog.rules.xml.IlrXmlObject;
import ilog.rules.xml.binding.IlrXmlDefaultDataDriver;
 
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.jar.JarInputStream;
 
public class SimpleRuleEngineRunner {
 
   public static void main(String[] args) throws Exception {
       // args[0] stores the ruleset path
       // args[1] stores the xmlFileName
       String rulesetPath = args[0];
       String xmlFileName = args[1];
       
       System.out.println("financial information is " + xmlFileName);
       System.out.println("ruleset archive is " + rulesetPath);
              
       File rulesetFile = new File(rulesetPath);
       
       JarInputStream is = new JarInputStream (new
                           FileInputStream(rulesetFile));
       
       IlrRulesetArchiveLoader rulesetloader = new IlrJarArchiveLoader(is);
       IlrRulesetArchiveParser rulesetparser = new IlrRulesetArchiveParser();
 
       boolean parsed = rulesetparser.parseArchive(rulesetloader);
 
       if (!parsed)
           return;
 
       // Create the engine
       IlrContext engine = new IlrContext(rulesetparser.getRuleset());
       
       try {
           // Read the input XML data
           IlrXmlDefaultDataDriver driver = new IlrXmlDefaultDataDriver
                                           (engine.getRuleset().getReflect());
           IlrXmlObject xmlObject = driver.readObject (new
                                                      FileReader(xmlFileName));
           
           // Set the input parameters
           IlrParameterMap inputs = new IlrParameterMap();
           inputs.setParameter("eventBatch", xmlObject);
           
           engine.setParameters(inputs);
           
           // Execute the ruleset
           IlrParameterMap outputs = engine.execute();
           
           // Write the modified XML data
           driver.writeObject(xmlObject, new FileWriter("results.xml"));
           
           // Get the number of fired rules
           int nrules = outputs.getIntValue("ilog.rules.firedRulesCount");
           
           System.out.println(nrules + " rules fired");
 
           // Clean the engine
           engine.retractAll();
           engine.end();
        } 
        catch ( IlrXmlErrorException e ) {
          e.printStackTrace();
        }
   }
};

Related Concepts

The Engine Application Programming Interface (API)

Related Tasks

Getting Notification During Ruleset Execution

Related Samples and Tutorials

Rule Engine Integration