How to start on debugging this Swing/AWT error?

G

Guest

I'm wondering about what techniques to use to debug an
error which is coming from somewhere in the guts of a
large piece of code I didn't write, with no indication
of where. I'm using JDK1.3.

The problem is that the error stack trace does not list
any part of the actual user code in the trace, which
puzzles me. Without this, I don't even know which of the
several dozen classes that may be generating it to
look at.

I've appended the error below. I don't need to know what
it mean, I basically know that. I need to know how I
could approach finding where in the code it is coming from.
In other cases I've worked in the stack trace always gave
be at least some clue.

Thanks,

--arne

DISCLAIMER: These opinions and statements are those of the author and
do not represent any views or positions of the Hewlett-Packard Co.

Exception occurred during event dispatching:
java.lang.ArrayIndexOutOfBoundsException: No such child: 3
at java.awt.Container.getComponent(Container.java:170)
at javax.swing.JComponent.rectangleIsObscured(JComponent.java:3615)
at javax.swing.JComponent.paint(JComponent.java:737)
at javax.swing.JLayeredPane.paint(JLayeredPane.java:546)
at javax.swing.JComponent.paintWithBuffer(JComponent.java:4393)
at javax.swing.JComponent._paintImmediately(JComponent.java:4336)
at javax.swing.JComponent.paintImmediately(JComponent.java:4187)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:370)
at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(SystemEventQueueUtilities.java:205)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:154)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:317)
at java.awt.EventDispatchThread.pumpOneEvent(EventDispatchThread.java:103)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:84)
 
D

David Zimmerman

I'm wondering about what techniques to use to debug an
error which is coming from somewhere in the guts of a
large piece of code I didn't write, with no indication
of where. I'm using JDK1.3.

The problem is that the error stack trace does not list
any part of the actual user code in the trace, which
puzzles me. Without this, I don't even know which of the
several dozen classes that may be generating it to
look at.

I would look for code that updates the GUI from outside of the Event Thread.
This looks like a component get removed in the middle of a paint.
 
T

Thomas Weidenfeller

The problem is that the error stack trace does not list
any part of the actual user code in the trace, which
puzzles me.

Custom code was maybe not involved. The stack trace looks as if the EDT
picked up an event from the event queue and processed it. That event
might have come, for example, from from some basic user interaction
like resizing the window, or placing another application in front of
the window. Native code might have placed the event on the event
queue.
Without this, I don't even know which of the
several dozen classes that may be generating it to
look at.

Before anything else, I would check the bugparade. Maybe it is a known
bug. If this draws a blank, my first assumtion would be a threading
problem. Data in the UI became inconsistent. Some part of the GUI
thinks there is still a component at index 3 in a container, but for
the Container it is not there any more.

I would try to verify the assumption by doing something like:

Set a breakpoint inside Container.getComponent(). In the source code I
have, the ArrayIndexOutOfBoundsException is throw explicitly, and
doesn't happen by accident when accessing an array. Once the breakpoint
triggers, you know which container is in question. With that knowledge
you can check your code for someone manipulating the container from
outside the EDT.

I would also check all containers if they have three or four components
only. These would be potential candidates for some more in depth
inspection. This is based on the assumption that the number of
components in the problematic container doesn't vary to much (that no
one tries to remove a bunch of components from it at once).

And of course if you know that some part of the code messes with
dynamically changing containers, give it a good inspection, too.

And all this might be going in the completely wrong direction. That's
debugging ...

/Thomas
 
T

Thomas G. Marshall

Thomas Weidenfeller <[email protected]> coughed up the following:

....[there once was a man from nanSNIPpet]...

....[john jacob jingleheimer snip]...
And all this might be going in the completely wrong direction. That's
debugging ...


The very first thing that I try when I get stuff like this is to binary
search for the component in question. Sometimes that's not possible but
it's usually fairly easy:

Hack out half of the components with comments. If the problem is still
there, then hack out half of the remaining. Otherwise switch halves and
check again. You get the idea.

It seems WAYYYY to simplistic, but I've found even swing thread-unsafe code
this way too. It actually works.

Thomas
 
G

Guest

Thomas G. Marshall said:
Thomas Weidenfeller <[email protected]> coughed up the following:
...[there once was a man from nanSNIPpet]...
...[john jacob jingleheimer snip]...
And all this might be going in the completely wrong direction. That's
debugging ...

The very first thing that I try when I get stuff like this is to binary
search for the component in question. Sometimes that's not possible but
it's usually fairly easy:
Hack out half of the components with comments. If the problem is still
there, then hack out half of the remaining. Otherwise switch halves and
check again. You get the idea.
It seems WAYYYY to simplistic, but I've found even swing thread-unsafe code
this way too. It actually works.

