any recommendations?

  • Thread starter Brandon McCombs
  • Start date
B

Brandon McCombs

Hello,

Somewhere in my code I have a bug that I can't reliably reproduce. It
occurs randomly when I'm deleting entries from a JList (I retrieve
certain pieces of info from the entry before deleting it, then I delete
it and the JList contents are then refreshed so remaining items are
re-added to the JList). The only output I get when the exception occurs
is the following:

Exception in thread "AWT-EventQueue-0"
java.lang.ArrayIndexOutOfBoundsException: 1 >= 0
at java.util.Vector.elementAt(Unknown Source)
at javax.swing.DefaultListModel.getElementAt(Unknown Source)
at javax.swing.plaf.basic.BasicListUI.paintCell(Unknown Source)
at javax.swing.plaf.basic.BasicListUI.paint(Unknown Source)
at javax.swing.plaf.ComponentUI.update(Unknown Source)
at javax.swing.JComponent.paintComponent(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JComponent.paintWithOffscreenBuffer(Unknown Source)
at javax.swing.JComponent.paintDoubleBuffered(Unknown Source)
at javax.swing.JComponent._paintImmediately(Unknown Source)
at javax.swing.JComponent.paintImmediately(Unknown Source)
at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
at
javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(Unknown
Source)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)


The "1" as the index value differs between exception printouts. I don't
know where that index value is originating from or what Vector is really
having its elements retrieved. The index value doesn't correspond to
the index of the Object that I'm selecting for deletion. I've placed
try/catches throughout the places where I thought was causing the
exception to print out a stacktrace that I hoped would include a line
number but I'm not getting any extra output. I also would put in a print
statement so I knew which try/catch was being executed but I don't see
that outputted either.

When the JList is refreshed it is done so through a thread. I've tried
to use run() to make the thread do its work but not in a thread and I
don't get the exception but since I can't reproduce it reliably I don't
know if it's really a threading problem or not. Using Eclipse's
debugger also doesn't help so far because I can't get the error to occur
during the debugging, at least not yet.

Is there anything else I can try that can give me more information as to
what line in my code this is occurring on so I can begin to fix it?

thanks
 
K

Knute Johnson

Brandon said:
Hello,

Somewhere in my code I have a bug that I can't reliably reproduce. It
occurs randomly when I'm deleting entries from a JList (I retrieve
certain pieces of info from the entry before deleting it, then I delete
it and the JList contents are then refreshed so remaining items are
re-added to the JList). The only output I get when the exception occurs
is the following:

Exception in thread "AWT-EventQueue-0"
java.lang.ArrayIndexOutOfBoundsException: 1 >= 0
at java.util.Vector.elementAt(Unknown Source)
at javax.swing.DefaultListModel.getElementAt(Unknown Source)
at javax.swing.plaf.basic.BasicListUI.paintCell(Unknown Source)
at javax.swing.plaf.basic.BasicListUI.paint(Unknown Source)
at javax.swing.plaf.ComponentUI.update(Unknown Source)
at javax.swing.JComponent.paintComponent(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JComponent.paintWithOffscreenBuffer(Unknown Source)
at javax.swing.JComponent.paintDoubleBuffered(Unknown Source)
at javax.swing.JComponent._paintImmediately(Unknown Source)
at javax.swing.JComponent.paintImmediately(Unknown Source)
at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
at
javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(Unknown
Source)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(Unknown
Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)


The "1" as the index value differs between exception printouts. I don't
know where that index value is originating from or what Vector is really
having its elements retrieved. The index value doesn't correspond to
the index of the Object that I'm selecting for deletion. I've placed
try/catches throughout the places where I thought was causing the
exception to print out a stacktrace that I hoped would include a line
number but I'm not getting any extra output. I also would put in a print
statement so I knew which try/catch was being executed but I don't see
that outputted either.

When the JList is refreshed it is done so through a thread. I've tried
to use run() to make the thread do its work but not in a thread and I
don't get the exception but since I can't reproduce it reliably I don't
know if it's really a threading problem or not. Using Eclipse's
debugger also doesn't help so far because I can't get the error to occur
during the debugging, at least not yet.

Is there anything else I can try that can give me more information as to
what line in my code this is occurring on so I can begin to fix it?

thanks

Are you modifying the JList on the EDT? Are you modifying the Vector
after creating your JList? Can you make a simple test program that
demonstrates the problem?
 
B

Brandon McCombs

Knute said:
Brandon said:
Hello,

Somewhere in my code I have a bug that I can't reliably reproduce. It
occurs randomly when I'm deleting entries from a JList (I retrieve
certain pieces of info from the entry before deleting it, then I
delete it and the JList contents are then refreshed so remaining items
are re-added to the JList). The only output I get when the exception
occurs is the following:

Exception in thread "AWT-EventQueue-0"
java.lang.ArrayIndexOutOfBoundsException: 1 >= 0
at java.util.Vector.elementAt(Unknown Source)
at javax.swing.DefaultListModel.getElementAt(Unknown Source)
at javax.swing.plaf.basic.BasicListUI.paintCell(Unknown Source)
at javax.swing.plaf.basic.BasicListUI.paint(Unknown Source) [snip]


The "1" as the index value differs between exception printouts. I
don't know where that index value is originating from or what Vector
is really having its elements retrieved. The index value doesn't
correspond to the index of the Object that I'm selecting for deletion.
I've placed try/catches throughout the places where I thought was
causing the exception to print out a stacktrace that I hoped would
include a line number but I'm not getting any extra output. I also
would put in a print statement so I knew which try/catch was being
executed but I don't see that outputted either.

