droolskogito

"drools-wiring-dynamic" error when modifying a Drools fact


I auto-generated a drools project using the archetype: mvn archetype:generate -DarchetypeGroupId=org.kie -DarchetypeArtifactId=kie-drools-exec-model-ruleunit-archetype -DarchetypeVersion=8.33.0.Final

Modified the Measurement class to add:

    public void setVal(final String val) {
        this.val = val;
    }

Added the following statement to the consequence of the original rule:

rule "will execute per each Measurement having ID color"
when
    $measure: /measurements[ id == "color", $colorVal : val ]
then
    $measure.setVal("BS");
end

When I ran the RuleTests (both via IntelliJ and via maven) I got the following error:

java.lang.UnsupportedOperationException: You're trying to dynamically define a class, please add the module org.drools:drools-wiring-dynamic to your classpath.

    at org.drools.wiring.statics.StaticProjectClassLoader$DummyInternalTypesClassLoader.defineClass(StaticProjectClassLoader.java:83)
    at org.drools.wiring.api.classloader.ProjectClassLoader.defineType(ProjectClassLoader.java:208)
    at org.drools.wiring.api.classloader.ProjectClassLoader.tryDefineType(ProjectClassLoader.java:192)
    at org.drools.wiring.api.classloader.ProjectClassLoader.loadType(ProjectClassLoader.java:181)
    at org.drools.wiring.api.classloader.ProjectClassLoader.loadClass(ProjectClassLoader.java:135)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)

The workaround is to add the following to the pom.xml

<dependency>
            <groupId>org.drools</groupId>
            <artifactId>drools-wiring-dynamic</artifactId>
            <version>8.33.0.Final</version>
        </dependency>

Does anyone know why this needs to be added manually? I don't see anything about this in the documentation.

Link to a replicator: https://github.com/code4dc/kogito-examples/tree/drools-wiring-replicator/kogito-springboot-examples/ruleunit-springboot-example

This uses Kogito instead of pure Drools but the error is still the same. Just go into the ruleunit-springboot-example dir and run mvn clean verify


Solution

  • Cannot reproduce.

    I've been following the steps you listed, and up to this commit it works as expected (tests are passing, no stacktraces), without having to add any additional dependencies.

    Further, I'm not sure what you are trying to achieve, but a more idiomatic way to write the rule for that mod would be:

    rule "will execute per each Measurement having ID color"
    when
        $measure: /measurements[ id == "color", $colorVal : val != "BS" ]
    then
        controlSet.add($colorVal);
        modify( $measure ) {
            setVal( "BS" )
        }
    end
    

    So the controlSet line is used to make sure non-regression during the test, the fact is modified with the modify() { expression } form which is idiomatic, and to avoid re-entry for property reactivity, we exclude the hardcoded value of "BS".

    In the test case for aligning with your use case in the way I could only guess, I've added:

    assertTrue( queryResult.stream().map(Measurement::getVal).allMatch("BS"::equals) );
    

    and tests are again passing, as expected (proved in this following commit).