Plugin

Maven Drools Plugin

The Maven Drools Plugin supports compilation of knowledge source code (*.DRL) for the Drools Rule Engine into a binary format suitable for both loading into the rule engine and re-using while compiling other knowledge source files.

The whole process is a lot like compiling Java classes and packaging them as JARs:

Besides re-using Drools knowledge artifacts, the plugin also supports specifying which Java JAR files you want to have available in your Drools knowledge sources.

Objectives

Goals

Create and maintain a Maven 3.x plugin which...

  • compiles *.drl source code files into pre-compiled, binary files containing serialized KnowledgePackages, called Drools Knowledge Modules, *.dkm. These are to rule applications what *.jar is to vanilla Java applications.
  • can aggregate multiple *.dkm files, potentially with inter-dependencies, into a Drools Knowledge Archive, allowing easy loading of all the knowledge modules by an application (these are to rule applications what *.war is to web applications)
  • supports modular, binary reuse of business rules: *.dkm files can depend on other *.dkm files or java libraries (*.jar)
  • is general purpose: can be used in a wide range of projects requiring compilation of Drools rules
  • is readily available: plugin and all its depdencies can be obtained from a public maven repository; mid-term goal: obtainable from Maven Central
  • is well-documented: potential users can start using it in their projects right away

Basic Concepts

Maven Drools Plugin: Basic concepts

Rules made available to the Drools rule engine in its most basic form are defined using text files ending in .drl. Although Drools does support other file formats for various other knowledge types, these formats are out of scope unless a plugin user requests support for them.

The textual rule representation has to be converted into a more suitable form before they can be run inside the Drools rule engine. There are various options regarding the how and when to perform this conversion, details of which can be found in the Drools Expert User Guide. This conversion step is called building or compiling the rule source code.

This plugin is intended to support rules compilation as part of a Maven build, which could run locally on a developer machine or on a continuous integration server. In addition, it allows you to deploy the compiled rule artifacts into a Maven repository for later (re-) use. You can even use a deployed rules artifact as a Maven dependency of another rules project, which comes handy if one subset of your rule base contains a function definition or a declared type which should be used in another, distinct subset of your rule base.

To allow for this kind of reuse, the plugin defines a new Maven packaging type called knowledge-module. The file extension assigned to the resulting artifacts is .dkm which stands for Drools Knowledge Module. For the time being, files of this type merely contain a Collection<KnowledgePackage>, but this will change in the near future: there will be a header with various version numbers prepended.

Usage

Prerequisites

  • Use Maven 3.0.x (x >= 3)
  • Starting with version 0.3.1, the plugin is available from Maven Central. No configuration of additional remote repositories necessary.

Usage Example

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.example</groupId>
  <artifactId>example-knowledge-module</artifactId>
  <version>1.0.0</version>
  <packaging>knowledge-module</packaging>    <!-- notice the new packaging type -->

  <name>An example Drools Knowledge Module</name>

  <build>
    <plugins>
      <plugin>
        <groupId>de.lightful.maven.plugins</groupId>
        <artifactId>maven-drools-plugin</artifactId>
        <version>0.3.1</version>
        <!-- vv== set extensions flag to true: this makes packaging type available to build -->
        <extensions>true</extensions>
        <!-- Depending on Drools runtime desired, define correct version of these dependencies: -->
        <dependencies>
          <dependency>
            <groupId>org.drools</groupId>
            <artifactId>knowledge-api</artifactId>
            <version>[5.3.0.Final]</version>
          </dependency>
          <dependency>
            <groupId>org.drools</groupId>
            <artifactId>drools-core</artifactId>
            <version>[5.3.0.Final]</version>
          </dependency>
          <dependency>
            <groupId>org.drools</groupId>
            <artifactId>drools-compiler</artifactId>
            <version>[5.3.0.Final]</version>
          </dependency>
        </dependencies>
        <configuration>
          <passes>
            <pass>
              <name>First Pass</name>
              <ruleSourceRoot>${basedir}/src/main/rules/pass-one</ruleSourceRoot>
              <includes>
                <include>**/*.drl</include>
              </includes>
              <excludes>
                <exclude>**/Test*.drl</exclude>
              </excludes>
            </pass>
          </passes>
        </configuration>
      </plugin>
    </plugins>
  </build>

  <dependencies>
    <!-- these are (actually existing) example dependencies -->
    <!-- used for testing the plugin:                       -->
    <!--
         Not yet available from Maven Central. If you'd like
         to use them, configure 

           http://lightful.de/mvnrepo/public/releases

         as an additional Maven remote repository.
    -->
    <dependency>
      <groupId>de.lightful.maven.drools.plugin.itartifacts</groupId>
      <artifactId>drools-fruit-types-5.3.0.Final</artifactId>
      <version>0.1.2</version>
      <type>dkm</type> <!-- use dkm as type specifier in dependencies -->
    </dependency>
    <dependency>
      <groupId>de.lightful.maven.drools.plugin.itartifacts</groupId>
      <artifactId>cities-fact-model</artifactId>
      <version>0.0.18</version>
    </dependency>
  </dependencies>

