The simple, stupid rules engine for Java

Overview

Easy Rules
The simple, stupid rules engine for Java™

MIT license Build Status Maven Central Javadoc Project status


Project status

As of December 2020, Easy Rules is in maintenance mode. This means only bug fixes will be addressed from now on. Version 4.1.x is the only supported version. Please consider upgrading to this version at your earliest convenience.

Latest news

  • 06/12/2020: Version 4.1 is out with a new module to support Apache JEXL as an additional supported expression language! You can find all details about other changes in the release notes.

What is Easy Rules?

Easy Rules is a Java rules engine inspired by an article called "Should I use a Rules Engine?" of Martin Fowler in which Martin says:

You can build a simple rules engine yourself. All you need is to create a bunch of objects with conditions and actions, store them in a collection, and run through them to evaluate the conditions and execute the actions.

This is exactly what Easy Rules does, it provides the Rule abstraction to create rules with conditions and actions, and the RulesEngine API that runs through a set of rules to evaluate conditions and execute actions.

Core features

  • Lightweight library and easy to learn API
  • POJO based development with an annotation programming model
  • Useful abstractions to define business rules and apply them easily with Java
  • The ability to create composite rules from primitive ones
  • The ability to define rules using an Expression Language (Like MVEL, SpEL and JEXL)

Example

1. First, define your rule..

Either in a declarative way using annotations:

@Rule(name = "weather rule", description = "if it rains then take an umbrella")
public class WeatherRule {

    @Condition
    public boolean itRains(@Fact("rain") boolean rain) {
        return rain;
    }
    
    @Action
    public void takeAnUmbrella() {
        System.out.println("It rains, take an umbrella!");
    }
}

Or in a programmatic way with a fluent API:

Rule weatherRule = new RuleBuilder()
        .name("weather rule")
        .description("if it rains then take an umbrella")
        .when(facts -> facts.get("rain").equals(true))
        .then(facts -> System.out.println("It rains, take an umbrella!"))
        .build();

Or using an Expression Language:

Rule weatherRule = new MVELRule()
        .name("weather rule")
        .description("if it rains then take an umbrella")
        .when("rain == true")
        .then("System.out.println(\"It rains, take an umbrella!\");");

Or using a rule descriptor:

Like in the following weather-rule.yml example file:

name: "weather rule"
description: "if it rains then take an umbrella"
condition: "rain == true"
actions:
  - "System.out.println(\"It rains, take an umbrella!\");"
MVELRuleFactory ruleFactory = new MVELRuleFactory(new YamlRuleDefinitionReader());
Rule weatherRule = ruleFactory.createRule(new FileReader("weather-rule.yml"));

2. Then, fire it!