When the JList is refreshed it is done so through a thread. I've tried
to use run() to make the thread do its work but not in a thread and I
don't get the exception but since I can't reproduce it reliably I
don't know if it's really a threading problem or not. Using Eclipse's
debugger also doesn't help so far because I can't get the error to
occur during the debugging, at least not yet.

Is there anything else I can try that can give me more information as
to what line in my code this is occurring on so I can begin to fix it?

thanks

Are you modifying the JList on the EDT? Are you modifying the Vector
after creating your JList? Can you make a simple test program that
demonstrates the problem?

The code that the Thread class uses to tell the JList when to update is
this:

SwingUtilities.invokeLater(new Runnable() {
public void run() {
component.updateGUI(results);
component.resetGUI(results);
}
});

Component is the class that contains my GUI which is a JTree and JList
in a JSplitPane; component is passed into the Thread's constructor.

Results is a Vector that contains the results of a LDAP search which
will be put into the JList.

Yes I'm modifying the Vector. Since the JList can have entries
added/modified/removed the Vector will obviously be changed accordingly
(as I state in the original mesg). I can't make a simple test program
because I don't know where the problem is. If I did I wouldn't have
posted this because I'd be working on figuring out a way to fix it. The
problem could be in a lot of places and ripping out stuff to duplicate
the problem would be a waste of time I believe since I can't reproduce
it not to mention the code involved is spread across multiple classes.
To test it I'm having to create temporary entries in my LDAP server and
then delete them one by one to see if the error occurs. Sometimes I
delete 50 before it crops up, other times I delete 1 and the index value
mentioned in the exception never corresponds with the deleted entry.

I'm mainly asking if there is a way to glean more info from the
exception information. I can't believe it isn't giving me a line number
to review. Is the printout I originally posted the only stack trace
information available from the JVM? I've put whole method bodies in a
try/catch and I don't get any more information so either I won't get
more information or I'm putting try/catches in the wrong place. Can the
JVM be launched with options that will help?

Brandon
 
K

Knute Johnson

Brandon said:
Knute said:
Brandon said:
Hello,

Somewhere in my code I have a bug that I can't reliably reproduce. It
occurs randomly when I'm deleting entries from a JList (I retrieve
certain pieces of info from the entry before deleting it, then I
delete it and the JList contents are then refreshed so remaining
items are re-added to the JList). The only output I get when the
exception occurs is the following:

Exception in thread "AWT-EventQueue-0"
java.lang.ArrayIndexOutOfBoundsException: 1 >= 0
at java.util.Vector.elementAt(Unknown Source)
at javax.swing.DefaultListModel.getElementAt(Unknown Source)
at javax.swing.plaf.basic.BasicListUI.paintCell(Unknown Source)
at javax.swing.plaf.basic.BasicListUI.paint(Unknown Source) [snip]


The "1" as the index value differs between exception printouts. I
don't know where that index value is originating from or what Vector
is really having its elements retrieved. The index value doesn't
correspond to the index of the Object that I'm selecting for
deletion. I've placed try/catches throughout the places where I
thought was causing the exception to print out a stacktrace that I
hoped would include a line number but I'm not getting any extra
output. I also would put in a print statement so I knew which
try/catch was being executed but I don't see that outputted either.

When the JList is refreshed it is done so through a thread. I've
tried to use run() to make the thread do its work but not in a thread
and I don't get the exception but since I can't reproduce it reliably
I don't know if it's really a threading problem or not. Using
Eclipse's debugger also doesn't help so far because I can't get the
error to occur during the debugging, at least not yet.

Is there anything else I can try that can give me more information as
to what line in my code this is occurring on so I can begin to fix it?

thanks

Are you modifying the JList on the EDT? Are you modifying the Vector
after creating your JList? Can you make a simple test program that
demonstrates the problem?

The code that the Thread class uses to tell the JList when to update is
this:

SwingUtilities.invokeLater(new Runnable() {
public void run() {
component.updateGUI(results);
component.resetGUI(results);
}
});

Component is the class that contains my GUI which is a JTree and JList
in a JSplitPane; component is passed into the Thread's constructor.

Results is a Vector that contains the results of a LDAP search which
will be put into the JList.

Yes I'm modifying the Vector. Since the JList can have entries
added/modified/removed the Vector will obviously be changed accordingly
(as I state in the original mesg). I can't make a simple test program
because I don't know where the problem is. If I did I wouldn't have
posted this because I'd be working on figuring out a way to fix it. The
problem could be in a lot of places and ripping out stuff to duplicate
the problem would be a waste of time I believe since I can't reproduce
it not to mention the code involved is spread across multiple classes.
To test it I'm having to create temporary entries in my LDAP server and
then delete them one by one to see if the error occurs. Sometimes I
delete 50 before it crops up, other times I delete 1 and the index value
mentioned in the exception never corresponds with the deleted entry.

I'm mainly asking if there is a way to glean more info from the
exception information. I can't believe it isn't giving me a line number
to review. Is the printout I originally posted the only stack trace
information available from the JVM? I've put whole method bodies in a
try/catch and I don't get any more information so either I won't get
more information or I'm putting try/catches in the wrong place. Can the
JVM be launched with options that will help?

Brandon

Brandon:

I think you are attempting to access a non-existing element or you've
been modifying the Vector itself which is not good either. If you want
to add and remove elements from a JList you need to use a ListModel that
is read/write. So since you can't make a test program, shows us
snippets of the critical code where you create the JList and modify it.
 
B

Brandon McCombs

Knute said:
Brandon said:
Knute said:
Brandon McCombs wrote:
Hello,

