Search code examples
droolsjboss-tools

Possible bug when comparing a value in an 'Object' field


I've been able to recreate this error in 6.0.3 and in 6.2.0. I'm not sure of the best way to explain it so i'll add code that reproduces it too.

I've pared down the code to just what would cause the error. In my original code I use some other pojos that are similar. Instead of pasting all of those classes in, this just uses some common java classes that have the same effect. You can use any Class though to get the same error

EventObject - can be any class that stores an 'Object' and has a getter and setter for that field

Random - can be any class that does not have a constructor with a single String argument

Integer - can be any class

When a rule is comparing a value that is contained in a field and the field is of the 'Object' class, Sometimes the rule tries to create a new instance of the object that it's trying to compare the value to and pass a String representation of that value into the constructor.

import java.util.EventObject;
import java.util.Random;

/**
 * The offending line is the comparison of the EventObjects Source (an Integer 
 * in this case) with the Random. Occasionally when trying to compare the two,
 * the rules processor tries to find a constructor for Random that has a string.
 * If it finds one, it attempts to pass String.valueOf(Integer) to the
 * constructor. If it doesn't find it, a reflections error is thrown:
 * java.lang.NoSuchMethodError: java.util.Random.<init>(Ljava/lang/String;)V
 *
 * The actual classes for the three types don't matter as long as EventObject is
 * any class that contains an Object field that can be set and retrieved, and
 * Random is any class that does not contain a Constructor with a single
 * String argument
 */

rule "Insert objects"
    dialect "java"
    agenda-group "aHiddenAgenda"
    when
        not Integer()
    then
        /* add more EventObjects to increase the failure rate. 10 almost always
         * works, 1000 almost never works
         */
        for(int i = 0; i < 175; i++) {
            insert(new EventObject(new Integer(i)));
        }
        for(int i = 0; i < 10; i++) {
            insert(new Random());
        }
end

rule "Find a Random where no EventObject contains it"
    dialect "java"
    agenda-group "aHiddenAgenda"
    when
        $toCompare : Random()
        not EventObject( $toCompare == source )
    then
end

Solution

  • OK, you have hit a bug in 6.2.0 and earlier.

    It is gone in 6.3.0 and 6.4.0 which I've tried and presumably later versions.