Re: JavaFX Application Thread is recursively re-entrant into Eventhandler handle() method under some circumstances

2018-09-09 Thread javafx
I am reading your stack trace but I defintely never mentioned the 
double invocation to handle that I see there are evidencing anything. 
The issue is the value of debugCounter at a two certain moments in the 
application - in the two calls to showDebugInformation. 


Although the proof that I am right is contained in the value 
debugCounter in the method showDebugInformation in the current program, 
if you go to the link in my previous post and download  and run the 
Complex version of this, you can more easily see the departure of the 
JavaApplicationThread from the instance of handle which is on the stack 
- and at a method which is not handle (as it is in this one) followed 
by  it's recursive re-entry to handle , completion of that 
recursive-handle's execution and re-entry and then completion into the 
previous invocation of handle. It's is completely obvious in the output 
of that Applcation. 


That application also throws the ConcurrentModificationException which 
is no way an artifact or misreading of a stacktrace. 


However, what is at issue in this program is the value of debugCounter 
in showDebugInformation.


Cheers. 
 
On Sunday, September 9, 2018 at 4:04 PM, John Hendrikx 
 wrote:

 

I see nothing special in the stack trace.

When you remove the component, a new MouseEvent *must* trigger
(MouseEvent.EXITED) as it always needs to match with 
MouseEvent.ENTERED.


So, the call to 'remove' triggers a new event, which gets handled by 
the

same handler.  It is indeed entered recursively, but in a normal
fashion.  This has nothing to do with another thread or compiler 
bugs.


Don't be confused by the double "handle" lines in the stacktrace. 
 This

happens when methods are overriden (the line number is 1).

There are two relevant lines in this trace:

   LabelEventHandler.handle(LabelEventHandler.java:95)

...where Remove is called, which triggers the recursive call later 
on:


   LabelEventHandler.handle(LabelEventHandler.java:88)

... for the MouseEvent.EXITED event.

The full stack trace is this:

at
bareBonesJavaFXBugExample.LabelEventHandler.handle(LabelEventHandler.java:88)
at
bareBonesJavaFXBugExample.LabelEventHandler.handle(LabelEventHandler.java:1)
at
javafx.base/com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
at
javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at
javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at
javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at
javafx.base/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at
javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at
javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at
javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at
javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at
javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at 
javafx.base/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)

at javafx.base/javafx.event.Event.fireEvent(Event.java:198)
at 
javafx.base/com.sun.javafx.event.EventQueue.fire(EventQueue.java:48)

at
javafx.graphics/javafx.scene.Scene$MouseHandler.handleNodeRemoval(Scene.java:3717)
at
javafx.graphics/javafx.scene.Scene$MouseHandler.access$7800(Scene.java:3604)
at 
javafx.graphics/javafx.scene.Scene.generateMouseExited(Scene.java:3601)
at 
javafx.graphics/javafx.scene.Parent$3.onProposedChange(Parent.java:613)

at
javafx.base/com.sun.javafx.collections.VetoableListDecorator.remove(VetoableListDecorator.java:329)
at
javafx.base/com.sun.javafx.collections.VetoableListDecorator.remove(VetoableListDecorator.java:221)
at
bareBonesJavaFXBugExample.LabelEventHandler.handle(LabelEventHandler.java:95)
at
bareBonesJavaFXBugExample.LabelEventHandler.handle(LabelEventHandler.java:1)
at
javafx.base/com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)

(... rest cut off as it is not needed ... )

--John

On 09/09/2018 19:05, jav...@use.startmail.com wrote:

Hi All,
I spent some time refactoring the program which displays this bug. 
It's
now small enough to share the source in an email, but it is very 
very
dense and the proof of bug, one  specific line to standard I/O, 
requires
the source code to be read and understood in order to see the bug. 
As I
said previously, more comprehensible and user-friendly versions of 
this

program are  available at . The javadoc is more copious, the bug is
manifested as an exception and the side effect of the bug are more
consequential.

This brief version cnosists of just two classes. 

Re: JavaFX Application Thread is recursively re-entrant into Eventhandler handle() method under some circumstances