Somewhere in my code I have a bug that I can't reliably reproduce.
It occurs randomly when I'm deleting entries from a JList (I
retrieve certain pieces of info from the entry before deleting it,
then I delete it and the JList contents are then refreshed so
remaining items are re-added to the JList). The only output I get
when the exception occurs is the following:

Exception in thread "AWT-EventQueue-0"
java.lang.ArrayIndexOutOfBoundsException: 1 >= 0
at java.util.Vector.elementAt(Unknown Source)
at javax.swing.DefaultListModel.getElementAt(Unknown Source)
at javax.swing.plaf.basic.BasicListUI.paintCell(Unknown Source)
at javax.swing.plaf.basic.BasicListUI.paint(Unknown Source) [snip]


The "1" as the index value differs between exception printouts. I
don't know where that index value is originating from or what Vector
is really having its elements retrieved. The index value doesn't
correspond to the index of the Object that I'm selecting for
deletion. I've placed try/catches throughout the places where I
thought was causing the exception to print out a stacktrace that I
hoped would include a line number but I'm not getting any extra
output. I also would put in a print statement so I knew which
try/catch was being executed but I don't see that outputted either.

When the JList is refreshed it is done so through a thread. I've
tried to use run() to make the thread do its work but not in a
thread and I don't get the exception but since I can't reproduce it
reliably I don't know if it's really a threading problem or not.
Using Eclipse's debugger also doesn't help so far because I can't
get the error to occur during the debugging, at least not yet.

Is there anything else I can try that can give me more information
as to what line in my code this is occurring on so I can begin to
fix it?

thanks

Are you modifying the JList on the EDT? Are you modifying the Vector
after creating your JList? Can you make a simple test program that
demonstrates the problem?

The code that the Thread class uses to tell the JList when to update
is this:

SwingUtilities.invokeLater(new Runnable() {
public void run() {
component.updateGUI(results);
component.resetGUI(results);
}
});

Component is the class that contains my GUI which is a JTree and JList
in a JSplitPane; component is passed into the Thread's constructor.

Results is a Vector that contains the results of a LDAP search which
will be put into the JList.

Yes I'm modifying the Vector. Since the JList can have entries
added/modified/removed the Vector will obviously be changed
accordingly (as I state in the original mesg). I can't make a simple
test program because I don't know where the problem is. If I did I
wouldn't have posted this because I'd be working on figuring out a way
to fix it. The problem could be in a lot of places and ripping out
stuff to duplicate the problem would be a waste of time I believe
since I can't reproduce it not to mention the code involved is spread
across multiple classes. To test it I'm having to create temporary
entries in my LDAP server and then delete them one by one to see if
the error occurs. Sometimes I delete 50 before it crops up, other
times I delete 1 and the index value mentioned in the exception never
corresponds with the deleted entry.

I'm mainly asking if there is a way to glean more info from the
exception information. I can't believe it isn't giving me a line
number to review. Is the printout I originally posted the only stack
trace information available from the JVM? I've put whole method bodies
in a try/catch and I don't get any more information so either I won't
get more information or I'm putting try/catches in the wrong place.
Can the JVM be launched with options that will help?

Brandon

Brandon:

I think you are attempting to access a non-existing element or you've
been modifying the Vector itself which is not good either. If you want
to add and remove elements from a JList you need to use a ListModel that
is read/write. So since you can't make a test program, shows us
snippets of the critical code where you create the JList and modify it.

Well the deletion still works when I get the exception. I am doing the
deletion by going through the ListModel for the JList which I thought
was correct. I never knew you could create a read-only ListModel.

I use the following as the constructor to my BrowserModel class which
contains 2 models for my Browser (JTree and JList I mentioned before):

public BrowserModel(Node root) {
this.root = (Node)root.getChildAt(0);
tree = new DefaultTreeModel(root);
list = new DefaultListModel();
}

The method I call for deleting a selected item from the JList is the
following (model is the instance of BrowserModel):

private void list_deleteObj() {
int idx = dirList.getSelectedIndex();
String dn = LDAPMgr.ldapUtility.getDN(
model.getListModel().getElementAt(idx) );
int ans = JOptionPane.showConfirmDialog(this,
"Confirm delete for:\n" + dn + "\n",
"Delete Object", JOptionPane.YES_NO_OPTION,
JOptionPane.PLAIN_MESSAGE);
if (ans == 1)
return;
String msg = null;
msg = LDAPMgr.ldapUtility.deleteEntry(
model.getListModel().getElementAt(idx));
/* if successful */
if (msg == null) {
model.getListModel().remove(idx);
/* reload the subtree and list to show deletion */
refresh();
}
}

The idx in the code above rarely matches (if ever) the index value
listed in the generated exception and again, the deletion above still
works when the exception is generated. Refresh() essentially determines
which node in the JTree needs refreshing and then calls expand(node,
node.getDN()). Expand() removes all the node's current children and
spawns the thread to retrieve the current children. The items in the
JList are the children of the selected Node in the JTree.

The thread is spawned with this:

selectedNode = node;
searchBase = dn;
if (asyncSearch != null)
asyncSearch.stopSearch(); //allow 1 search at a time
asyncSearch = new AsyncSearch(this);
asyncSearch.setSearchBase(searchBase);
asyncSearch.setFilter("(objectClass=*)");
asyncSearch.setReturnedAttributes("*");
asyncSearch.setScope(1);
asyncSearch.start();

That calls a method that executes a LDAP search and passes the results
back to the Browser class by calling updateGUI() from the Browser.
Within updateGUI() the Browser populates the selected node's children in
the JTree as well as the JList (which is just another view of the node's
children). If I do this whole process enough times I get the
aforementioned exception.