Thanks to all. I followed a procedure much like you describe and isolated
the bug.

Basically there is a JDesktopPane that contains 4 JInternalFrames. The
frames can be iconized. If any of the JInternalFrames attempts to deiconize
any of the JInternalFrames this exception occurs. It does not occur
if the deiconization occurs as a result of a user action, or as a result
of an action that starts at the JDesktopPane or higher. That's as far
as I've got. Interestingly the deiconization actually succeeds, except
that the icon remains as a ghost image on the JDesktopPane (which I should
have noticed sooner...).

I'm trying to find out if this is a bug in JDK1.3 or in the code itself.
Someone mentioned "bugparade", a pointer would be appreciated. Right
now I'm checking on the internet in general to see what I can find.

--arne

DISCLAIMER: These opinions and statements are those of the author and
do not represent any views or positions of the Hewlett-Packard Co.
 
G

Guest

I'm trying to find out if this is a bug in JDK1.3 or in the code itself.
Someone mentioned "bugparade", a pointer would be appreciated. Right
now I'm checking on the internet in general to see what I can find.

I got "bugparade" figured out. I'm still looking tho'
 
G

Guest

(e-mail address removed) wrote:
I got "bugparade" figured out. I'm still looking tho'

Looks like a flavor of "Swing is not threadsafe". Sound right to
anyone? In the meantime I think I'll modify the code to deiconize the
windows up in response to an action, instead of directly.

--arne

DISCLAIMER: These opinions and statements are those of the author and
do not represent any views or positions of the Hewlett-Packard Co.
 
G

Guest

Looks like a flavor of "Swing is not threadsafe". Sound right to
anyone? In the meantime I think I'll modify the code to deiconize the
windows up in response to an action, instead of directly.

Guess I'm mostly talking to myself here, but the fix was (apparently)
simple, and was because of the thread issue.

One example of a change is:

//Old code
/**************************
try {
setIcon(false);
toFront();
try {
setSelected(true);
} catch(Exception e) {
e.printStackTrace();
}
}
catch(Exception e) {
e.printStackTrace();
}
***************************/

//New code
Runnable raiseMe = new Runnable(){
public void run(){
try {
setIcon(false);
toFront();
try {
setSelected(true);
} catch(Exception e) {
e.printStackTrace();
}
} catch(Exception e) {
e.printStackTrace();
}
}
};
SwingUtilities.invokeLater(raiseMe);

Now the funny thing is that there appears to be non-thread-safe
stuff like this all over the code, but it mostly works. Guess
it's a matter of luck. Looks like I have a lot of inspecting
to do...

Is anyone aware of any drawbacks to what I did here?

--arne

DISCLAIMER: These opinions and statements are those of the author and
do not represent any views or positions of the Hewlett-Packard Co.
 
T

Thomas G. Marshall

Looks like a flavor of "Swing is not threadsafe". Sound right to
anyone? In the meantime I think I'll modify the code to deiconize the
windows up in response to an action, instead of directly.

Most every swing component needs to be mutated in the awt event dispatching
thread. Note that if your code is /already/ within that thread as a result
of a callback to a listener, then you can access the component directly.


http://java.sun.com/j2se/1.4.2/docs...tilities.html#invokeLater(java.lang.Runnable)

Note that if your problem is not infintely repeatable, it might not be the
issue.
 
T

Thomas G. Marshall

Guess I'm mostly talking to myself here, but the fix was (apparently)
simple, and was because of the thread issue.

One example of a change is:

//Old code
/**************************
try {
setIcon(false);
toFront();
try {
setSelected(true);
} catch(Exception e) {
e.printStackTrace();
}
}
catch(Exception e) {
e.printStackTrace();
}
***************************/

//New code
Runnable raiseMe = new Runnable(){
public void run(){
try {
setIcon(false);
toFront();
try {
setSelected(true);
} catch(Exception e) {
e.printStackTrace();
}
} catch(Exception e) {
e.printStackTrace();
}
}
};
SwingUtilities.invokeLater(raiseMe);

This is the top issue of most of the code I've ever been called in to fix.

Now the funny thing is that there appears to be non-thread-safe
stuff like this all over the code, but it mostly works. Guess
it's a matter of luck. Looks like I have a lot of inspecting
to do...

Stuff that "mostly works" but not reliably are one of the hallmark of
threading problems.

Threading problem code falls into 4 categories:

1. always seems to work (though fraught with peril later)
2. some parts of the code work, and others don't
3. some parts of the code /sometimes/ don't work, but unrepeatably
4. the software explodes into bit splatters on the wall
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,218
Latest member
JolieDenha

Latest Threads

Top