2018-09-09 Thread javafx
I did not say it was another Thread. In fact, I said it was the Java 
Application Thread itself- being recursively re-entrant.


Specifically, at the time the MOUSE_EXITED_TARGET event is generated, 
the Java Application Thread has a choice- continue proocessing the 
EventHandler#handle method which it is in, or respond to 
the MOUSE_EXITED_TARGET event which was just generated. Suprisingly, it 
does the second , completes that call to handle, then the stack pops 
and it nfinishes the previous invocation of handle. It's not about 
another Thread.



I don't   refer to the stack trace as proof   that the thread is 
reentrant. I do say the contrapositve of that, which is, if the thread 
trace didn't show the bug  then the bug  wouldn't  exist. But I don't 
assert the stack trace as a proof.


The proof is  the proof  I gave in the javadoc, and that is the value 
of one the static int debugCounter acheives in the debug statements can 
only be explained if  recursive re-entrancy has cocurred, which  is 
true. You need to address this. 


Also, this is merely the most barebones implementation which reveals 
this bug. This is why I didn't want to post it, because you have to 
work out what cannot be the case before evaluating the argument. What 
cannot be the case is  debugCounter cannot have value 1 in the debug 
output method. 


The link provides a more consequential /  more easily understood bug / 
less dismissable bug- a ConcurrentModificationException  against a Set 
which the EventHandler is iterating through. That CME happens not 
because two threads are operating on the Set but because one thread , 
the JAva Application Thread is modifying the Set while it is also 
iterating through it. 


 


 
On Sunday, September 9, 2018 at 4:04 PM, John Hendrikx 
 wrote:

 

I see nothing special in the stack trace.

When you remove the component, a new MouseEvent *must* trigger
(MouseEvent.EXITED) as it always needs to match with 
MouseEvent.ENTERED.


So, the call to 'remove' triggers a new event, which gets handled by 
the

same handler.  It is indeed entered recursively, but in a normal
fashion.  This has nothing to do with another thread or compiler 
bugs.


Don't be confused by the double "handle" lines in the stacktrace. 
 This

happens when methods are overriden (the line number is 1).

There are two relevant lines in this trace:

   LabelEventHandler.handle(LabelEventHandler.java:95)

...where Remove is called, which triggers the recursive call later 
on:


   LabelEventHandler.handle(LabelEventHandler.java:88)

... for the MouseEvent.EXITED event.

The full stack trace is this:

at
bareBonesJavaFXBugExample.LabelEventHandler.handle(LabelEventHandler.java:88)
at
bareBonesJavaFXBugExample.LabelEventHandler.handle(LabelEventHandler.java:1)
at
javafx.base/com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
at
javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at
javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at
javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at
javafx.base/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at
javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at
javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at
javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at
javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at
javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at 
javafx.base/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)

at javafx.base/javafx.event.Event.fireEvent(Event.java:198)
at 
javafx.base/com.sun.javafx.event.EventQueue.fire(EventQueue.java:48)

at
javafx.graphics/javafx.scene.Scene$MouseHandler.handleNodeRemoval(Scene.java:3717)
at
javafx.graphics/javafx.scene.Scene$MouseHandler.access$7800(Scene.java:3604)
at 
javafx.graphics/javafx.scene.Scene.generateMouseExited(Scene.java:3601)
at 
javafx.graphics/javafx.scene.Parent$3.onProposedChange(Parent.java:613)

at
javafx.base/com.sun.javafx.collections.VetoableListDecorator.remove(VetoableListDecorator.java:329)
at
javafx.base/com.sun.javafx.collections.VetoableListDecorator.remove(VetoableListDecorator.java:221)
at
bareBonesJavaFXBugExample.LabelEventHandler.handle(LabelEventHandler.java:95)
at
bareBonesJavaFXBugExample.LabelEventHandler.handle(LabelEventHandler.java:1)
at
javafx.base/com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)

(... rest cut off as it is not needed ... )

--John

On 09/09/2018 19:05, jav...@use.startmail.com wrote:


Re: JavaFX Application Thread is recursively re-entrant into Eventhandler handle() method under some circumstances

2018-09-09 Thread John Hendrikx

I see nothing special in the stack trace.