I hope that description is helpful and understandable.
If you can figure this one out I'd appreciate it because I don't even
know where to look since nothing is making sense (index values not
matching up, deletion still works).


thanks for the help
 
K

Knute Johnson

Brandon said:
Knute said:
Brandon said:
Knute Johnson wrote:
Brandon McCombs wrote:
Hello,

Somewhere in my code I have a bug that I can't reliably reproduce.
It occurs randomly when I'm deleting entries from a JList (I
retrieve certain pieces of info from the entry before deleting it,
then I delete it and the JList contents are then refreshed so
remaining items are re-added to the JList). The only output I get
when the exception occurs is the following:

Exception in thread "AWT-EventQueue-0"
java.lang.ArrayIndexOutOfBoundsException: 1 >= 0
at java.util.Vector.elementAt(Unknown Source)
at javax.swing.DefaultListModel.getElementAt(Unknown Source)
at javax.swing.plaf.basic.BasicListUI.paintCell(Unknown Source)
at javax.swing.plaf.basic.BasicListUI.paint(Unknown Source)
[snip]


The "1" as the index value differs between exception printouts. I
don't know where that index value is originating from or what
Vector is really having its elements retrieved. The index value
doesn't correspond to the index of the Object that I'm selecting
for deletion. I've placed try/catches throughout the places where I
thought was causing the exception to print out a stacktrace that I
hoped would include a line number but I'm not getting any extra
output. I also would put in a print statement so I knew which
try/catch was being executed but I don't see that outputted either.

When the JList is refreshed it is done so through a thread. I've
tried to use run() to make the thread do its work but not in a
thread and I don't get the exception but since I can't reproduce it
reliably I don't know if it's really a threading problem or not.
Using Eclipse's debugger also doesn't help so far because I can't
get the error to occur during the debugging, at least not yet.

Is there anything else I can try that can give me more information
as to what line in my code this is occurring on so I can begin to
fix it?

thanks

Are you modifying the JList on the EDT? Are you modifying the
Vector after creating your JList? Can you make a simple test
program that demonstrates the problem?


The code that the Thread class uses to tell the JList when to update
is this:

SwingUtilities.invokeLater(new Runnable() {
public void run() {
component.updateGUI(results);
component.resetGUI(results);
}
});

Component is the class that contains my GUI which is a JTree and
JList in a JSplitPane; component is passed into the Thread's
constructor.

Results is a Vector that contains the results of a LDAP search which
will be put into the JList.

Yes I'm modifying the Vector. Since the JList can have entries
added/modified/removed the Vector will obviously be changed
accordingly (as I state in the original mesg). I can't make a simple
test program because I don't know where the problem is. If I did I
wouldn't have posted this because I'd be working on figuring out a
way to fix it. The problem could be in a lot of places and ripping
out stuff to duplicate the problem would be a waste of time I believe
since I can't reproduce it not to mention the code involved is spread
across multiple classes. To test it I'm having to create temporary
entries in my LDAP server and then delete them one by one to see if
the error occurs. Sometimes I delete 50 before it crops up, other
times I delete 1 and the index value mentioned in the exception never
corresponds with the deleted entry.

I'm mainly asking if there is a way to glean more info from the
exception information. I can't believe it isn't giving me a line
number to review. Is the printout I originally posted the only stack
trace information available from the JVM? I've put whole method
bodies in a try/catch and I don't get any more information so either
I won't get more information or I'm putting try/catches in the wrong
place. Can the JVM be launched with options that will help?

Brandon

Brandon:

I think you are attempting to access a non-existing element or you've
been modifying the Vector itself which is not good either. If you
want to add and remove elements from a JList you need to use a
ListModel that is read/write. So since you can't make a test program,
shows us snippets of the critical code where you create the JList and
modify it.

Well the deletion still works when I get the exception. I am doing the
deletion by going through the ListModel for the JList which I thought
was correct. I never knew you could create a read-only ListModel.

I use the following as the constructor to my BrowserModel class which
contains 2 models for my Browser (JTree and JList I mentioned before):

public BrowserModel(Node root) {
this.root = (Node)root.getChildAt(0);
tree = new DefaultTreeModel(root);
list = new DefaultListModel();
}

The method I call for deleting a selected item from the JList is the
following (model is the instance of BrowserModel):

private void list_deleteObj() {
int idx = dirList.getSelectedIndex();
String dn = LDAPMgr.ldapUtility.getDN(
model.getListModel().getElementAt(idx) );
int ans = JOptionPane.showConfirmDialog(this,
"Confirm delete for:\n" + dn + "\n",
"Delete Object",
JOptionPane.YES_NO_OPTION,
JOptionPane.PLAIN_MESSAGE);
if (ans == 1)
return;
String msg = null;
msg = LDAPMgr.ldapUtility.deleteEntry(
model.getListModel().getElementAt(idx));
/* if successful */
if (msg == null) {
model.getListModel().remove(idx);
/* reload the subtree and list to show deletion */
refresh();
}
}

The idx in the code above rarely matches (if ever) the index value
listed in the generated exception and again, the deletion above still
works when the exception is generated. Refresh() essentially determines
which node in the JTree needs refreshing and then calls expand(node,
node.getDN()). Expand() removes all the node's current children and
spawns the thread to retrieve the current children. The items in the
JList are the children of the selected Node in the JTree.

The thread is spawned with this:

selectedNode = node;
searchBase = dn;
if (asyncSearch != null)
asyncSearch.stopSearch(); //allow 1 search at a time
asyncSearch = new AsyncSearch(this);
asyncSearch.setSearchBase(searchBase);
asyncSearch.setFilter("(objectClass=*)");
asyncSearch.setReturnedAttributes("*");
asyncSearch.setScope(1);
asyncSearch.start();

That calls a method that executes a LDAP search and passes the results
back to the Browser class by calling updateGUI() from the Browser.
Within updateGUI() the Browser populates the selected node's children in
the JTree as well as the JList (which is just another view of the node's
children). If I do this whole process enough times I get the
aforementioned exception.

I hope that description is helpful and understandable.
If you can figure this one out I'd appreciate it because I don't even
know where to look since nothing is making sense (index values not
matching up, deletion still works).


thanks for the help

Brandon:

I don't see anything there, nothing looks out of the ordinary. Any
chance that you've got a concurrency problem? Or maybe you are setting
the size of the ListModel before trying to remove the element?

I think this is going to be hard to find without a simpler test program.
I had a problem like that once though that I couldn't duplicate. I
ended up solving it by synchronizing access to the method where I
thought the problem was occurring. That was kind of a shotgun approach.

Sorry I can't be more help.
 
M

Michael Rauscher

Brandon said:
Exception in thread "AWT-EventQueue-0"
java.lang.ArrayIndexOutOfBoundsException: 1 >= 0
at java.util.Vector.elementAt(Unknown Source)
at javax.swing.DefaultListModel.getElementAt(Unknown Source)
at javax.swing.plaf.basic.BasicListUI.paintCell(Unknown Source)
at javax.swing.plaf.basic.BasicListUI.paint(Unknown Source)
[snip]
Well the deletion still works when I get the exception. I am doing the
deletion by going through the ListModel for the JList which I thought
was correct. I never knew you could create a read-only ListModel.

NB: a ListModel *is* read-only by default.
The method I call for deleting a selected item from the JList is the
following (model is the instance of BrowserModel):

private void list_deleteObj() {

Is this method called from the EDT?
The idx in the code above rarely matches (if ever) the index value
listed in the generated exception and again, the deletion above still
works when the exception is generated. Refresh() essentially determines

Sure, the exception originates from the UI-Delegate's paint method. Why
would you expect the deletion not to work?

The reason for the exception is usually a simple one: you're modifying
the underlying ListModel in one thread while the EDT repaints the list.

Imagine the following pseudo code as part of the painting procedure:

int n = model.getSize();
for ( int i = 0; i < n; i++ ) {
// ...
Object value = model.getElementAt(i);
// ...
}

Let's consider a ListModel that contains 5 elements. The code above runs
on the EDT, so it starts with n = 5 and enters the loop. Now, in another
thread you delete one element from the ListModel so that
model.getSize()==4. The loop continues until i=4, then an
ArrayIndexOutOfBoundsException will be thrown, e.g.: 4 >= 4. If the
second thread would have removed all elements from the ListModel, the
exception is thrown immediately at the next model.getElementAt method
call, e. g. 2 >= 0.
The thread is spawned with this:
....
asyncSearch = new AsyncSearch(this); ....
asyncSearch.start();

Does AsynchSearch modify the ListModel? And if, how?

Bye
Michael
 
N

Nigel Wade

Brandon McCombs wrote:

The method I call for deleting a selected item from the JList is the
following (model is the instance of BrowserModel):

private void list_deleteObj() {
int idx = dirList.getSelectedIndex();
String dn = LDAPMgr.ldapUtility.getDN(
model.getListModel().getElementAt(idx) );
int ans = JOptionPane.showConfirmDialog(this,
"Confirm delete for:\n" + dn + "\n",
"Delete Object", JOptionPane.YES_NO_OPTION,
JOptionPane.PLAIN_MESSAGE);
if (ans == 1)
return;
String msg = null;
msg = LDAPMgr.ldapUtility.deleteEntry(
model.getListModel().getElementAt(idx));
/* if successful */
if (msg == null) {
model.getListModel().remove(idx);
/* reload the subtree and list to show deletion */
refresh();
}
}

What thread is the above method being executed on? If it's not the EDT you have
a problem there, you are modifying the JList in a thread other than the EDT.

The error is telling you that when the EDT came to draw a JList it tried to
access element 1 and that element didn't exist in the the DefaultListModel's
Vector at the time. That would imply a synchronization error, the Vector is in
the process of being modified whilst it's being drawn (the JList and
DefaultTreeModel have a different idea of how many elements there are), and I
don't see how that can happen unless it's being modified from another thread -
even the EDT can only do one thing at a time...
 
B

Brandon McCombs

Michael said:
Brandon said:
Exception in thread "AWT-EventQueue-0"
java.lang.ArrayIndexOutOfBoundsException: 1 >= 0
at java.util.Vector.elementAt(Unknown Source)
at javax.swing.DefaultListModel.getElementAt(Unknown Source)
at javax.swing.plaf.basic.BasicListUI.paintCell(Unknown Source)
at javax.swing.plaf.basic.BasicListUI.paint(Unknown Source)
[snip]
Well the deletion still works when I get the exception. I am doing the
deletion by going through the ListModel for the JList which I thought
was correct. I never knew you could create a read-only ListModel.

NB: a ListModel *is* read-only by default.
The method I call for deleting a selected item from the JList is the
following (model is the instance of BrowserModel):

