SAX parsers hanging (crimson and xerces) on InputStream
Hi,
While searching I've seen a lot of postings about sax parsers hanging on InputStreams. Many have no replies, some do. So far I've tried several fixes mentioned to no avail. I've seen it hang in the startDocument() and hang after reading the entire document. All sorts of hangs . . . Oh and in some situations it works fine, but that's not good enough.
1. I tried wrapping the InputStream as described at the jdom.org FAQ with my own InputStream that hides the close() call. Then I pass my wrapper InputStream to the saxparser.parse() method. This didn't work, because you need to wrap SocketInputStream, not InputStream and SocketInputStream has package permissions which keep me from inheriting from it. If somebody can shed some light on how to do this, I'll try again, but for now that approach is shelved.
2. I tried adding an EOF character, 0x1A, to the end of the xml string being sent over the socket. The parser still hangs.
Any more suggestions?
Thanks,
Steve
[1034 byte] By [
sliner] at [2007-9-30 4:24:05]

Here's a faq question and answer from jdom.org. Can anybody explain how to do this in more detail? He mentions two workarounds. I've done the second and it works fine, but I'd prefer to get the first workaround working instead -- the wrapper InputStream idea.
Why does passing a document through a socket sometimes hang the parser?
The problem is that several XML parsers close the input stream when they read EOF (-1). This is true of Xerces, which is JDOM's default parser. It is also true of Crimson. Unfortunately, closing a SocketInputStream closes the underlying SocketImpl, setting the file descriptor to null. The socket's output stream is useless after this, so your application will be unable to send a response. To workaround, protect your socket's input stream with an InputStream wrapper that doesn't close the underlying stream (override the close() method), or read everything into a buffer before handing off to the JDOM builder:
byte[] buf = new byte[length];
new DataInputStream(inputStream).readFully(buf);
InputStream in = new ByteArrayInputStream(buf);
(Contributed by Joseph Bowbeer)