Easy Rules v4.0.0 Release Notes

Release Date: 2020-05-17 // 15 days ago
  • 🚀 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
    • 0️⃣ 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.

Previous changes from v3.4.0

  • 🚀 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.