Here’'s the code and exception. Is this me and my Java ignorance, or is it a bug?
If I skip the “removePacketListener” from the close() methed, if I rejoin a GroupChat, I get a NullPointerException in the packet listener, I’‘m assuming because my object is still actually hanging around due to connections’’ reference to it and I set all my stuff to null during the close.
public class GroupChatTab implements PacketListener {
public void start() {
...connect...logon...bla..bla...
conn.addPacketListener(this, new FromContainsFilter(room));
} public void processPacket(Packet packet) {
if (packet instanceof Message) {
chatText = chatText.concat("[" + ((Message) packet).getFrom() + "] " + ((Message) packet).getBody()+"\n");
...display updated text...
}
} public void close() {
if (groupChat != null) {
groupChat.leave();
groupChat = null;
}
conn.removePacketListener(this); // get an index out of bound error
}
}
I grabbed the source and set it up in Eclipse and found the problem was the the listener is inserted into the list as a ListenerWrapper but the remove routine is looking for a PacketListener.
I changed the method to this and all seems dandy now:
public void removePacketListener(PacketListener packetListener) {
synchronized (listeners) {
for (Iterator iter = listeners.iterator(); iter.hasNext(); ) {
ListenerWrapper element = (ListenerWrapper) iter.next();
if (element.packetListener.equals(packetListener)) {
iter.remove();
}
}
}
}
Thanks for the fix! I’‘ll get it into CVS. It’‘s somewhat pathetic that I didn’'t catch this particular bug before. I guess it really points to the need for a test suite…
Got your message about having separate threads for bugs so I’'m posting this here as a follow-up…
In build 4/7/03 the new removePacketListener code will bomb out with a NullPointerException when it hits a null entry for a listener that had been removed previously (if it leaves a sparse array situation).
Just for my own edification, is there a reason (compatability/performance/etc) for using index functions vs. the iterators?
Hmm, not that I know of. Using an Iterator probably wouldn’'t work in this particular situation though, since we need the index in order to set the value to nul.