Uploaded image for project: 'Drools'
  1. Drools
  2. DROOLS-7197

Generics work different in executable model than in MVEL

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Done
    • Icon: Major Major
    • None
    • 7.73.0.Final
    • None
    • 2022 Week 41-43 (from Oct 10), 2022 Week 44-46 (from Oct 31), 2022 Week 47-49 (from Nov 21), 2022 Week 50-02 (from Dec 12)
    • 2
    • Hide

      Project https://github.com/flozano/drools-issues class GenericOverrideTest, when using executable model, test ensureOverrideWorksWell fails (uses motor property), whereas ensureOverrideWorksWellOK passes (uses engine property).

      When using MVEL engine both tests pass.

       

       

       

      ~/Projects/java/drools-issues  main ❯ ./gradlew test --tests GenericOverrideTest
      To honour the JVM settings for this build a single-use Daemon process will be forked. See https://docs.gradle.org/7.4.2/userguide/gradle_daemon.html#sec:disabling_the_daemon.
      Daemon will be stopped at the end of the build> Task :test FAILEDGenericOverrideTest > ensureOverrideWorks(RuntimeType) > drools.issues.GenericOverrideTest.ensureOverrideWorks(RuntimeType)[2] FAILED
          drools.issues.executor.InvalidRulesException at GenericOverrideTest.java:174 tests completed, 1 failedFAILURE: Build failed with an exception.* What went wrong:
      Execution failed for task ':test'.
      > There were failing tests. See the report at: file:///Users/flozano/Projects/java/drools-issues/build/reports/tests/test/index.html* Try:
      > Run with --stacktrace option to get the stack trace.
      > Run with --info or --debug option to get more log output.
      > Run with --scan to get full insights.* Get more help at https://help.gradle.orgBUILD FAILED in 4s
      4 actionable tasks: 4 executed
      Show
      Project https://github.com/flozano/drools-issues class GenericOverrideTest , when using executable model, test ensureOverrideWorksWell fails (uses motor property), whereas ensureOverrideWorksWellOK passes (uses engine property). When using MVEL engine both tests pass.       ~/Projects/java/drools-issues  main ❯ ./gradlew test --tests GenericOverrideTest To honour the JVM settings for this build a single-use Daemon process will be forked. See https://docs.gradle.org/7.4.2/userguide/gradle_daemon.html#sec:disabling_the_daemon. Daemon will be stopped at the end of the build> Task :test FAILEDGenericOverrideTest > ensureOverrideWorks(RuntimeType) > drools.issues.GenericOverrideTest.ensureOverrideWorks(RuntimeType)[2] FAILED     drools.issues.executor.InvalidRulesException at GenericOverrideTest.java:174 tests completed, 1 failedFAILURE: Build failed with an exception.* What went wrong: Execution failed for task ':test'. > There were failing tests. See the report at: file:///Users/flozano/Projects/java/drools-issues/build/reports/tests/test/index.html* Try: > Run with --stacktrace option to get the stack trace. > Run with --info or --debug option to get more log output. > Run with --scan to get full insights.* Get more help at https://help.gradle.orgBUILD FAILED in 4s 4 actionable tasks: 4 executed
    • Workaround Exists
    • Hide

      Use "#" to specify the sub class.

      $v:DieselCar(motor#DieselEngine.adBlueRequired==true)
      

       

      Show
      Use "#" to specify the sub class. $v:DieselCar(motor#DieselEngine.adBlueRequired==true)  
    • Set a Value
    • NEW
    • NEW
    • ---
    • ---

      I have an abstract base class for some facts. This base class has two getters, one is abstract and is overridden by subclasses. The other method is just an "alias" of the first one, just delegates to it. Both return a generic type, specified by the subclasses.

      When using executable model, accessing the "abstract" getter I can see the full generic type specified by the subclass, whereas if I access the getter of the same generic type that just delegates to the abstract one, I cannot see any property defined by the concrete type, just the ones visible from the abstract class.

      When using mvel engine, both getters work the same.

      Here are the relevant parts of the reproducing code, as an example to illustrate the issue.

      Base fact class:

      public abstract class Vehicle<TEngine extends Engine> {
              // ...
      
      	public abstract TEngine getEngine();
      
      	public TEngine getMotor() {
      		return getEngine();
      	}
      
      

      Subclass

      public class DieselCar extends Vehicle<DieselEngine> {
      	private final DieselEngine engine;
      
      	public DieselCar(String maker, String model, int kw, boolean adBlueRequired) {
      		super(maker, model);
      		this.engine = new DieselEngine(kw, adBlueRequired);
      	}
      
      	@Override
      	public DieselEngine getEngine() {
      		return engine;
      	}
      }
      

      Parameter type used in the DieselCar class when subclassing Vehicle:

      public class DieselEngine extends Engine {
      
      	private final boolean adBlueRequired;
      // getters
      

      In this example, adBlueRequired is only accessible in DieselCar facts.

      These two DRLs should be equivalent:
      Using motor property

      dialect "mvel"
      
      rule "Diesel cars with ad-blue have score of 5"
      	when
      		$v:drools.issues.model.vehicles.DieselCar(motor.adBlueRequired==true)
      	then
      		$v.score=5;		
      end
      

      and using engine

      dialect "mvel"
      
      rule "Diesel cars with ad-blue have score of 5"
      	when
      		$v:drools.issues.model.vehicles.DieselCar(engine.adBlueRequired==true)
      	then
      		$v.score=5;		
      end
      

      but they're not - the first one fails, the second one works.

      when I use motor instead of engine, the error I get is:

      InvalidExpressionErrorResult: Unknown field adBlueRequired on TEngine
      
      [main] ERROR drools.issues.executor.DroolsInternalFactory - KieBuilder has errors (releaseId=drools.issues.rules:GenericOverrideTest_ensureOverrideWorks.drl:1.0.0): Error Messages:
      Message [id=1, kieBase=defaultKieBase, level=ERROR, path=drools/issues/GenericOverrideTest_ensureOverrideWorks.drl, line=-1, column=0
         text=Unknown field adBlueRequired on TEngine]
      ---
      Warning Messages:
      ---
      Info Messages:
      
      [main] WARN drools.issues.executor.DroolsInternalFactory - failing DRL: 
      // DRL directly from drools/issues/GenericOverrideTest_ensureOverrideWorks.drl
      package drools.issues;
      
      dialect "mvel"
      
      rule "Diesel cars with ad-blue have score of 5"
      	when
      		$v:drools.issues.model.vehicles.DieselCar(motor.adBlueRequired==true)
      	then
      		$v.score=5;		
      end
      
      //
      

              mfusco@redhat.com Mario Fusco
              flozano@gmail.com Francisco Alejandro Lozano López
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

                Created:
                Updated:
                Resolved: