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

   ### Component
   
   Drools
   
   ### Versions
   
   Drools: 10.2.0
   Java: 21 runtime (locally 21.0.2); Maven compilation target 17
   Spring Boot: 3.5.16
   Maven: 3.9.16 (locally installed)
   
   ### Problem
   
   A fact is dynamic when the entry point is registered on it as a JavaBeans
   `PropertyChangeListener`, either through `insert(fact, true)` or because its 
type is
   declared `@propertyChangeSupport`. Its setters then notify the session and 
the rules
   matching it are re-evaluated with no explicit `update` call.
   
   That registration does not survive marshalling. The listener is the entry 
point
   itself, which is not serializable, so `PropertyChangeSupport` silently omits 
it and
   the blob carries an empty listener list. `ProtobufOutputMarshaller` does not 
record
   that the fact was dynamic, and `ProtobufInputMarshaller` re-creates the 
handle and
   asserts it into the network without registering any listener.
   
   The restored fact still holds the right values, which makes this easy to 
miss: the
   object looks correct while the engine was never told it changed. 
`fireAllRules()`
   does not compensate — there is no activation to fire, because nothing 
re-evaluated
   the pattern.
   
   - Fresh session: setter changes the fact → the entry point receives the 
event →
     affected rules can fire.
   - Restored session: the same setter changes the fact → no listener receives 
the
     event → the fact is never re-evaluated.
   
   ### Reproducer
   
   ```java
   public static class DynamicFact implements Serializable {
       private final PropertyChangeSupport support = new 
PropertyChangeSupport(this);
       private String name;
   
       public DynamicFact(String name) { this.name = name; }
       public String getName() { return name; }
   
       public void setName(String name) {
           String old = this.name;
           this.name = name;
           support.firePropertyChange("name", old, name);
       }
       public void addPropertyChangeListener(PropertyChangeListener l) { 
support.addPropertyChangeListener(l); }
       public void removePropertyChangeListener(PropertyChangeListener l) { 
support.removePropertyChangeListener(l); }
   }
   ```
   
   ```drl
   rule "name changed"
   when
       DynamicFact( name == "changed" )
   then
   end
   ```
   
   ```java
   KieSession session = kieBase.newKieSession();
   ((WorkingMemoryEntryPoint) session.getEntryPoint("DEFAULT"))
           .insert(new DynamicFact("initial"), true);
   session.fireAllRules();
   
   ByteArrayOutputStream baos = new ByteArrayOutputStream();
   MarshallerFactory.newMarshaller(kieBase).marshall(baos, session);
   session.dispose();
   
   KieSession restored = MarshallerFactory.newMarshaller(kieBase)
           .unmarshall(new ByteArrayInputStream(baos.toByteArray()));
   
   DynamicFact fact = (DynamicFact) restored.getObjects().iterator().next();
   fact.setName("changed");
   
   restored.fireAllRules();   // returns 0, expected 1
   ```
   
   The same happens with a plain insert when the type is declared
   @propertyChangeSupport.
   
   Expected behaviour
   
   An unmarshalled session behaves like the session that was marshalled: a fact 
that was
   dynamic before the round trip stays dynamic, and its setters go on notifying 
the
   engine. A fact inserted without the dynamic flag stays non-dynamic.


-- 
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