On Mon, 12 Oct 2026 15:54:37 GMT, Marius Hanl <[email protected]> wrote:

>> Many tests already fail if you get this wrong (it was a bad commit on my 
>> side), it perhaps wasn't 5000 tests that failed, but it was a lot :)
>> 
>> I think there even already is a targetted test (but it is so fundamental 
>> that many others will fail as well).
>
> I digged deeper into the vetoing and the `logNonConvergence` the last days 
> and I really like it. 
> Digging into the code, I have one question. I wrote a test which demonstrates 
> my question:
> 
> 
>     @Test
>     void test() {
>         SimpleIntegerProperty property = new SimpleIntegerProperty(0);
>         List<Change> firstListenerChanges = new ArrayList<>();
>         List<Change> secondListenerChanges = new ArrayList<>();
>         List<Change> thirdListenerChanges = new ArrayList<>();
> 
>         property.addListener((_, old, current) -> {
>             System.out.println("L1");
>             firstListenerChanges.add(new Change("L1", old, current));
> 
>             if (current.intValue() == 2) {
>                 property.set(1);
>             }
>         });
>         property.addListener((_, old, current) -> {
>             System.out.println("L2");
>             secondListenerChanges.add(new Change("L2", old, current));
>         });
>         property.addListener((_, old, current) -> {
>             System.out.println("L3");
>             thirdListenerChanges.add(new Change("L3", old, current));
> 
>             if (current.intValue() == 1) {
>                 System.out.println("Set 2");
>                 property.set(2);
>                 System.out.println("Set 3");
>                 property.set(3);
>             }
>         });
> 
>         property.set(1);
> 
>         assertEquals(3, property.get());
>         assertConsistentChangeSequence(firstListenerChanges, 0, 3, Set.of(0, 
> 1, 2, 3));
>         assertConsistentChangeSequence(secondListenerChanges, 0, 3, Set.of(0, 
> 1, 2, 3));
>         assertConsistentChangeSequence(thirdListenerChanges, 0, 3, Set.of(0, 
> 1, 2, 3));
>     }
> 
> 
> It prints out:
> 
> L1
> L2
> L3
> Set 2
> L1
> L1
> Oct 12, 2026 5:52:27 PM com.sun.javafx.binding.ListenerList logNonConvergence
> WARNING: IntegerProperty [value: 1] was modified during the invocation of 
> multiple listeners, and the values set do not seem to be converging; the 
> listener 
> test.javafx.beans.ObservableValueTest$$Lambda/0x000000005826df70@2a7686a7 
> changed the value from 1 to 2, which was then reset to 1 by another listener; 
> to avoid this warning ensure listeners are not making conflicting updates, or 
> avoid changing the value in listeners
> 
> Set 3
> L1
> 
> 
> Shouldn't listener 2 (L2) and L3 also be notified in that case?

Yes, they should indeed be notified -- an earlier iteration (when `progress` 
was still used for two way communication up and down the call stack) had this 
correct, but it has regressed and no test caught it.

The problem is that when a nested loop exits, normally `progress` will be 
exactly set to the value that it had when the parent loop called it -- but when 
non-convergence happens, it exits the loop hard, and leaves `progress` at some 
different value. The fix is to restore `progress` always before exiting a 
nested loop.

-------------

PR Review Comment: https://git.openjdk.org/jfx/pull/1081#discussion_r4251642807

Reply via email to