</project>

A few things to notice

  • specify the packaging type as knowledge-module
  • you can list as many <pass>es as you want. The passes are executed sequentially in declaration order.
    Multiple passes caters to the use-case of using Drools' declare keyword to create user-defined types which are then used in other source files. Since the regular KnowledgeBuilder does not support forward references, one has to sort out dependencies manually. Introducing multiple compiler passes with different sets of files to compile helps to alleviate this problem.
  • each <pass> can have one <name> which is just a name echoed on the console during compilation. If you don't specify one, a default name will be generated.
  • each <pass> can contain a <ruleSourceRoot> specifying where all the rules for this pass must live.
  • each <pass> can contain <includes> and <excludes>, which should be known from various other plugins. If you don't specify any includes, a default include **/*.drl will be used. The default excludes set is empty.
  • You must not include the Drools runtime libraries (like drools-compiler, drools-core etc.) into the <dependencies> section of the knowledge module. The runtime libraries have to be defined as dependencies of the plugin, like shown in the example. If you forget about this, you will get nasty class cast exceptions: the runtime libraries will be loaded twice, each by different class loaders. For details, see this FAQ entry.
  • Supported Drools runtime versions: 5.3.0.Final, 5.4.0.Final. Support for older Drools versions was dropped with plugin version 0.3.1 due to breaking API changes in Drools.

Example output

Call mvn clean verify on the example project above with a few rules in src/main/rules/pass-one and you will get something like:

[INFO] --- maven-drools-plugin:0.2.4:compile (default-compile) @ example-knowledge-module ---
... maven download logging skipped for brevity ...
[INFO] This is the compiler plugin
[INFO] Passes: [Pass{name='First Pass', ruleSourceRoot=/home/someuser/example-knowledge-module/src/main/rules/pass-one, includes=[**/*.drl], excludes=[**/Test*.drl]}]
[INFO] Project: An example Drools Knowledge Module
[INFO] Pass #1:
[INFO]     Name:             'First Pass'
[INFO]     Rule Source Root: /home/someuser/example-knowledge-module/src/main/rules/pass-one
[INFO]     Includes:         ['**/*.drl']
[INFO]     Excludes:         ['**/Test*.drl']
[INFO] Using Drools Runtime version 5.3.0.Final
[INFO] Resolved dependencies of com.example:example-knowledge-module:dkm:1.0.0 (compile).
[INFO] 