When you remove the component, a new MouseEvent *must* trigger 
(MouseEvent.EXITED) as it always needs to match with MouseEvent.ENTERED.


So, the call to 'remove' triggers a new event, which gets handled by the 
same handler.  It is indeed entered recursively, but in a normal 
fashion.  This has nothing to do with another thread or compiler bugs.


Don't be confused by the double "handle" lines in the stacktrace.  This 
happens when methods are overriden (the line number is 1).


There are two relevant lines in this trace:

   LabelEventHandler.handle(LabelEventHandler.java:95)

...where Remove is called, which triggers the recursive call later on:

   LabelEventHandler.handle(LabelEventHandler.java:88)

... for the MouseEvent.EXITED event.

The full stack trace is this:

	at 
bareBonesJavaFXBugExample.LabelEventHandler.handle(LabelEventHandler.java:88)
	at 
bareBonesJavaFXBugExample.LabelEventHandler.handle(LabelEventHandler.java:1)
	at 
javafx.base/com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
	at 
javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
	at 
javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
	at 
javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
	at 
javafx.base/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
	at 
javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
	at 
javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
	at 
javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
	at 
javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
	at 
javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)

at 
javafx.base/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
at javafx.base/javafx.event.Event.fireEvent(Event.java:198)
at javafx.base/com.sun.javafx.event.EventQueue.fire(EventQueue.java:48)
	at 
javafx.graphics/javafx.scene.Scene$MouseHandler.handleNodeRemoval(Scene.java:3717)
	at 
javafx.graphics/javafx.scene.Scene$MouseHandler.access$7800(Scene.java:3604)

at 
javafx.graphics/javafx.scene.Scene.generateMouseExited(Scene.java:3601)
at 
javafx.graphics/javafx.scene.Parent$3.onProposedChange(Parent.java:613)
	at 
javafx.base/com.sun.javafx.collections.VetoableListDecorator.remove(VetoableListDecorator.java:329)
	at 
javafx.base/com.sun.javafx.collections.VetoableListDecorator.remove(VetoableListDecorator.java:221)
	at 
bareBonesJavaFXBugExample.LabelEventHandler.handle(LabelEventHandler.java:95)
	at 
bareBonesJavaFXBugExample.LabelEventHandler.handle(LabelEventHandler.java:1)
	at 
javafx.base/com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)


(... rest cut off as it is not needed ... )

--John

On 09/09/2018 19:05, jav...@use.startmail.com wrote:

Hi All,
I spent some time refactoring the program which displays this bug. It's
now small enough to share the source in an email, but it is very very
dense and the proof of bug, one  specific line to standard I/O, requires
the source code to be read and understood in order to see the bug. As I
said previously, more comprehensible and user-friendly versions of this
program are  available at . The javadoc is more copious, the bug is
manifested as an exception and the side effect of the bug are more
consequential.

This brief version cnosists of just two classes. Here is the JavaFX
Application class:

***

package bareBonesJavaFXBugExample;


import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;



/**
 * An {@link Application} with one {@link Pane} containing one {@link
Label}. The {@link Label} has a single {@link
javafx.event.EventHandler}, {@link LabelEventHandler} which processes
all {@link MouseEvent}s the {@link Label} receives.
 * 
 * To trigger the bug, run the application, then spend a second mouse
over the little label in the upper left hand corner of the scrren. You
will see output to standard I/O. Then, click the label, which will then
disppear. Check the I/O for Strings ending in debugCounter is 1. 
 * What that String means and how it proves that the JavaFX Application
Thread has become reentrant is explained in the javadoc of {@link
LabelEventHandler}.
 */
