apache / incubator-kie-drools

Drools is a rule engine, DMN engine and complex event processing (CEP) engine for Java.
http://www.drools.org
Apache License 2.0
5.88k stars 2.5k forks source link

org.mvel2.CompileException on Drools Template file with parameters in constraints #6154

Open Cocoa-Puffs opened 2 days ago

Cocoa-Puffs commented 2 days ago

Java Version: 21 Spring Boot Version: 3.3.4 KIE Version: 9.44.0.Final

Short summary: In Drools Template files if there are parameters on a given line that end with a variable name a trailing space must be the last character of the line or during compiling an exception is thrown stating that unclosed @if{} blocks exist in the template file.

Detailed explanation: Take for example the following drt snippet:

when
    $c: Customer($balances : balances != null)
    $b_thb: Balance(currency == "@{balanceType}") from $balances
then

Using either DataProviderCompiler or ObjectDataCompiler to compile the above I get the following error:

Caused by: org.mvel2.CompileException: [Error: unclosed @if{} block. expected @end{}] [Near : {... nceType}");@end{} ....}]

The exception references the end of the action block. However when I replace the parameter with a concrete example:

when
    $c: Customer($balances : balances != null)
    $b_thb: Balance(currency == "MAGIC_COIN") from $balances
then

The exception does not come. After a bit of digging around with the debugger I have found that what happens is during compile time KIE wraps every line in if statements that use a parameter, for example the above snippet turns into:

when
    $c: Customer($balances : balances != null)
@if{balanceType != null}    $b_thb: Balance(currency == "@{balanceType}") from $balances@end{}
then

It then fails to read the @end{} statement as the closure of the if at the beginning of the line resulting in an exception. If I then modify the drt file to have a space at the end of this line the compilation is successful. Checking out the ExpressionNode using the debugger we can see the following:

when
    $c: Customer($balances : balances != null)
@if{balanceType != null}    $b_thb: Balance(currency == "@{balanceType}") from $balances @end{}
then