tkobayas opened a new issue, #7137:
URL: https://github.com/apache/incubator-kie/issues/7137

   **Describe the bug**
   
   With the executable model, `@propertyChangeSupport` on a DRL type 
declaration has no effect. The engine does not register itself as a 
`PropertyChangeListener` on inserted facts, so setters that fire 
`PropertyChangeEvent` do not trigger an update.
   
   It works with the non-executable model (DRL compiled by `drools-compiler`).
   
   Related: #7132. That issue deprecates `insert(Object object, boolean 
dynamic)` and points users to `@propertyChangeSupport`. Today, executable model 
users have no working replacement.
   
   **Expected behavior**
   
   Same as the non-executable model: after `ksession.insert(fact)`, the engine 
registers a listener on the fact, and a property change event causes an update 
of the fact.
   
   **Actual behavior**
   
   No listener is registered (`getPropertyChangeListeners().length == 0` after 
insert). The property change is not seen by the engine, and rules that depend 
on it do not fire.
   
   **How to Reproduce?**
   
   A JavaBean fact:
   
   ```java
   public class DynamicFact {
       private final PropertyChangeSupport support = new 
PropertyChangeSupport(this);
       private String name;
       private String value;
   
       public String getName() { return name; }
       public void setName(String name) {
           String old = this.name;
           this.name = name;
           support.firePropertyChange("name", old, name);
       }
       public String getValue() { return value; }
       public void setValue(String value) {
           String old = this.value;
           this.value = value;
           support.firePropertyChange("value", old, value);
       }
       public void addPropertyChangeListener(PropertyChangeListener l) { 
support.addPropertyChangeListener(l); }
       public void removePropertyChangeListener(PropertyChangeListener l) { 
support.removePropertyChangeListener(l); }
   }
   ```
   
   DRL:
   
   ```drl
   import org.example.DynamicFact;
   
   declare DynamicFact
       @propertyChangeSupport
   end
   
   rule rule1 when
       $f : DynamicFact( name == "user1" )
   then
       $f.setName("user2");   // no modify: the property change event should 
trigger the update
   end
   
   rule rule2 when
       $f : DynamicFact( name == "user2" )
   then
       $f.setValue("VAL1");
   end
   ```
   
   ```java
   DynamicFact fact = new DynamicFact();
   fact.setName("user1");
   ksession.insert(fact);
   ksession.fireAllRules();
   // expected: fact.getValue() == "VAL1"
   ```
   
   Result with a `BaseModelTest` in `drools-model-codegen`:
   
   | Case | STANDARD_FROM_DRL | PATTERN_DSL (executable model) |
   |---|---|---|
   | `declare ... @propertyChangeSupport end` + `ksession.insert(fact)` | OK 
(listeners after insert: 1, `value = "VAL1"`) | **NG** (listeners after insert: 
0, `value = null`) |
   | RHS `insert(fact, true)` (deprecated) | OK | OK |
   
   **Additional information**
   
   Cause:
   
   - In the non-executable model, `TypeDeclarationFactory.processAnnotations()` 
sets `TypeDeclaration.setDynamic(true)`:
     
https://github.com/apache/incubator-kie/blob/a0b09cc64fa53b67770b4db69fe935df9bfc2220/drools-compiler/src/main/java/org/drools/compiler/builder/impl/TypeDeclarationFactory.java#L105
     At runtime, `NamedEntryPoint` registers the listener when 
`typeConf.isDynamic()` is true:
     
https://github.com/apache/incubator-kie/blob/a0b09cc64fa53b67770b4db69fe935df9bfc2220/drools-kiesession/src/main/java/org/drools/kiesession/entrypoints/NamedEntryPoint.java#L230
   - In the executable model, codegen (`POJOGenerator.processTypeMetadata()`) 
emits the annotation as `TypeMetaData`. But 
`TypeDeclarationUtil.wireMetaTypeAnnotations()` has no case for 
`propertyChangeSupport`, and it is not in `KNOWN_ANNOTATIONS`. It is only 
stored as custom metadata, and `setDynamic(true)` is never called:
     
https://github.com/apache/incubator-kie/blob/a0b09cc64fa53b67770b4db69fe935df9bfc2220/drools-model/drools-model-compiler/src/main/java/org/drools/modelcompiler/util/TypeDeclarationUtil.java#L53-L120
   
   The existing test `PropertyReactivityTest.testPropertyChangeSupportNewAPI` 
runs with the executable model too, but it does not catch this. Its assertions 
(the rule does not re-fire, and no listener is left after `dispose()`) are also 
true when no listener was ever registered:
   
https://github.com/apache/incubator-kie/blob/a0b09cc64fa53b67770b4db69fe935df9bfc2220/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/PropertyReactivityTest.java#L1693
   
   Proposed fix:
   
   1. In `TypeDeclarationUtil`, add `"propertyChangeSupport"` to 
`KNOWN_ANNOTATIONS` and add a case in `wireMetaTypeAnnotations()`:
      ```java
      case "propertyChangeSupport":
          typeDeclaration.setDynamic( true );
          break;
      ```
      No runtime change is needed.
   2. Add an executable model test (`BaseModelTest`) with the scenario above: 
automatic update, and listener count after insert / delete / dispose.
   3. Make `testPropertyChangeSupportNewAPI` assert that a listener is 
registered after insert.
   
   Open questions:
   
   - The non-executable model also accepts the capitalized form 
`@PropertyChangeSupport` in DRL. Should the executable model accept it too? 
Other annotations in `wireMetaTypeAnnotations()` (`role`, `expires`, ...) are 
matched by the exact lowercase name as well.
   - The Java annotation `org.kie.api.definition.type.PropertyChangeSupport` on 
a Java class is ignored in both models 
(`TypeDeclaration.processTypeAnnotations()` does not read it). Should it be 
supported, here or in a separate issue?
   
   Version: main (`999-SNAPSHOT`, a0b09cc64fa), Java 17.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to