public class JavaFXAnomalyBareBonesApplication extends Application
{
public void start(Stage primaryStage)
 

Re: JavaFX Application Thread is recursively re-entrant into Eventhandler handle() method under some circumstances

2018-09-09 Thread javafx

Hi All,
I spent some time refactoring the program which displays this bug. It's 
now small enough to share the source in an email, but it is very very 
dense and the proof of bug, one  specific line to standard I/O, 
requires the source code to be read and understood in order to see the 
bug. As I said previously, more comprehensible and user-friendly 
versions of this program are  available at . The javadoc is more 
copious, the bug is manifested as an exception and the side effect of 
the bug are more consequential.


This brief version cnosists of just two classes. Here is the JavaFX 
Application class:


***

package bareBonesJavaFXBugExample;


import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;



/**
 * An {@link Application} with one {@link Pane} containing one {@link 
Label}. The {@link Label} has a single {@link 
javafx.event.EventHandler}, {@link LabelEventHandler} which processes 
all {@link MouseEvent}s the {@link Label} receives.

 * 
 * To trigger the bug, run the application, then spend a second mouse 
over the little label in the upper left hand corner of the scrren. You 
will see output to standard I/O. Then, click the label, which will then 
disppear. Check the I/O for Strings ending in debugCounter is 1. 

 * What that String means and how it proves that the JavaFX Application 
Thread has become reentrant is explained in the javadoc of {@link 
LabelEventHandler}.

 */
public class JavaFXAnomalyBareBonesApplication extends Application
{
    public void start(Stage primaryStage)
    {

      Pane mainPane = new Pane();
      mainPane.setMinHeight(800);
      mainPane.setMinWidth(800);

      Label label = new Label(" this is quite a bug ");

      LabelEventHandler labelEventHandler = new 
LabelEventHandler(mainPane, label);

      label.addEventHandler(MouseEvent.ANY, labelEventHandler);

      mainPane.getChildren().add(label);


      Scene scene = new Scene(mainPane);
      primaryStage.setScene(scene);
      primaryStage.show();

    }