private void list_deleteObj() {

Is this method called from the EDT?

currently it is not.
Sure, the exception originates from the UI-Delegate's paint method. Why
would you expect the deletion not to work?

I never said I didn't expect it to work. I was notifying you guys that
it still was in case you didn't know and needed to know.
The reason for the exception is usually a simple one: you're modifying
the underlying ListModel in one thread while the EDT repaints the list.

Imagine the following pseudo code as part of the painting procedure:

int n = model.getSize();
for ( int i = 0; i < n; i++ ) {
// ...
Object value = model.getElementAt(i);
// ...
}

Let's consider a ListModel that contains 5 elements. The code above runs
on the EDT, so it starts with n = 5 and enters the loop. Now, in another
thread you delete one element from the ListModel so that
model.getSize()==4. The loop continues until i=4, then an
ArrayIndexOutOfBoundsException will be thrown, e.g.: 4 >= 4. If the
second thread would have removed all elements from the ListModel, the
exception is thrown immediately at the next model.getElementAt method
call, e. g. 2 >= 0.

ok that makes sense.
Does AsynchSearch modify the ListModel? And if, how?

no. It calls updateGUI() from the component that spawned the thread.
Component is a constructor to that thread class and updateGUI() is an
interface method of an interface I created for that purpose of letting
the components (I got 3 of them) update themselves in their own ways.
Only one of them is involved with this problem though. I'll work on
making the delete method spawn from the EDT.

I don't suppose you guys know of a way I can test this to know for sure
it works?
 
B

Brandon McCombs

Knute said:
Brandon said:
Knute said:
Brandon McCombs wrote:
Knute Johnson wrote:
Brandon McCombs wrote:
Hello,

Somewhere in my code I have a bug that I can't reliably reproduce.
It occurs randomly when I'm deleting entries from a JList (I
retrieve certain pieces of info from the entry before deleting it,
then I delete it and the JList contents are then refreshed so
remaining items are re-added to the JList). The only output I get
when the exception occurs is the following:

Exception in thread "AWT-EventQueue-0"
java.lang.ArrayIndexOutOfBoundsException: 1 >= 0
at java.util.Vector.elementAt(Unknown Source)
at javax.swing.DefaultListModel.getElementAt(Unknown Source)
at javax.swing.plaf.basic.BasicListUI.paintCell(Unknown Source)
at javax.swing.plaf.basic.BasicListUI.paint(Unknown Source)
[snip]


The "1" as the index value differs between exception printouts. I
don't know where that index value is originating from or what
Vector is really having its elements retrieved. The index value
doesn't correspond to the index of the Object that I'm selecting
for deletion. I've placed try/catches throughout the places where
I thought was causing the exception to print out a stacktrace that
I hoped would include a line number but I'm not getting any extra
output. I also would put in a print statement so I knew which
try/catch was being executed but I don't see that outputted either.

When the JList is refreshed it is done so through a thread. I've
tried to use run() to make the thread do its work but not in a
thread and I don't get the exception but since I can't reproduce
it reliably I don't know if it's really a threading problem or
not. Using Eclipse's debugger also doesn't help so far because I
can't get the error to occur during the debugging, at least not yet.

Is there anything else I can try that can give me more information
as to what line in my code this is occurring on so I can begin to
fix it?

thanks

Are you modifying the JList on the EDT? Are you modifying the
Vector after creating your JList? Can you make a simple test
program that demonstrates the problem?


The code that the Thread class uses to tell the JList when to update
is this:

SwingUtilities.invokeLater(new Runnable() {
public void run() {
component.updateGUI(results);
component.resetGUI(results);
}
});

Component is the class that contains my GUI which is a JTree and
JList in a JSplitPane; component is passed into the Thread's
constructor.

Results is a Vector that contains the results of a LDAP search which
will be put into the JList.

Yes I'm modifying the Vector. Since the JList can have entries
added/modified/removed the Vector will obviously be changed
accordingly (as I state in the original mesg). I can't make a simple
test program because I don't know where the problem is. If I did I
wouldn't have posted this because I'd be working on figuring out a
way to fix it. The problem could be in a lot of places and ripping
out stuff to duplicate the problem would be a waste of time I
believe since I can't reproduce it not to mention the code involved
is spread across multiple classes. To test it I'm having to create
temporary entries in my LDAP server and then delete them one by one
to see if the error occurs. Sometimes I delete 50 before it crops
up, other times I delete 1 and the index value mentioned in the
exception never corresponds with the deleted entry.

I'm mainly asking if there is a way to glean more info from the
exception information. I can't believe it isn't giving me a line
number to review. Is the printout I originally posted the only stack
trace information available from the JVM? I've put whole method
bodies in a try/catch and I don't get any more information so either
I won't get more information or I'm putting try/catches in the wrong
place. Can the JVM be launched with options that will help?

Brandon

Brandon:

I think you are attempting to access a non-existing element or you've
been modifying the Vector itself which is not good either. If you
want to add and remove elements from a JList you need to use a
ListModel that is read/write. So since you can't make a test
program, shows us snippets of the critical code where you create the
JList and modify it.

Well the deletion still works when I get the exception. I am doing the
deletion by going through the ListModel for the JList which I thought
was correct. I never knew you could create a read-only ListModel.

I use the following as the constructor to my BrowserModel class which
contains 2 models for my Browser (JTree and JList I mentioned before):

public BrowserModel(Node root) {
this.root = (Node)root.getChildAt(0);
tree = new DefaultTreeModel(root);
list = new DefaultListModel();
}

The method I call for deleting a selected item from the JList is the
following (model is the instance of BrowserModel):

private void list_deleteObj() {
int idx = dirList.getSelectedIndex();
String dn = LDAPMgr.ldapUtility.getDN(
model.getListModel().getElementAt(idx) );
int ans = JOptionPane.showConfirmDialog(this,
"Confirm delete for:\n" + dn + "\n",
"Delete Object",
JOptionPane.YES_NO_OPTION,
JOptionPane.PLAIN_MESSAGE);
if (ans == 1)
return;
String msg = null;
msg = LDAPMgr.ldapUtility.deleteEntry(
model.getListModel().getElementAt(idx));
/* if successful */
if (msg == null) {
model.getListModel().remove(idx);
/* reload the subtree and list to show deletion */
refresh();
}
}

