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

ClassCastException on Fact Attribute Set After UpdateToVersion

    XMLWordPrintable

Details

    • Bug
    • Resolution: Done
    • Major
    • 7.43.0.Final
    • 7.41.0.Final
    • core engine
    • None
    • 2020 Week 34-36 (from Aug 17)
    • NEW
    • NEW

    Description

      After updating a KieContainer with a change in a fact type UnreferencedType, if instances of another unrelated fact type ReferencedType are modified in a rule, then setting any field of ReferencedType through the FactType API will throw a ClassCastException:

      java.lang.ClassCastException: class org.example.facts.ReferencedType cannot be cast to class org.example.facts.ReferencedType (org.example.facts.ReferencedType is in unnamed module of loader org.drools.dynamic.DynamicProjectClassLoader$DefaultInternalTypesClassLoader @59901c4d; org.example.facts.ReferencedType is in unnamed module of loader org.drools.dynamic.DynamicProjectClassLoader$DefaultInternalTypesClassLoader @5e1fc2aa)
       
       at org.drools.base.org.example.facts.ReferencedType1921143808$setStr.setValue(Unknown Source)
       at org.drools.core.base.ClassFieldWriter.setValue(ClassFieldWriter.java:164)
       at org.drools.core.base.ClassFieldAccessor.setValue(ClassFieldAccessor.java:246)
       at org.drools.core.factmodel.ClassDefinition.set(ClassDefinition.java:278)
       at org.example.reproducer.FactTypeUpdateTest.testUpdateThenSetFactAttribute(FactTypeUpdateTest.java:132)
       at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
       at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
       at java.base/java.lang.reflect.Method.invoke(Method.java:566)
       at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
       at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
       at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
       at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
       at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
       at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
       at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
       at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
       at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
       at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
       at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
       at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
       at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
       at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
       at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
       at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
       at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
       at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
       at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
       at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
       at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
       at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)

      Below the example DRL that triggers the issue.

      Initial DRL:

       package org.example.facts 
       declare ReferencedType
       str : String
       end
       declare UnreferencedType
       x : int
       end
       
       package org.example.rules
       import org.example.facts.*;
       rule "rule updating ReferencedType"
       when
       $x : ReferencedType( )
       then
       $x.setStr("foo");
       update($x);
       end

      Updated DRL:

       package org.example.facts 
       declare ReferencedType
       str : String
       end
       declare UnreferencedType
       x : int
       y : String // NEW ATTRIBUTE ADDED HERE
       end
       
       package org.example.rules
       import org.example.facts.*;
       rule "rule updating ReferencedType"
       when
       $x : ReferencedType( )
       then
       $x.setStr("foo");
       update($x);
       end

      Throwing code example:

      updateToVersion(); // Updates the KieContainer
      KieBase kiebase = kieContainer.getKieBase("ExampleKiebase");
      FactType referencedType = kiebase.getFactType("org.example.facts", "ReferencedType"); 
      Object instance = referencedType.newInstance();
      referencedType.set(instance, "str", "bar"); // Throws ClassCastException

       

      This is similar to DROOLS-5449, but in this case we instantiate the fact from the updated fact type, so we believe that there is no API misuse.

      Attachments

        Activity

          People

            mfusco@redhat.com Mario Fusco
            mcasalino Matteo Casalino (Inactive)
            Votes:
            2 Vote for this issue
            Watchers:
            5 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: