Easy Rules v4.0.0 Release Notes
Release Date: 2020-05-17 // almost 3 years 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 theMap<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 methodRuleListener#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 inFacts
API - issue #259: Add
BeanResolver
toSpELAction
andSpELCondition
๐ 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
andSpELRuleFactory
โจ 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 packageorg.jeasy.rules.core
toorg.jeasy.rules.api
- ๐ฆ
CompositeRule
and its implementations (ActivationRuleGroup
,UnitRuleGroup
andConditionalRuleGroup
) have been moved from the root packageorg.jeasy.rules.support
to a dedicated packageorg.jeasy.rules.support.composite
- ๐ฆ
RuleDefinitionReader
and its implementations (AbstractRuleDefinitionReader
,YamlRuleDefintionReader
andJsonRuleDefintionReader
) have been moved from the root packageorg.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)
andorg.jeasy.rules.mvel.MVELRule.then(String, ParserContext)
- ๐ Methods
org.jeasy.rules.mvel.MVELRuleFactory.createRule(Reader, ParserContext)
andorg.jeasy.rules.mvel.MVELRuleFactory.createRules(Reader, ParserContext)
- ๐ Methods
org.jeasy.rules.spel.SpELRule.when(String, ParserContext)
andorg.jeasy.rules.spel.SpELRule.then(String, ParserContext)
- ๐ Methods
org.jeasy.rules.spel.SpELRuleFactory.createRule(Reader, ParserContext)
andorg.jeasy.rules.spel.SpELRuleFactory.createRules(Reader, ParserContext)
- ๐ Methods
org.jeasy.rules.support.AbstractRuleFactory.createSimpleRule(RuleDefinition, ParserContext)
andorg.jeasy.rules.support.AbstractRuleFactory.createCompositeRule(RuleDefinition, ParserContext)
do not take aParserContext
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 nowvoid
- ๐
Facts#remove(String)
does not return the removed fact anymore, the return type is nowvoid
Facts#iterator
now returns aIterator<Fact>
instead ofIterator<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 theFacts
API to see if there is a fact mapped for the given name before callingput
. - ๐ For
Facts#remove
, since the removed fact is not returned anymore, one can query theFacts
API
to get the fact before removing it.
- ๐ Introducing a new