The idx in the code above rarely matches (if ever) the index value
listed in the generated exception and again, the deletion above still
works when the exception is generated. Refresh() essentially
determines which node in the JTree needs refreshing and then calls
expand(node, node.getDN()). Expand() removes all the node's current
children and spawns the thread to retrieve the current children. The
items in the JList are the children of the selected Node in the JTree.

The thread is spawned with this:

selectedNode = node;
searchBase = dn;
if (asyncSearch != null)
asyncSearch.stopSearch(); //allow 1 search at a time
asyncSearch = new AsyncSearch(this);
asyncSearch.setSearchBase(searchBase);
asyncSearch.setFilter("(objectClass=*)");
asyncSearch.setReturnedAttributes("*");
asyncSearch.setScope(1);
asyncSearch.start();
That calls a method that executes a LDAP search and passes the
results back to the Browser class by calling updateGUI() from the
Browser. Within updateGUI() the Browser populates the selected node's
children in the JTree as well as the JList (which is just another view
of the node's children). If I do this whole process enough times I get
the aforementioned exception.

I hope that description is helpful and understandable.
If you can figure this one out I'd appreciate it because I don't even
know where to look since nothing is making sense (index values not
matching up, deletion still works).


thanks for the help

Brandon:

I don't see anything there, nothing looks out of the ordinary. Any
chance that you've got a concurrency problem? Or maybe you are setting
the size of the ListModel before trying to remove the element?

It's possible b/c like I said, I can't get it to work in Eclipse's
debugger and maybe the breakpoints I sort of straightening everything
out while being debugged. Well I don't specifically set it. To remove
the current items before I retrieve the most current children for the
selected tree node I call model.getListModel().removeAllElements(). Then
the search is executed and the newest data is put back into the list one
by one by looping through the Vector of results returned from the search.
I think this is going to be hard to find without a simpler test program.
I had a problem like that once though that I couldn't duplicate. I
ended up solving it by synchronizing access to the method where I
thought the problem was occurring. That was kind of a shotgun approach.

I've been setting synchronized keyword on some methods. I'll need to
keep doing that in case it helps but without a sure fire way of testing
this I may never really know if it's fixed.
 
C

Chris Uppal

Brandon said:
Is there anything else I can try that can give me more information as to
what line in my code this is occurring on so I can begin to fix it?

People downthread are already speculating that the problem is caused by
modifying the model from outside the EDT; I suspect that they are correct.

I just wanted to add (for general info) that the version of rt.jar which comes
with the JRE is (at least in 1.5 and 1.6 on my machine) compiled without line
numbers -- whence the less informative stack trace. The equivalent rt.jar
which is part of the JRE which is inside the JDK /does/ have that information
(again, as far as I can tell from what's on my machine). So if you can use
that JRE to execute your program, instead of the "standard" one, then you may
get more information.

-- chris
 
B

Brandon McCombs

Chris said:
People downthread are already speculating that the problem is caused by
modifying the model from outside the EDT; I suspect that they are correct.

I just wanted to add (for general info) that the version of rt.jar which comes
with the JRE is (at least in 1.5 and 1.6 on my machine) compiled without line
numbers -- whence the less informative stack trace. The equivalent rt.jar
which is part of the JRE which is inside the JDK /does/ have that information
(again, as far as I can tell from what's on my machine). So if you can use
that JRE to execute your program, instead of the "standard" one, then you may
get more information.

-- chris

Well I've gotten line numbers printed before but for some reason in this
case (when I really need it) the line number doesn't get printed. I've
been using the JRE included with Eclipse 3.1.2 but I just tried using
JDK 1.5 and it didn't help make line numbers visible (running it outside
of Eclipse as a regular JAR).
 
B

Brandon McCombs

Nigel said:
Brandon McCombs wrote:



What thread is the above method being executed on? If it's not the EDT you have
a problem there, you are modifying the JList in a thread other than the EDT.

The error is telling you that when the EDT came to draw a JList it tried to
access element 1 and that element didn't exist in the the DefaultListModel's
Vector at the time. That would imply a synchronization error, the Vector is in
the process of being modified whilst it's being drawn (the JList and
DefaultTreeModel have a different idea of how many elements there are), and I
don't see how that can happen unless it's being modified from another thread -
even the EDT can only do one thing at a time...

Maybe I did this wrong but in the place in my code where I call the
method above I put the following:

SwingUtilities.invokeLater(new Runnable() {
public void run() {
list_deleteObj(); }
});

And I still get the exception generated so what am I missing?
 
B

Brandon McCombs

Michael said:
Brandon said:
Exception in thread "AWT-EventQueue-0"
java.lang.ArrayIndexOutOfBoundsException: 1 >= 0
at java.util.Vector.elementAt(Unknown Source)
at javax.swing.DefaultListModel.getElementAt(Unknown Source)
at javax.swing.plaf.basic.BasicListUI.paintCell(Unknown Source)
at javax.swing.plaf.basic.BasicListUI.paint(Unknown Source)
[snip]
Well the deletion still works when I get the exception. I am doing the
deletion by going through the ListModel for the JList which I thought
was correct. I never knew you could create a read-only ListModel.

NB: a ListModel *is* read-only by default.
The method I call for deleting a selected item from the JList is the
following (model is the instance of BrowserModel):

private void list_deleteObj() {

Is this method called from the EDT?
The idx in the code above rarely matches (if ever) the index value
listed in the generated exception and again, the deletion above still
works when the exception is generated. Refresh() essentially determines

Sure, the exception originates from the UI-Delegate's paint method. Why
would you expect the deletion not to work?

The reason for the exception is usually a simple one: you're modifying
the underlying ListModel in one thread while the EDT repaints the list.

Imagine the following pseudo code as part of the painting procedure:

int n = model.getSize();
for ( int i = 0; i < n; i++ ) {
// ...
Object value = model.getElementAt(i);
// ...
}

Let's consider a ListModel that contains 5 elements. The code above runs
on the EDT, so it starts with n = 5 and enters the loop. Now, in another
thread you delete one element from the ListModel so that
model.getSize()==4. The loop continues until i=4, then an
ArrayIndexOutOfBoundsException will be thrown, e.g.: 4 >= 4. If the
second thread would have removed all elements from the ListModel, the
exception is thrown immediately at the next model.getElementAt method
call, e. g. 2 >= 0.


Although what you say makes sense, I wonder if it's my problem because
I'm modifying the model outside of the EDT (whatever that situation is
properly termed) and after a few other method calls is when the model is
updated with new nodes. I don't know when the exception actually occurs
(painting when the item is deleted or painting when i refresh the list
to get the current contents from the server) so maybe your theory is
still accurate.

private void list_deleteObj() {
int idx = dirList.getSelectedIndex();
String dn = LDAPMgr.ldapUtility.getDN(
model.getListModel().getElementAt(idx) );
int ans = JOptionPane.showConfirmDialog(this,
"Confirm delete for:\n" + dn + "\n",
"Delete Object",
JOptionPane.YES_NO_OPTION,
JOptionPane.PLAIN_MESSAGE);
if (ans == 1)
return;
String msg = null;
msg = LDAPMgr.ldapUtility.deleteEntry(
model.getListModel().getElementAt(idx));
/* if successful */
if (msg == null) {
model.getListModel().remove(idx);
/* reload the subtree and list to show deletion */
refresh();
}
}

As you can see the removal from the list occurs before refresh(). In
refresh() I call expand(). In expand() I spawn the thread to refresh the
list model. If the repaint from the model.getListModel().remove(idx);
doesn't occur until my thread is spawned then maybe that creates the
exception. In another posting a few minutes before this one I tell
Nigel that I put the call to the method above on the EDT and it didn't
help; after enough deletions the exception crops up again.
 
M

Michael Rauscher

Brandon said:
Although what you say makes sense, I wonder if it's my problem because
I'm modifying the model outside of the EDT (whatever that situation is
properly termed) and after a few other method calls is when the model is
updated with new nodes.