Using class loader with these URLs:
[INFO] URL in use (#1): file:/home/someuser/.m2/repository/de/lightful/maven/drools/plugin/itartifacts/cities-fact-model/0.0.18/cities-fact-model-0.0.18.jar
[INFO] Loaded drools dependency de.lightful.maven.drools.plugin.itartifacts:drools-fruit-types-5.3.0.Final:dkm:0.1.2
[INFO]   Contains packages:
[INFO]     model.fruit
[INFO]       type 'WeightOfFruit': 
[INFO]         field 'fruit' is of type model.fruit.Fruit
[INFO]         field 'weight' is of type java.lang.Integer
[INFO]       type 'Fruit': 
[INFO]         field 'name' is of type java.lang.String
[INFO] Executing compiler pass 'First Pass'...
[INFO]   Compiling rule file '/home/someuser/example-knowledge-module/src/main/rules/pass-one/cool-rule.drl' ...
[INFO] Done with compiler pass 'First Pass'.
[INFO] Writing 1 knowledge packages into output file /home/someuser/example-knowledge-module/target/example-knowledge-module-1.0.0.dkm
[INFO]   Package #1: com.example.pricing (1 rules)
[INFO] Setting project artifact to /home/someuser/example-knowledge-module/target/example-knowledge-module-1.0.0.dkm
[INFO] 
[INFO] --- maven-compiler-plugin:2.3.2:testCompile (default-testCompile) @ example-knowledge-module ---
[WARNING] File encoding has not been set, using platform encoding UTF-8, i.e. build is platform dependent!
[INFO] Compiling 1 source file to /home/someuser/example-knowledge-module/target/test-classes
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 5.452s
[INFO] Finished at: Mon Nov 28 22:43:39 CET 2011
[INFO] Final Memory: 21M/490M
[INFO] ------------------------------------------------------------------------

Releases

Releases

Release 0.3.1 is available from Maven Central. Consider this version a development release intended to gather feedback from potential users. Try to migrate your rules project into a modular, Maven-based one, re-use some knowledge modules here and there, and let me know how far this plugin carries you. If you encounter any problems, let me know.

Supported features

  • automatic resolution of direct jar dependencies (i. e. you can use classes from these jar files in your Drools code)
  • automatic resolution of direct dkm dependencies (i. e. you can use declares from other Drools knowledge packages in your Drools code)
  • transitive dependency resolution, both for jar and for dkm type dependencies. That means: you can have a knowledge-module which depends on another knowledge module, which depends on another knowledge module, ... - The plugin will load the required knowledge modules before starting compilation of the project depending on those.

Current limitations

  • Requires Maven 3.x. Development and testing is done using Maven 3.0.4. Older versions might work, but are basically unsupported. Please upgrade to the most recent Maven release.
  • Due to a limitation in Drools' I/O code (see JBRULES-3225 for details), it is currently not possible to de-serialize drools knowledge modules which contain multiple KnowledgePackages depending on each other. Workaround: define one Maven module per logical Drools package and define those dependencies explicitly in the pom.xml. Put differently: within a single Drools Knowledge Module, make your *.drl files contain all the same package ... statement.
  • No support for *.dka files yet. This means: for loading the knowledge module files into your application, you will need to keep track of the dependencies between all the knowledge modules involved on your own. For small rule bases with few modules, this seems feasible. For larger rulebases or larger numbers of knowledge modules, please hang on for a few more weeks.

Change Log

Use the Issue Tracker with the desired filter on field Fix Version to obtain any change log you'd like to inspect.

Example: All issues fixed from version 0.2.10 to version 0.3.1

Roadmap

Roadmap

Further development will be demand-driven. A major stakeholder of the whole effort will probably be all my brave colleagues from the EUROPACE.NL team at HYPOPORT AG, building the probably first integrated online mortgage sales platform for the Dutch market. We use Drools for risk assessment, so we need to compile a lot of rules frequently.

Nevertheless, all bugs and enhancement requests will be entered into and tracked by the public issue tracker. The tracker is currently not ready for public use yet, so if you have any questions or issues regarding the plugin, please post a comment here.

Contributing

Contributing

This plugin's source code is hosted on github.com. Albeit the project structure has become a bit complex over the last few months, I'd like to encourage you to fork it, experiment with it, or even contribute improvements back into the mainline. I plan to write a few blog posts about the project setup, so if you're feeling lost while looking at the github repositories now, don't worry too much.

License

License

The Maven Drools Plugin is licensed under Apache License, Version 2.0.