Bogus behavior of window listeners

Discussion in 'Java' started by Twisted, Nov 20, 2006.

  1. Twisted

    Twisted Guest

    I may have discovered another bug in the 1.6.0 release candidate
    library implementation.

    I mentioned earlier that my app's "are you sure?" on-exit dialog was
    suddenly popping up twice. I've since found it popping up only once, as
    it should, under a well-defined set of circumstances that prove the
    culprit to be one of two occurrences of:

    if (frame.getWindowListeners().length > 0)
    frame.removeWindowListener(frame.getWindowListeners()[0]);

    This used to work -- the window always has exactly the one window
    listener if it has any, and it's sometimes removed and replaced with a
    different one, and all of this activity is restricted to the event
    dispatch thread so there are no concurrency issues.

    Now we have a clear case of where this fails exactly once. The app adds
    an initial window listener, and at a later time when there's some
    cleanup to be done on exit it replaces that one with a different one.
    If the cleanup stops being needed, it replaces it again. Although the
    code in that replace is identical to the code in the first, I expect
    javac is probably dumb enough to create two different anonymous inner
    classes for these, so the third and the first aren't the same class as
    the JVM sees it.

    So listener 1 is added, then removed and 2 added, then 2 removed and 3
    added, 3 removed and 2 added, 2 removed and 3 added, and so forth. Or
    so it used to go. Now, one of them (perhaps listener 1) lingers
    forever.

    Either adding the first window listener doesn't cause
    frame.getWindowListeners().length > 0, or
    frame.removeWindowListener(frame.getWindowListeners()[0]) simply
    doesn't work properly. I'm guessing the former -- add listener 1 and
    the array remains empty; add listener 2 and it grows an element; remove
    it and add listener 3 works as it should; remove that and put 2 back
    works as it should; and so forth.

    Anyone else encountering this?
     
    Twisted, Nov 20, 2006
    #1
    1. Advertising

  2. Twisted wrote:
    > I may have discovered another bug in the 1.6.0 release candidate
    > library implementation.


    Bug ID?

    (snip stuff about listeners and exit dialogs)

    > Anyone else encountering this?


    Code?

    (And why are you posting a very GUI related question
    on c.l.j.programmer, rather than c.l.j.gui?)

    Andrew T.
     
    Andrew Thompson, Nov 20, 2006
    #2
    1. Advertising

  3. Twisted

    Twisted Guest

    Andrew Thompson wrote:
    > Twisted wrote:
    > > I may have discovered another bug in the 1.6.0 release candidate
    > > library implementation.

    >
    > Bug ID?


    ?

    > (snip stuff about listeners and exit dialogs)
    >
    > > Anyone else encountering this?

    >
    > Code?


    ?

    > (And why are you posting a very GUI related question
    > on c.l.j.programmer, rather than c.l.j.gui?)


    Because this is the c.l.j group I have bookmarked?
     
    Twisted, Nov 20, 2006
    #3
  4. Twisted wrote:
    >
    > I mentioned earlier that my app's "are you sure?" on-exit dialog was
    > suddenly popping up twice. I've since found it popping up only once, as
    > it should, under a well-defined set of circumstances that prove the
    > culprit to be one of two occurrences of:
    >
    > if (frame.getWindowListeners().length > 0)
    > frame.removeWindowListener(frame.getWindowListeners()[0]);


    You are assuming your listener is the only listener. That's not a good
    assumption to make.

    > Now we have a clear case of where this fails exactly once. The app adds
    > an initial window listener, and at a later time when there's some
    > cleanup to be done on exit it replaces that one with a different one.
    > If the cleanup stops being needed, it replaces it again. Although the
    > code in that replace is identical to the code in the first, I expect
    > javac is probably dumb enough to create two different anonymous inner
    > classes for these, so the third and the first aren't the same class as
    > the JVM sees it.


    Why not use a debugger or printf?

    Tom Hawtin
     
    Thomas Hawtin, Nov 20, 2006
    #4
  5. Twisted

    Twisted Guest

    Thomas Hawtin wrote:
    > Twisted wrote:
    > >
    > > I mentioned earlier that my app's "are you sure?" on-exit dialog was
    > > suddenly popping up twice. I've since found it popping up only once, as
    > > it should, under a well-defined set of circumstances that prove the
    > > culprit to be one of two occurrences of:
    > >
    > > if (frame.getWindowListeners().length > 0)
    > > frame.removeWindowListener(frame.getWindowListeners()[0]);

    >
    > You are assuming your listener is the only listener. That's not a good
    > assumption to make.


    In a part of the original posting that you conveniently snipped, I
    explicitly stated that it is the only listener. I create the frame and
    add just one. Later, under certain circumstances, code may remove it
    and add a different one; again after that point there is only one.
    There may be subsequent changes of the listener according to the same
    pattern.

    > Why not use a debugger or printf?


    Printf? In Java? :)

    Well, actually I may take some further steps to investigate this. I
    thought of putting a number in the title bar of the dialog box to
    identify which listener is responsible for it. Then I'll know exactly
    which one isn't being removed.
     
    Twisted, Nov 20, 2006
    #5
  6. Twisted wrote:
    > Thomas Hawtin wrote:

    ....
    >> Why not use a debugger or printf?

    >
    > Printf? In Java? :)


    "printf" is a method in java.io.PrintStream, the class for both
    System.err and System.out. It was added in 1.5.

    > Well, actually I may take some further steps to investigate this. I
    > thought of putting a number in the title bar of the dialog box to
    > identify which listener is responsible for it. Then I'll know exactly
    > which one isn't being removed.


    Are you sure? Which one will your code display if you think you have
    removed listener X, and have added listener Y?

    I would be more direct about it, and put in a test for an existing
    listener when one is about to be added.

    Patricia
     
    Patricia Shanahan, Nov 20, 2006
    #6
  7. Twisted wrote:
    >
    > In a part of the original posting that you conveniently snipped, I
    > explicitly stated that it is the only listener. I create the frame and


    It's the only listener you add. It's not necessarily the only listener.
    PL&F add listeners. Components add listeners to models. Lots of
    listeners are about that you never knew about.

    > Printf? In Java? :)


    Yeah, it's been in Java since 1.5 (I still use println myself).

    Tom Hawtin
     
    Thomas Hawtin, Nov 20, 2006
    #7
  8. Thomas Hawtin wrote:
    > Twisted wrote:
    >>
    >> In a part of the original posting that you conveniently snipped, I
    >> explicitly stated that it is the only listener. I create the frame and

    >
    > It's the only listener you add. It's not necessarily the only listener.
    > PL&F add listeners. Components add listeners to models. Lots of
    > listeners are about that you never knew about.


    However, presumably Twisted only cares about the explicitly created
    listeners. Presumably, they will belong to user program classes,
    including anonymous inner classes in the user program, not PL&F
    implementation classes.

    Patricia
     
    Patricia Shanahan, Nov 21, 2006
    #8
  9. Patricia Shanahan wrote:
    > Thomas Hawtin wrote:
    >> Twisted wrote:
    >>>
    >>> In a part of the original posting that you conveniently snipped, I
    >>> explicitly stated that it is the only listener. I create the frame and

    >>
    >> It's the only listener you add. It's not necessarily the only
    >> listener. PL&F add listeners. Components add listeners to models. Lots
    >> of listeners are about that you never knew about.

    >
    > However, presumably Twisted only cares about the explicitly created
    > listeners. Presumably, they will belong to user program classes,
    > including anonymous inner classes in the user program, not PL&F
    > implementation classes.


    I'm going to take that back. I just took another look at the base
    message of this thread:

    "if (frame.getWindowListeners().length > 0)
    frame.removeWindowListener(frame.getWindowListeners()[0]);"

    This code could be a really bad idea if there is ever a library
    implementation listener attached to frame. Suppose the first element of
    the array is a library listener, and the second is Twisted's. The
    library listener gets removed, and Twisted's listener stays, as another
    one is added.

    I've never tried to remove an arbitrary listener, only ones I added, so
    I have no practical experience of the effects of doing this.

    Patricia
     
    Patricia Shanahan, Nov 21, 2006
    #9
  10. Twisted

    Twisted Guest

    Thomas Hawtin wrote:
    > It's the only listener you add. It's not necessarily the only listener.
    > PL&F add listeners. Components add listeners to models. Lots of
    > listeners are about that you never knew about.


    It worked before, so it seems doubtful that this could be the
    explanation.
     
    Twisted, Nov 21, 2006
    #10
  11. Twisted wrote:
    > Thomas Hawtin wrote:
    >> It's the only listener you add. It's not necessarily the only listener.
    >> PL&F add listeners. Components add listeners to models. Lots of
    >> listeners are about that you never knew about.

    >
    > It worked before, so it seems doubtful that this could be the
    > explanation.
    >


    The explanation that Thomas' observation suggests would lead to bugs
    where any change in your program or the graphics libraries, even
    apparently harmless changes, could matter.

    You remove, in effect, an arbitrary Window listener, and then assume
    that your listener has been removed.

    The API documentation makes no statements about the order of listeners
    in the array returned by getWindowListener, so the order could change,
    for exactly the same combination of add and remove operations, from
    release to release of the software. If your listener happens to be
    referenced by element 0, all will be well. If not, you would get exactly
    the symptoms you describe, plus possibly additional symptoms. There may
    be consequences to the library failing to react to the condition the
    removed listener was dealing with.

    There is a really simple way to test for this issue. Change:

    if (frame.getWindowListeners().length > 0)
    frame.removeWindowListener(frame.getWindowListeners()[0]);

    to

    WindowListener[] listeners = frame.getWindowListeners();
    if (listeners.length > 0){
    if(listeners.length.length == 1){
    frame.removeWindowListener(listeners[0]);
    }else{
    *** write debug output or throw an exception
    }
    }

    Patricia
     
    Patricia Shanahan, Nov 21, 2006
    #11
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Karl Seguin

    firewalls "removing bogus header"

    Karl Seguin, Feb 10, 2004, in forum: ASP .Net
    Replies:
    4
    Views:
    1,427
    George Ter-Saakov
    Feb 10, 2004
  2. Doug

    I.E. Bogus Progress Meter?

    Doug, Aug 3, 2004, in forum: ASP .Net
    Replies:
    1
    Views:
    378
    Kevin Spencer
    Aug 3, 2004
  3. Replies:
    6
    Views:
    700
  4. Matt Kruse
    Replies:
    2
    Views:
    185
  5. William Wallace

    Event Listeners : window vs document

    William Wallace, Jul 20, 2010, in forum: Javascript
    Replies:
    6
    Views:
    244
    David Mark
    Jul 20, 2010
Loading...

Share This Page