public class Test {
    public static void main(String[] args) {
        // define facts
        Facts facts = new Facts();
        facts.put("rain", true);

        // define rules
        Rule weatherRule = ...
        Rules rules = new Rules();
        rules.register(weatherRule);

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

This is the hello world of Easy Rules. You can find other examples like the Shop, Airco or WebApp tutorials in the wiki.

Contribution

You are welcome to contribute to the project with pull requests on GitHub. Please note that Easy Rules is in maintenance mode, which means only pull requests for bug fixes will be considered.

If you believe you found a bug or have any question, please use the issue tracker.

Awesome contributors

Thank you all for your contributions!

Easy Rules in other languages

Who is using Easy Rules?

Credits

YourKit Java Profiler

Many thanks to YourKit, LLC for providing a free license of YourKit Java Profiler to support the development of Easy Rules.

License

Easy Rules is released under the terms of the MIT license:

The MIT License (MIT)

Copyright (c) 2021 Mahmoud Ben Hassine ([email protected])

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
Comments
  • Problem with executing all the rules in the easy-rules-2.0.0

    Problem with executing all the rules in the easy-rules-2.0.0

    I tried out the new version 2.0.0. All the registered rules does not seem to be triggered. I'm pasting the code I have written, and I'm expecting all the rules to be executed, but it's not working this way. Let me know if I'm missing something.

      @Rule
      public class RuleA {
        @Condition
        public boolean when(){
            System.out.println("A is called");
            return true;
        }
        @Action
        public void then(){
            System.out.println("A is executed");
        }
    }
    
    @Rule
    public class RuleB {
        @Condition
        public boolean when(){
            System.out.println("B is called");
            return true;
        }
    
        @Action
        public void then(){
            System.out.println("B is executed");
        }
    }
    
    @Rule
    public class RuleC {
        @Condition
        public boolean when(){
            System.out.println("C is called");
            return true;
        }
    
        @Action
        public void then(){
            System.out.println("C is executed");
        }
    }
    

    The Main method for calling these rules:

    public class Main {
        public static void main(String[] args) {
              RuleA a = new RuleA();
              RuleB b = new RuleB();
              RuleC c = new RuleC();
    
               RulesEngine rulesEngine = RulesEngineBuilder.aNewRulesEngine().build();
              rulesEngine.registerRule(a);
              rulesEngine.registerRule(b);
              rulesEngine.registerRule(c);
    
                 rulesEngine.fireRules();
        }
    }
    

    Output printed in the console-------------------

    May 21, 2015 10:18:26 AM org.easyrules.core.DefaultRulesEngine logEngineParameters INFO: Rule priority threshold: 2,147,483,647 May 21, 2015 10:18:26 AM org.easyrules.core.DefaultRulesEngine logEngineParameters INFO: Skip on first applied rule: false May 21, 2015 10:18:26 AM org.easyrules.core.DefaultRulesEngine logEngineParameters INFO: Skip on first failed rule: false May 21, 2015 10:18:26 AM org.easyrules.core.DefaultRulesEngine applyRules INFO: Rule 'rule' triggered. A is called A is executed May 21, 2015 10:18:26 AM org.easyrules.core.DefaultRulesEngine applyRules INFO: Rule 'rule' performed successfully.

    Question:

    Why aren't RuleB and RuleC executed in this case ?

    question 
    opened by vinoct6 18
  • Use Expression Language to define rules

    Use Expression Language to define rules

    It should be possible to define rules with an Expression Language (like OGNL, MVEL, JBoss EL, Spring EL).

    Conditions are easy to express using an expression language. The challenge here is how to define actions, their order, on which facts do they act, etc...

    Still need to investigate and find a clean (and easy!) way to express actions.

    Any suggestions or ideas are welcome!

    Feature 
    opened by fmbenhassine 14
  • MVELCondition does not re-throw exceptions

    MVELCondition does not re-throw exceptions

    Hi

    We have problem with identifying/handling errors on a condition execution. Exceptions in MVELCondition are suppressed and can't be handled in onFailure(...) from RuleListener.

    Code in MVELCondition doesn't re-throw exceptions. The code example:

    public boolean evaluate(Facts facts) {
            try {
                return (Boolean)MVEL.executeExpression(this.compiledExpression, facts.asMap());
            } catch (Exception var3) {
                LOGGER.error("Unable to evaluate expression: '" + this.expression + "' on facts: " + facts, var3);
                return false;
            }
        }
    

    Similar issue was described here https://github.com/j-easy/easy-rules/issues/194 but in this time it is related to MVELCondition. As I see, it was fixed already for MVELAction. Could you please help us in this situation? Thanks.

    breaking change 
    opened by alexpalchuk 13
  • Add ActivationRuleGroup implementation

    Add ActivationRuleGroup implementation

    Hey everyone

    Currently, composite rules work only if all the rules return true.

    Is modifying this behaviour outside of the scope of easy-rules? I'd just like to know, if it is something that would be of interest, I would love to contribute.

    My use case is such that I am using the easy-rules for form field validations (which is work beautifully for). The only issue I have is that I would like composite rules to fire is any of the internal rules return true vs all of them.

    It might also be an interesting idea to allow the action to be fired on the reverse of a rule fire (i.e. allow a negative return to trigger the action - but perhaps this is for another issue)

    enhancement Feature 
    opened by SeanSWatkins 12
  • Add rules engine listener

    Add rules engine listener

    I would like to fetch some data from database and pass into per rule. I noticed that there is RuleListener but it seems it is triggered per rule. I think that an API for per execution.

    Feature 
    opened by cemo 12
  • @Autowired class is null inside Rule class

    @Autowired class is null inside Rule class

    Hi,

    Thanks for this awesome feature. It made my life easier, when I was thinking how to implement multiple rules in my project. I have a scenario where I update my database based on conditions. I am using EasyRules for the same.

    I am autowiring my DAO class inside the spring rule engine class. When I run the code, my Dao class which is autowired inside my SpringRule class is null. Hence I am getting nullpointerexception. My code is as below

    @SpringRule
    public class Rule1 {
    
    @Autowired
    private MyDAO myDAO;   --> (is null during runtime)
    
    public Rule1 () {
        super();
    }
    
    @Condition
    public boolean when() {
        if (condition) {
            return true;
        }
        return false;
    }
    
    @Action(order = 1)
    public void then() throws Exception {
        myDAO.update("test");
        System.out.println("Waiting state success");
    }
    
    }
    

    My DAO interface is:

    public interface MyDAO {
       public void update(String value);
    }
    

    My DAO impl calss is:

    @Repository
    public class MyDAOImpl implements MyDAO{
    
    @Override
    public void update(String value){
    //update in DB
    }
    }
    
    waiting for feedback 
    opened by madhunaidu2468 12
  • Why doesn't AnnotatedRulesEngine convert beans to a Rule?

    Why doesn't AnnotatedRulesEngine convert beans to a Rule?

    I am working on capturing business rule events in order to record their execution for debugging purposes. I am wrapping a Rule in order to capture the execution. This works well for the DefaultRulesEngine but won't work for the AnnotatedRulesEngine. It will be tricker to do this with that.

    If the AnnotatedRulesEngine had converted the annotated object into a Rule at registration then this would have been considerably easier to. Does this sound too crazy?

    Is there a better way to record the execution (or not) then delegation? We are recording more then just logging. We need to record into a custom reporting library.

    Feature 
    opened by mrcritical 12
  • Facts should implement Serializable

    Facts should implement Serializable

    Can we add support for rule engine to implement serializable interface

    Caused by: java.io.NotSerializableException: org.jeasy.rules.api.Facts Serialization stack: - object not serializable (class: org.jeasy.rules.api.Facts, value: [])

    opened by mahendrakapadne 11
  • [safe-condition]: Safe evaluation. Do not throws exception

    [safe-condition]: Safe evaluation. Do not throws exception

    Actual process of DefaultRulesEngine:

    • Evaluate method is not error safe
    • Execute method is error safe

    If any rule evaluation fails and launch an exception, the engine throws an exception. If we have a complex evaluation, an exception could be thrown.

    This PR avoids this problem.

    Plus added onEvaluateFailure listener for this case.

    opened by sanmibuh 11
  • Spring / Rules contexts

    Spring / Rules contexts

    Thank you for this promising project.

    The interest of Spring is very limited with the actual implementation.

    Perhaps it could be interesting to set a context to a RulesEngine like this: rulesEngine.addContext("age", 18); or rulesEngine.fireRules("age", 18, "gender", "Male");

    And to set dynamically the context to the rule during the execution: In the pojo: @Rule(...) public class AgeRule { @Context("age") //injected by the ruleEngine private Long age; }

    enhancement Feature Major API change 
    opened by rodriguezc 11
  • MVELRuleDefinition should be public

    MVELRuleDefinition should be public

    I wanna create rules directly from some in-memory data (like a Pojo or a Map) instead of a file, so I dig into your sources and I found this: image It's almost exactly what I want, but neither MVELRuleDefinitionReader nor MVELRuleDefinition is Public, so I could not use MVELRuleDefinition.create() to create my Rule. So if this need is reasonable, please consider:

    1. expose these Classes
    2. provide a new method in MVELRuleFactory which take a Map as input.

    I think 1 is more flexible so I could use my db as a rule store and provide a web UI to manage my rules, what about you guys?

    opened by sxcooler 10
  • ConcurrentModificationException under load

    ConcurrentModificationException under load

    Hi,

    We are seeing this error under load.

    java.util.ConcurrentModificationException: null
    	at java.base/java.util.TreeMap$PrivateEntryIterator.nextEntry(Unknown Source)
    	at java.base/java.util.TreeMap$KeyIterator.next(Unknown Source)
    	at org.jeasy.rules.core.RuleProxy.appendActionMethodsNames(RuleProxy.java:353)
    	at org.jeasy.rules.core.RuleProxy.getRuleDescription(RuleProxy.java:334)
    	at org.jeasy.rules.core.RuleProxy.invoke(RuleProxy.java:101)
    	at com.sun.proxy.$Proxy218.getDescription(Unknown Source)
    	at org.jeasy.rules.core.DefaultRulesEngine.log(DefaultRulesEngine.java:146)
    	at org.jeasy.rules.core.DefaultRulesEngine.doFire(DefaultRulesEngine.java:80)
    	at org.jeasy.rules.core.DefaultRulesEngine.fire(DefaultRulesEngine.java:70)
    
    

    In RuleProxy line 279

        private Set<ActionMethodOrderBean> getActionMethodBeans() {
            if (this.actionMethods == null) {
                this.actionMethods = new TreeSet<>();
    

    Consider using ConcurrentSkipListSet.

    opened by ab0159w 1
  • Optimize performance by using method handle to replace reflect

    Optimize performance by using method handle to replace reflect

    RuleProxy has been sped up by caching the reflective access in v3.4.0. However it still invokes native reflection, and there is a better way to optimize the performance : e.g. https://github.com/FasterXML/jackson-modules-base/blob/2.15/blackbird/README.md benchmarks https://github.com/FasterXML/jackson-modules-base/blob/2.15/blackbird/benchmarks/README.md

    It could use BiConsumer to replace the ActionMethodOrderBean#method prop. And using consumer.accept(target, actualParameters.toArray()) BTW, importing extra dependencies of method handle is needless, it's better than ASM.

    static class MethodHandleRule {
        void execute(Object[] args){
            System.out.println("Using method handle as lambda.");
            System.out.println("And print args: " + Arrays.toString(args));
        }
    }
        
    @SuppressWarnings({"rawtypes", "unchecked"})
    public void usingMethodHandle() throws Throwable {
        final MethodHandleRule target = new MethodHandleRule();
        final MethodHandles.Lookup lookup = MethodHandles.lookup();
        final Method method = target.getClass().getDeclaredMethod("execute", Object[].class);
        final MethodHandle methodHandle = lookup.unreflect(method);
    
        final Object functionInterface = LambdaMetafactory.metafactory(lookup, "accept",
                methodType(BiConsumer.class), methodType(void.class, Object.class, Object.class),
                methodHandle, methodHandle.type()
        ).getTarget().invoke();
    
        final BiConsumer consumer = (BiConsumer) functionInterface;
        final Object args = new Object[]{"123", "234"};
        consumer.accept(target, args);
    }
    
    opened by BOFA1ex 0
  • Migration From version 3 to Version 4 breaking the already working relavance rules

    Migration From version 3 to Version 4 breaking the already working relavance rules

    hi I've Followed the instruction mentioned in the migration guide but seems like the relevance rules are breaking. my question is do we need to change anything in the yaml files as well or this is just a bug in the library ? i've attached Example rule below which is working in version 3 but not in version 4

    ---
    name: step1_danger_signs
    description: danger_signs
    priority: 1
    condition: "!step1_contact_reason.isEmpty()"
    actions:
      - "isRelevant = true"
    
    opened by junaidwarsivd 0
  • MVEL variables throw PropertyAccessException unresolvable property or identifier after upgrade

    MVEL variables throw PropertyAccessException unresolvable property or identifier after upgrade

    I followed the v3 --> v4 upgrade instructions and all mvel yaml file rules compile and most run fine. However, a few are throwing errors in the actions when attempting to access variables (seems the ctx is null and the variable can't be accessed).

    Is there another step in the version upgrade? Most of our variables are Optionals that we use get(), isPresent, and orElse functions on.

    Here's a sample code that worked on 3.3 but fails on 4.1:

    ---
    name: "zzz_custom"
    condition: >
      parameterValues = config.get('parameters');
      parameterValues.isPresent();
    actions:
      - >
        for(rule:parameterValues.get()){
          if(rule.match==true){
            for(mod:rule.fields.entrySet()){
              org.apache.commons.beanutils.BeanUtils.copyProperty(callParameters,mod.key,mod.value);
            }
          }
        }
    

    The error occurs in the actions on the line trying to access parameterValues.get() with PropertyAccessException. If I insert this call parameterValues = config.get('parameters'); then it works.

    I have other mvel yaml files that are having a similar problem, but so far, I've not been able to solve it simply by re-initializing the variable like above.

    opened by aquacode 1
Releases(easy-rules-4.1.0)
  • easy-rules-4.1.0(Dec 6, 2020)

    This version is a minor release which comes with the following new features, enhancements and bug fixes:

    New features

    • Issue #283: Add size method in Rules API
    • Issue #288: Update Rules#register / Rules#unregister methods to accept varargs
    • Issue #271: Add support for Apache JEXL

    Bug fixes

    • Issue #291: Update RuleProxy to accept types implementing Comparable

    Documentation

    • Issue #316: Update Javadoc about rule comparison
    • Issue #320: Document composite rules about their thread unsafety

    I would like to thank all contributors who helped making this release possible!

    Source code(tar.gz)
    Source code(zip)
  • easy-rules-4.0.0(May 17, 2020)

    This is a major release which is based on Java 8. This version comes with a number of new features and bug fixes (See detailed list below). Moreover, some breaking changes have been introduced to fix a couple of design inconsistencies in v3. Here are the major changes:

    • Introducing a new Fact domain concept which replaces the Map<String, Object> data structure used in v3. This new concept has a number of advantages like type safety, better encapsulation and a cleaner API.
    • MVEL/SpEL conditions now throw runtime exceptions instead of catching them and returning false. This makes it possible to correctly unit test conditions as well as listen to evaluation errors with a rule listener (a new method RuleListener#onEvaluationError has been introduced for this purpose).
    • SpEL conditions and actions should now use the #{ ... } template by default. This is configurable but it has been made the default to be consistent with Spring's default template parser.

    Moreover, thanks to this major Java version upgrade, a lot of improvements have been introduced in the API (like using default methods in interfaces, adding @FunctionalInterface where appropriate, etc) as well as in the code base (using lambdas and streams where it made sense, using new reflection APIs introduced in Java 8, etc).

    Here is the list of issues resolved in this release:

    New features

    • issue #276: Add Fact concept
    • issue #250: Add a clear method in Facts API
    • issue #259: Add BeanResolver to SpELAction and SpELCondition

    Bug fixes

    • issue #267: Facts#asMap should return an immutable map or a copy of the facts
    • issue #211: MVELCondition does not re-throw exceptions
    • issue #257: Inconsistent SpEL expression templating between SpELRule and SpELRuleFactory

    Enhancements

    • issue #268: Improve Javadoc of Facts#iterator to mention that it should not be used to remove facts
    • issue #253: Add default methods in interfaces

    I would like to thank all contributors who made this release possible by reporting issues, testing fixes, requesting features and participating in discussions: @readilychen, @elitacco, @snok3r, @AleksandrPalchuk, @turiandras, @Alexey1Gavrilov, @yunfengwang and @R-Gerard ! Thank you all for your contributions!

    A special BIG thank you to @zhhaojie for following up on issues, helping in design discussions and all the time and effort put on Easy Rules!

    Migration guide from v3 to v4

    Moved APIs

    The following APIs have been moved between packages for better cohesion:

    • RulesEngineParameters has been moved from package org.jeasy.rules.core to org.jeasy.rules.api
    • CompositeRule and its implementations (ActivationRuleGroup, UnitRuleGroup and ConditionalRuleGroup) have been moved from the root package org.jeasy.rules.support to a dedicated package org.jeasy.rules.support.composite
    • RuleDefinitionReader and its implementations (AbstractRuleDefinitionReader, YamlRuleDefintionReader and JsonRuleDefintionReader) have been moved from the root package org.jeasy.rules.support to a dedicated packageorg.jeasy.rules.support.reader

    Action: Update import statements where the aforementioned classes are used

    Removed APIs

    For both MVEL and SpEL modules, the ParserContext is now passed to rules and rule factories at construction time. Hence, all overloaded methods where the parser context is passed as a parameter (which are now useless) have been removed:

    • Methods org.jeasy.rules.mvel.MVELRule.when(String, ParserContext) and org.jeasy.rules.mvel.MVELRule.then(String, ParserContext)
    • Methods org.jeasy.rules.mvel.MVELRuleFactory.createRule(Reader, ParserContext) and org.jeasy.rules.mvel.MVELRuleFactory.createRules(Reader, ParserContext)
    • Methods org.jeasy.rules.spel.SpELRule.when(String, ParserContext) and org.jeasy.rules.spel.SpELRule.then(String, ParserContext)
    • Methods org.jeasy.rules.spel.SpELRuleFactory.createRule(Reader, ParserContext) and org.jeasy.rules.spel.SpELRuleFactory.createRules(Reader, ParserContext)
    • Methods org.jeasy.rules.support.AbstractRuleFactory.createSimpleRule(RuleDefinition, ParserContext) and org.jeasy.rules.support.AbstractRuleFactory.createCompositeRule(RuleDefinition, ParserContext) do not take a ParserContext as parameter anymore.

    Action: Pass the parser context at construction time (to the rule or the rule factory) and call new methods that do not take the parser context as parameter.

    Changed APIs

    Due to the introduction of the new Fact concept (issue #276), the following method signatures have been changed:

    • Facts#put(String, Object) does not return the previous associated value if any, the return type is now void
    • Facts#remove(String) does not return the removed fact anymore, the return type is now void
    • Facts#iterator now returns a Iterator<Fact> instead of Iterator<Map.Entry<String, Object>>

    Actions:

    • Update the assigned variable type where those methods are called.
    • For Facts#put, since the previously associated value if any is not returned anymore, one can query the Facts API to see if there is a fact mapped for the given name before calling put.
    • ForFacts#remove, since the removed fact is not returned anymore, one can query the Facts API to get the fact before removing it.
    Source code(tar.gz)
    Source code(zip)
  • easy-rules-3.4.0(Dec 8, 2019)

    This is a minor release with a few enhancements and bug fixes:

    Enhancements

    • Issue #221: RuleProxy can be speed up by caching reflective access
    • Issue #238: Make AbstractRulesEngine public
    • Issue #223: Remove DefaultRuleListener and DefaultRulesEngineListener

    Bug fixes

    • Issue #239: RulesEngine listeners are not invoked when registered in an InferenceRulesEngine

    Many thanks to all contributors for their help in this release!

    ❗️ Please note that this is the last release in the v3 line. Next version will be 4.0.0 and will be based on Java 8.

    Source code(tar.gz)
    Source code(zip)
  • easy-rules-3.3.0(Apr 25, 2019)

    This release is a minor version with the following changes:

    Features and enhancements

    • #156: Add composite rule support from a rule descriptor file
    • #166: Change default log level to DEBUG
    • #197: Add support for parser context in MVEL conditions/actions
    • #202: Add support to read rules from JSON objects
    • #204: Add support for Spring Expression Language

    Bug fixes

    • #157: RulesEngine#getListeners and RulesEngine#getRulesEngineListeners should return a unmodifiable list of listeners
    • #158: RulesEngine#getParameters should return a copy of the parameters
    • #165: Incorrect rule validation for non annotated fact parameters
    • #194: MVELAction does not re-throw exceptions
    • #203: ConditionalRuleGroup has wrong priority control

    ❗️ Heads-up: Even though this is a minor release, there is a small breaking change in the MVELRuleFactory API. It was not possible to introduce SpEL and JSON support without introducing this breaking change, and waiting for a major release (Java 8 baseline) did not make sense. Semantic versioning rules are not as easy to implement as Easy Rules 😄

    Many thanks to @Jeff-Jia, @wuhaidu, @khaledabderrahim, @ramnaresh2051, @kayeight, @amitvj1 and @mr0815mr for their contributions to this release!

    Source code(tar.gz)
    Source code(zip)
  • easy-rules-3.2.0(Apr 9, 2018)

    This is the second maintenance release of the 3.x line. It introduces a new module called easy-rules-support. This module contains support classes that were in the easy-rules-core module. For instance, the org.jeasy.rules.core.CompositeRule has been moved to easy-rules-support as org.jeasy.rules.support.CompositeRule and made abstract. 3 implementations of composite rules are now provided out of the box:

    • UnitRuleGroup: All or nothing semantics (exactly the same as CompositeRule in previous versions)
    • ActivationRuleGroup: XOR logic, ie only one rule of the group will be triggered (issue #122)
    • ConditionalRuleGroup: A primary rule acts as a precondition to trigger the rule group (issue #130)

    This release comes with other new features and some bug fixes:

    Features

    • Issue #96: Set priority through @Rule annotation
    • Issue #133: Read YAML rule descriptor from a String
    • Issue #138: Load multiple rules from a single yaml file

    Bug fixes

    • Issue #139: NPE If a null Fact is injected through annotation
    • Issue #143: Proxy toString() is not equal to original object toString()
    • Issue #141: NPE in MVELRuleDefinitionReader if rule name, description or priority is not specified

    Deprecations

    • Issue #145: Deprecate MVELRuleFactory#createRuleFrom(java.io.File). A new method that takes a java.io.Reader is to be used instead to be able to read rules not only from files (with a FileReader), but also from Strings (with a StringReader) or any other reader implementation.
    • Issue #122: org.jeasy.rules.core.CompositeRule is deprecated. It has been moved to the new easy-rules-support module and is now abstract.

    I would like to thank @dagframstad, @danrivcap, @bpoussin and @paulbrejla for their contributions to this release.

    Source code(tar.gz)
    Source code(zip)
  • easy-rules-3.1.0(Dec 18, 2017)

    This release is another important milestone for Easy Rules! We finally managed to get some long awaited features out :smile:

    The major additions of v3.1 are:

    • New inference rules engine
    • New Condition, Action and RuleBuilder APIs
    • Support for using expression language to define rules

    This release has also introduced a lot of API improvements thanks to some amazing contributors! Here is the full list of changes:

    Features:

    • issue #36: Use Expression Language to define rules
    • issue #88: Add inference rules engine
    • issue #113: Use SLF4J instead of java.util.logging
    • issue #121: Add rules engine listener
    • issue #119: Add Condition / Action APIs

    Bug fixes:

    • issue #91: Log performance in silent mode
    • issue #100: Rule proxy's equals return unexpected result

    Enhancements

    • issue #123: cast friendly Facts
    • issue #118: Use toString() to print engine parameters
    • issue #111: Remove unnecessary method and interface
    • issue #115: Override equals()/hashCode()/toString() same as BasicRule
    • issue #104: [subFacts]: Conditions or Actions can have subclass of Facts as parameter
    • issue #95: Improve the Facts api
    • issue #94: A little optimization in RuleProxy.java

    Deprecations

    • issue #126: Deprecate RulesEngineBuilder
    • issue #91: Methods RulesEngineParameters#setSilentMode and RulesEngineParameters#isSilentMode as well as constructors taking silentMode parameter

    I would like to thank @wg1j, @sanmibuh, @shivmitra, @cemo and @khandelwalankit for their contributions!

    Source code(tar.gz)
    Source code(zip)
  • easy-rules-3.0.0(May 30, 2017)

    This is a big milestone for Easy Rules since the beginning! v2.x was a successful line but we must admit it suffered from a couple of design decisions:

    1. Rules were designed to encapsulate data (BOM) they operate on. This works fine, but is not very friendly to concurrent threads
    2. The rules engine was designed to encapsulate the set of rules it operates on. For the same reason as 1) , this make the engine not thread safe

    v3 is finally here to fix these issues! Please find below the most important changes and additions.

    Important notes about v3

    • Easy Rules is now part of the jeasy project. Hence, the maven's groupId has changed from org.easyrules toorg.jeasy

    • Online documentation has been moved from www.easyrules.org to the wiki of the github project. The www.easyrules.org site will be shutdown on 31/07/2017.

    • Gitter chat room has been moved from https://gitter.im/easyrules/easyrules to https://gitter.im/j-easy/easy-rules

    Major changes

    • issue #37 : Add working memory abstraction through the Facts API
    • issue #86 : Add rules set abstraction through the Rules API
    • issue #87 : Add @Fact annotation to inject facts in conditions and actions methods of rules

    The DefaultRulesEngine class is now public. Keys APIs (Rule, RulesEngine and RuleListener) have been updated to accept Rules and Facts in their methods signatures. Please refer to the javadoc for all details about these changes.

    Deprecations

    • issue #79 : deprecate rules engine name parameter
    • issue #74 : remove spring support that was deprecated in v2.5
    • issue #75 : remove quartz support that was deprecated in v2.5

    This release would not have been possible without the help of some awseome contributors! We are grateful to all of them! Thank you for your time and effort.

    Source code(tar.gz)
    Source code(zip)
  • easyrules-2.5.0(May 18, 2017)

    This is the latest version in v2.x line. It adds the following features and bug fixes:

    Features

    • issue #64 : Add ability to unregister a rule by name
    • issue #65 : Add Spring Boot Starter for Easy Rules
    • issue #72 : Add ability to get notified with rule evaluation result in the RuleListener API

    Fixed bugs

    • issue #66 : Core annotations are not inherited in child classes
    • issue #68 : @SpringRule annotation is not inherited in child classes

    In this version, support for Spring and Quartz has been deprecated and will be removed in v3.0.

    Many thanks to @khandelwalankit, @cogito-clarus, @careerscale, @cgonul, @pklovesbacon and @yisraelU for reporting issues and testing fixes.

    A special thank to @andersonkyle for adding a spring boot starter to easy rules! A big thank goes to @will-gilbert for implementing easy rules tutorials with groovy!

    Source code(tar.gz)
    Source code(zip)
  • easyrules-2.4.0(Feb 8, 2017)

    This is a minor release with the following changes:

    Features

    • issue #52: add skipOnFirstNonTriggeredRule parameter

    Bug fixes

    • issue #57: incorrect sorting of rules when BasicRule.getPriority method is overridden

    Enhancements

    • issue #63: Utils class should not be public

    Deprecations

    • issue #47: JMX support has been deprecated in v2.3 and removed in this version

    Many thanks to all contributors, especially @toudidel and @spearway and @JurMarky, for reporting issues, fixing bugs and implementing features.

    Source code(tar.gz)
    Source code(zip)
  • easyrules-2.3.0(Aug 24, 2016)

    New features

    • issue #34 : add method beforeEvaluate in RuleListener
    • issue #39 : add method getListeners in RulesEngine to get registered listeners
    • issue #40 : add method checkRules in RulesEngine to check rules without firing them
    • issue #41 : add possibility to create composite rules from annotated rules

    Fixed bugs

    • issue #32 : unable to use Easy Rules in android due to JMX
    • issue #38 : unable to set rules engine name in spring factory bean

    Improvements

    • issue #46 : improve JUL log record format

    Deprecation

    • issue #47 : deprecate JMX managed rules and rules engine
    Source code(tar.gz)
    Source code(zip)
Owner
Jeasy
Easy peasy libraries and micro-frameworks for the JVM
Jeasy
Drools is a rule engine, DMN engine and complex event processing (CEP) engine for Java.

An open source rule engine, DMN engine and complex event processing (CEP) engine for Java™ and the JVM Platform. Drools is a business rule management

KIE (Drools, OptaPlanner and jBPM) 4.9k Dec 31, 2022
A collection of JUnit rules for testing code which uses java.lang.System.

System Rules System Rules is a collection of JUnit rules for testing code which uses java.lang.System. System Lambda is an alternative to System Rules

Stefan Birkner 536 Dec 22, 2022
OpenL Tablets Business Rules Management System

Easy Business Rules OpenL Tablets targets the infamous gap between business requirements (rules and policies) and software implementation. Designed to

OpenL Tablets 114 Dec 17, 2022
An All-In-One Macro for Hypixel Skyblock. Includes numerous features for Quality of Life that do NOT abide by the Hypixel Rules.

AIOMacro An All-In-One Macro for Hypixel Skyblock. Includes numerous features for Quality of Life that do NOT abide by the Hypixel Rules. Installation

Jackson 18 Dec 19, 2022
A Java-based template project for the FastJ Game Engine.

FastJ Java Template Program Requirements Java 16 JDK Basic understanding of Java Initial Setup Download the Template You have a few options for gettin

Andrew Dey 13 May 15, 2022
Google App Engine Standard Environment Source Code for Java 8 and Java11

Google App Engine Standard Environment Source Code for Java 8 and Java11. This is a repository that contains the Java Source Code for Google App Engin

Google Cloud Platform 167 Jan 2, 2023
Rivr is a lightweight open-source dialogue engine enabling Java developers to easily create enterprise-grade VoiceXML applications.

Overview Rivr is a lightweight open-source dialogue engine enabling Java developers to easily create enterprise-grade VoiceXML applications. Read our

Nu Echo Inc. 57 Jun 27, 2022
Multi-OS Engine: Create iOS Apps in Java (or Kotlin ... etc.)

Multi-OS Engine Overview Multi-OS Engine provides a Java runtime and Java interfaces to iOS platform API to develop native iOS applications with nativ

Multi-OS Engine 561 Dec 22, 2022
Flights metasearch engine simulation using Java, GraphQL and React.js, developed for COMP30220 Distributed Systems.

Distributed Airways For the full project report, see ./report.pdf. A demonstration video is available here. Requirements Docker JDK 8 and Apache Maven

Rajit Banerjee 3 Dec 29, 2022
VFX processing engine in Java

sofvfx Video converter for ASCII display. Setup To use sofvfx, you will need to download ffmpeg. When done, open the downloaded .zip, go to /bin/ and

angelsflyinhell 4 Dec 29, 2022
Realtime Data Processing and Search Engine Implementation.

Mutad The name Mutad is a reverse spelling of datum. Overview An implementation of a real-time data platform/search engine based on various technology

Shingo OKAWA 14 Aug 4, 2022
🕊️ The world's most advanced open source instant messaging engine for 100K~10M concurrent users https://turms-im.github.io/docs

简体中文 What is Turms Turms is the most advanced open-source instant messaging engine for 100K~10M concurrent users in the world. Please refer to Turms D

null 1.2k Dec 27, 2022
Sceneform React Native AR Component using ARCore and Google Filament as 3D engine. This the Sceneform Maintained Component for React Native

Discord Server Join us on Discord if you need a hand or just want to talk about Sceneform and AR. Features Remote and local assets Augmented Faces Clo

SceneView Open Community 42 Dec 17, 2022
Mirror of Apache Velocity Engine

Title: Apache Velocity Engine Apache Velocity Welcome to Apache Velocity Engine! Apache Velocity is a general purpose template engine written in Java.

The Apache Software Foundation 298 Dec 22, 2022
Cadence is a distributed, scalable, durable, and highly available orchestration engine to execute asynchronous long-running business logic in a scalable and resilient way.

Cadence This repo contains the source code of the Cadence server and other tooling including CLI, schema tools, bench and canary. You can implement yo

Uber Open Source 6.5k Jan 4, 2023
Kyrestia, named after Kyrestia the Firstborne, is a process engine supporting mainstream process definition standards.

Kyrestia Kyrestia, named after Kyrestia the Firstborne, is a process engine supporting mainstream process definition standards. It is not only lightwe

Weiran Wu 32 Feb 22, 2022
Epiphany is a personalized Twitch resources recommendation engine

Epiphany Overview Epiphany is a personalized Twitch resources recommendation engine. Users can search and retrieve real-time Twitch resources using Tw

Eric 1 Jan 29, 2022
BlackBox is a virtual engine, it can clone and run virtual application on Android

BlackBox is a virtual engine, it can clone and run virtual application on Android, users don't have to install APK file to run the application on devices. BlackBox control all virtual applications, so you can do anything you want by using BlackBox.

null 1.6k Jan 3, 2023
Fazendo Super Mario Bros com minha engine

?? Super Mario Bros •Completo• Linguagem utilizada: JAVA Mario Bros Provavelmente todo mundo conhece e já jogou a história de Mario Bros, o famoso enc

lailaz 3 Jan 6, 2022