Easy Rules v4.1.0 Release Notes

Release Date: 2020-12-06 // 11 months ago
  • ๐Ÿš€ 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!


Previous changes from v4.0.0

  • ๐Ÿš€ 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.