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]