If you modfy the model outside of the EDT, then it's the problem. It's
easy. Really. Don't modify UI-state outside of the EDT and you don't get
strange Exceptions :)

I'll explain it in more detail, e. g. have a look at
model.getListModel().remove(idx);
/* reload the subtree and list to show deletion */
refresh();

Since you're using DefaultListModel, the element at index idx gets
removed from DefaultListModel's data Vector. Then, the model's listeners
(to which the JList belongs, too) get notified. The JList repaints itself.

You call refresh afterwards. I expect, you set a new Vector on the
DefaultListModel. I expect that this occurs outside of the EDT, too.


Now, I can imagine two situations:
1) remove was called while repaint was active
2) refresh() modified the ListModel while repaint was active.
E. g. refresh could call DefaultListModel#removeAll.
As you can see the removal from the list occurs before refresh().

Doesn't matter. The point is, that you modify UI-state outside of the
EDT. There are only a few methods in Swing (e. g. repaint()) that may be
used outside the EDT.

Bye
Michael
 
M

Michael Rauscher

Brandon said:
Maybe I did this wrong but in the place in my code where I call the
method above I put the following:

SwingUtilities.invokeLater(new Runnable() {
public void run() {
list_deleteObj(); }
});

And I still get the exception generated so what am I missing?

Look out for other threads. What does e. g. AsynchSearch do?

Bye
Michael
 
B

Brandon McCombs

Michael said:
Look out for other threads. What does e. g. AsynchSearch do?

It retrieves the current state of what the list should contain by
contacting an LDAP server. It then alerts the GUI the results are ready
by calling the GUI's updateGUI() method by I do that on the EDT like
above so it should be okay.

What I ended up doing that seems to work so far is I put the body of the
method prepareGUI() inside of the SwingUtilities.invokeLater() call.
The prepareGUI() is called by asyncSearch to prepare the GUI before the
newest results are loaded. prepareGUI() is actually what deletes the
rest of the items in the listmodel so that I don't get duplicate entries
when it is updated. I've been testing that and haven't received the
exception, yet.
 
M

Michael Rauscher

Brandon said:
It retrieves the current state of what the list should contain by
contacting an LDAP server. It then alerts the GUI the results are ready
by calling the GUI's updateGUI() method by I do that on the EDT like
above so it should be okay.

What I ended up doing that seems to work so far is I put the body of the
method prepareGUI() inside of the SwingUtilities.invokeLater() call.
The prepareGUI() is called by asyncSearch to prepare the GUI before the
newest results are loaded. prepareGUI() is actually what deletes the
rest of the items in the listmodel so that I don't get duplicate entries
when it is updated. I've been testing that and haven't received the
exception, yet.

Sounds good. Next time don't follow the trial and error method: just
ensure that any code that modifies the GUI runs on the EDT.

Bye
Michael
 

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

Forum statistics

Threads
473,982
Messages
2,570,186
Members
46,743
Latest member
WoodrowMea

Latest Threads

Top