1. Overview

In this article, we’ll go through some of the most popular rule engines for Java.

Within mission-critical applications, the process of maintaining business logic within the source code can become too complicated. Business rules can be used to ease the development and maintenance by separating business logic from the source code.

In the Java world, most of the rules engines libraries implement JSR94 standard known as Java Rule API Engine.

2. Drools

Drools is a Business Rules Management System (BRMS) solution. Drools can integrate with jBPM, a Business Process Management tool for standardization of process, events activities, tasks, etc.

If you want to read more, an introduction to Drools is available here, along with an article on integration with Spring.

3. OpenL Tablets

OpenL Tablets is a business rules management system and a business rules engine based on Excel decision tables. Since the format of tables used by this framework is familiar to business users, it bridges the gap between business users and developers.

Here is a simple example of how the framework works by using an Excel file containing decision tables. First, let’s import its dependencies which rely on org.openl.core and org.openl.rules modules:

<dependency>
    <groupId>org.openl</groupId>
    <artifactId>org.openl.core</artifactId>
    <version>5.26.5</version>
</dependency>
<dependency>
    <groupId>org.openl.rules</groupId>
    <artifactId>org.openl.rules</artifactId>
    <version>5.26.5</version>
</dependency>

Now, a User POJO:

public class User {
    private String name;
    // getters and setters
}

And an enum that will represent the outcome of the applied rules:

public enum Greeting {
    // ...
}

The Case class wraps the User object with variables that lead to outcomes:

public class Case {
    // Variables to infer outcomes
    // getters and setters
}

The interface IRule contains the rule injected by the Excel file:

public interface IRule {
    void helloUser(Case aCase, final Response response);
}

The Response class handles the return of the applied rule:

public class Response {
    private String result;
    private Map<String, String> map = new HashMap<>();
}

The main class, which triggers the rule execution:

public class Main {
    private IRule instance;

    public static void main(String[] args) {
        Main rules = new Main();
        // setup user and case here
        rules.process(aCase);
    }

    public void process(Case aCase) {
        EngineFactory<IRule> engineFactory = new RulesEngineFactory<IRule>(
          getClass().getClassLoader()
            .getResource("openltablets/HelloUser.xls"), IRule.class);
        instance = engineFactory.newEngineInstance();
        instance.helloUser(aCase, new Response());
    }
}

4. Easy Rules

Easy Rules is a simple Java rules engine providing a lightweight and POJO based framework to define business. It can create complex rules from primitive ones by using the composite pattern.

This framework, in contrast to the most traditional rules engines, doesn’t make use of XML files or any Domain Specific Language files to segregate rules from the application. It uses annotation-based classes and methods for injecting business logic into the application.

Easy Rules can be handy for developers to create and maintain applications with business logic that’s entirely separated from the application itself. On the other hand, as this framework doesn’t implement the JSR94 standard and the business logic has to be coded straight to Java code.

Here we provide a “Hello, world” example. Let’s import the required dependencies based on the easy-rules-core module:

<dependency>
    <groupId>org.jeasy</groupId>
    <artifactId>easy-rules-core</artifactId>
    <version>4.1.0</version>
</dependency>

Next, we create a class that defines a rule:

@Rule(name = "Hello World rule", description = "Always say hello world")
public class HelloWorldRule {

    @Condition
    public boolean when() {
        return true;
    }

    @Action
    public void then() throws Exception {
        System.out.println("hello world");
    }
}

Finally, we create the main class:

public class Launcher {
    public static void main(String... args) {
        // create facts
        Facts facts = new Facts();

        // create rules
        Rules rules = new Rules();
        rules.register(new HelloWorldRule());

        // create a rules engine and fire rules on known facts
        RulesEngine rulesEngine = new DefaultRulesEngine();
        rulesEngine.fire(rules, facts);
    }
}

5. RuleBook

RuleBook is a Java framework that leverages Java 8 lambdas and the Chain of Responsibility Pattern to define rules using simple BDD approach.

Like most rules engines, RuleBook makes use of the concept of “Facts”, which is data supplied to rules. RuleBook allows rules to modify the state of facts, which then can be read and modified by rules further down the chain. For those rules that read in data (Facts) of one type and output a result of a different type, RuleBook has Decisions.

RuleBook can be integrated with Spring using Java DSL.

Here, we provide a simple “Hello, world” example using RuleBook. Let’s add its dependency which is relying on the rulebook-core module:

<dependency>
    <groupId>com.deliveredtechnologies</groupId>
    <artifactId>rulebook-core</artifactId>
    <version>0.12</version>
</dependency>

Now, we create the rule:

public class HelloWorldRule {
    public RuleBook<Object> defineHelloWorldRules() {
        return RuleBookBuilder
          .create()
            .addRule(rule -> rule.withNoSpecifiedFactType()
              .then(f -> System.out.print("Hello ")))
            .addRule(rule -> rule.withNoSpecifiedFactType()
              .then(f -> System.out.println("World")))
            .build();
    }
}

Finally, the main class:

public static void main(String[] args) {
    HelloWorldRule ruleBook = new HelloWorldRule();
    ruleBook
      .defineHelloWorldRules()
      .run(new FactMap<>());
}

6. Conclusion

In this quick article, we’ve discussed some well-known libraries that provide engines for business logic abstraction.

As always, examples from this article are available on our GitHub repository.