NPE calls getLength () on NodeList
I am using the org.w3c.dom.Document interface to parse the XML messages that are passed between the client and the server. Intermittently I come across NPE that I cannot explain.
The chain of events is as follows: the client sends a message to the server on a separate (not AWT) thread. The response is captured as a string converted to a Document object, at which point the root element is received:
Element root = response.getDocumentElement();
This root element is then passed to the leaderboard screen, thus:
Leaderboard leaderboard = ScreenCache.getLeaderboard();
if (!leaderboard.isVisible())
{
return;
}
leaderboard.buildTablesFromResponseLater(root);
Then I call on the AWT thread, since I am going to use the data to redraw the screen in various ways (updating tables, etc) and Swing is not thread safe. I also read somewhere that DOM stuff is not thread safe (although I can't get life to discover it again).
public void buildTablesFromResponseLater(final Element root)
{
Runnable updateRunnable = new Runnable()
{
@Override
public void run()
{
buildTablesFromResponse(root);
}
};
SwingUtilities.invokeLater(updateRunnable);
}
Inside buildTablesFromResponse, I start to parse the XML. I get various attributes from it and then I call the following code:
NodeList children = root.getElementsByTagName(TAG_ROOM_STATS);
int length = children.getLength(); <- NPE HERE
However, this creates an NPE as shown below:
10/05 23:44:14.505 java.lang.NullPointerException
at com.sun.org.apache.xerces.internal.dom.DeepNodeListImpl.nextMatchingElementAfter(Unknown Source)
at com.sun.org.apache.xerces.internal.dom.DeepNodeListImpl.item(Unknown Source)
at com.sun.org.apache.xerces.internal.dom.DeepNodeListImpl.getLength(Unknown Source)
at online.screen.g.d(Leaderboard.java:370)
at online.screen.g.c(Leaderboard.java:364)
at online.screen.g.b(Leaderboard.java:315)
at online.screen.g.a(Leaderboard.java:312)
at online.screen.g$4.run(Leaderboard.java:305)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$400(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(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)
I can't see what I am doing wrong here. There are various other places where I parse XML like this and it works great and as I said this issue is rare even with Leaderboard. The only differences I can think of are the following:
- The listing post is likely to be "cumbersome" than the others.
- Other places will almost certainly get a NodeList / length on the same stream that opens the socket, which will be a non-AWT stream. However, I would have thought it would be more prone to problems than less!
If somehow the AWT issue is an issue then this is a quick fix to parse the XML before accessing the AWT thread to draw the screen. I'm just reluctant to do this without understanding the underlying problem.
source to share
Obviously this is a very old thread, but in case anyone else runs into this problem ... I recently ran into this problem and after some research, the only suggestion I could find is that it happens because parsing still happens when accessors are called. So I guess to briefly summarize what I found, yes, you have to completely finish parsing the XML before accessing it.
From this thread ( https://community.oracle.com/thread/2114086 ):
This is because JAXP is not thread safe. need to sync the bracket or use a flow parser.
source to share