    /**
     * The entry point of application.
     *
     * @param args
     *         the input arguments
     */
    public static void main(String[] args)
    {

        launch(args);
    }



}


***

and here is its only dependency, the EventListener class. I included 
enough javadoc to have the program makes sense. :


***

package bareBonesJavaFXBugExample;



import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.scene.control.Label;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;

import java.util.Collection;
import java.util.ConcurrentModificationException;

/**
 * An {@link EventHandler} implementation for {@link MouseEvent}s. 
 This implementation's {@link EventHandler#handle(Event)} shows 
the relevant debug information to standard output before and after 
removing the member {@link #label} from the {@link #pane}.

 * 
 * discussion
 * 
 * Users should first satisfy themselves that the value of {@link 
LabelEventHandler#debugCounter} can only be non-zero, in fact 1 (one) 
in the method {@link LabelEventHandler#showDebugInformation(String)} if 
the method {@link LabelEventHandler#handle(MouseEvent)}  has been 
re-entered recursively, that is, before a previous invocation of {@link 
LabelEventHandler#handle(MouseEvent)} has returned.

 * 
 * Proof:  1) debugCounter starts at value 0 
(zero).  2) debugCounter is only incremented once, 
by 1 (one), and that is after the first call to {@link 
LabelEventHandler#showDebugInformation(String)} has returned. 3) 
debugCounter is only decremented once, by 1 (one) and that 
is before the last call to {@link 
LabelEventHandler#showDebugInformation(String)}. 4) however, 
because
 * debugCounter is a class variable ( it's static), if 
handle() is recurvsively re-entered then it's value can be 1 (one) when 
the re-entrant Thread executes {@link 
LabelEventHandler#showDebugInformation(String)}

 * 
 * End proof.
 * 
 * 
 * 
 * The output of this method to standard I/O is volumnious but 
searching the output for the exact String "debugCounter is 1" will 
immediately show the {@link LabelEventHandler#handle(MouseEvent)} 
method to have been recursively entered. 
 * Some other possibilities other than the JavaFX Application Thread 
recursing into {@code handle()} need to be addressed.  One is 
the fact that the compiler is free to reorder statements if it can
 * prove that such a reordering would have no effect on the program's 
correctness.

 * 
 * So somehow the compiler is reordering the increment/decrement of 
{@code  debugCounter} and the calls to {@code   showDebugInformation}. 
 But this would 

Re: JavaFX Application Thread is recursively re-entrant into Eventhandler handle() method under some circumstances

2018-09-08 Thread javafx

Here is the link to the demonstration applications for this issue.

I noticed one small javadoc error which references a class whose name 
was changed in a refactoring, but it should not really confuse anyone. 


You have to read the readme.txt .

https://uploadfiles.io/ejt5h


HTH
 
On Friday, September 7, 2018 at 8:37 PM, jav...@use.startmail.com 
wrote:

 

Hi, 

I have a couple of very small apps (3 small classes in one case and 5
in another)  which demonstrate that, under some circumstances, the
JavaFX Application Thread will recursively re-enter
EventHandler#handle().

So this means that it is already in handle (and calls therefrom) and
will, in some situations not complete that  processing (thus exiting
handle) before it reappears in the same instance of EventHandler's
handle method again. So this is true recursion.

I actually don't know if this is expected behavior or not. No one 
I've

talked to expected it; the general understanding is the JavaFX
Application Thread (processing) is specifically single-threaded and
also that it will defintily complete one invocation of handle() 
before

beginning another one.

I have to say that there is NO other Thread  in play here, at least 
no
other Thread my applications create (what's going on QuantumToolKit 
may

be a different story.)

The material upshot of this is it can lead to apparent  program
incorrectness if the dev believes that it's not the case, and 100% of
devs I've talked to think it's not possible. 

I am happy to post or attach the classes or modules as requested but
first I wanted to check to see if in fact this is already known to be
true and is in fact  expected behavior, in which case it's a 
non-issue

and just a subtlety people are not aware of.

Thank you so much !


Re: JavaFX Application Thread is recursively re-entrant into Eventhandler handle() method under some circumstances

2018-09-08 Thread Kevin Rushforth
I am not aware of such a bug. If you have a test program, then you can 
file a bug here:


https://bugreport.java.com/

-- Kevin


On 9/7/2018 5:37 PM, jav...@use.startmail.com wrote:

Hi,

I have a couple of very small apps (3 small classes in one case and 5 
in another)  which demonstrate that, under some circumstances, the 
JavaFX Application Thread will recursively re-enter 
EventHandler#handle().


So this means that it is already in handle (and calls therefrom) and 
will, in some situations not complete that  processing (thus exiting 
handle) before it reappears in the same instance of EventHandler's 
handle method again. So this is true recursion.


I actually don't know if this is expected behavior or not. No one I've 
talked to expected it; the general understanding is the JavaFX 
Application Thread (processing) is specifically single-threaded and 
also that it will defintily complete one invocation of handle() before 
beginning another one.


I have to say that there is NO other Thread  in play here, at least no 
other Thread my applications create (what's going on QuantumToolKit 
may be a different story.)


The material upshot of this is it can lead to apparent  program 
incorrectness if the dev believes that it's not the case, and 100% of 
devs I've talked to think it's not possible.


I am happy to post or attach the classes or modules as requested but 
first I wanted to check to see if in fact this is already known to be 
true and is in fact  expected behavior, in which case it's a non-issue 
and just a subtlety people are not aware of.


Thank you so much !




JavaFX Application Thread is recursively re-entrant into Eventhandler handle() method under some circumstances

2018-09-07 Thread javafx

Hi, 

I have a couple of very small apps (3 small classes in one case and 5 
in another)  which demonstrate that, under some circumstances, the 
JavaFX Application Thread will recursively re-enter 
EventHandler#handle().


So this means that it is already in handle (and calls therefrom) and 
will, in some situations not complete that  processing (thus exiting 
handle) before it reappears in the same instance of EventHandler's 
handle method again. So this is true recursion.


I actually don't know if this is expected behavior or not. No one I've 
talked to expected it; the general understanding is the JavaFX 
Application Thread (processing) is specifically single-threaded and 
also that it will defintily complete one invocation of handle() before 
beginning another one.


I have to say that there is NO other Thread  in play here, at least no 
other Thread my applications create (what's going on QuantumToolKit may 
be a different story.)


The material upshot of this is it can lead to apparent  program 
incorrectness if the dev believes that it's not the case, and 100% of 
devs I've talked to think it's not possible. 


I am happy to post or attach the classes or modules as requested but 
first I wanted to check to see if in fact this is already known to be 
true and is in fact  expected behavior, in which case it's a non-issue 
and just a subtlety people are not aware of.


Thank you so much !