tags:

views:

637

answers:

3

I am attempting to receive a stream of XML events over a Java NIO channel. I am new to both NIO and StAX parsing, so I could very easily be overlooking something :)

My search has led me to several SAX and StAX implementations, but they all seem to operate on InputStreams and InputSources--not NIO channels. The two closest attempts I have made have been to get the InputStream from the channel and create a PipedInputStream:

// method 1
PipedOutputStream out = new PipedOutputStream();
InputStream in = new PipedInputStream(out);
PrintWriter writer = new PrintWriter(out);

//method 2
InputStream in = channel.socket().getInputStream()
//method 3
IputStream in = Channels.newInputStream(channel);

followed by:

XMLStreamReader xmlStreamReader = XMLInputFactory.newInstance()
     .createXMLStreamReader(in);
//...

When the above code is used with method 1, it blocks on the createXMLStreamReader line. When methods 2/3 are used, they immediately throw IllegalBlockingModeException (I do understand why). Maybe a new approach is needed?

My goal is to have a non-blocking server select => accept character data from a client => parse it to XML events using a specific encoding => forward that event object to another thread for processing => and return to the selecting.

So am I overlooking something, or is there a better approach that can be used? If so what?

Thanks!

A: 

You need to use the java.nio.channels.Channels utility class.

ReadableByteChannel ch = //...
InputStream in = Channels.newInputStream(ch);

You may need to configure the socket channel to be blocking.

SelectableChannel ch = //...
ch.configureBlocking(true);

This means you will not be able to do non-blocking I/O.

Michael Barker
The OP already tried that (see method 3).
skaffman
Yes, noticed that after I posted, I've added the configureBlocking call which should fix method 3.
Michael Barker
The problem with blocking is that I am trying to not have a thread per connection, but rather a single thread read and then fork out additional processing as needed
Harlan Iverson
You and me both: http://stackoverflow.com/questions/1023759/is-there-a-push-based-non-blocking-xml-parser-for-java
Michael Barker
Well now, we are trying to solve exactly the same problem for exactly the same application. Funny.
Harlan Iverson
+1  A: 

Are you sure you need to use NIO? It may not offer the relative benefits originally expected:

Paul Tyma: Kill the myth please. NIO is not faster than IO

Paul Tyma: Writing Java Multithreaded Servers - whats old is new

A stack showing where inside createXMLStreamReader() it is blocking could help, but it's probably behaving as designed. If it was designed to work against InputStreams which always either (1) give the expected amount of data; (2) end; or (3) block, then it won't automatically behave in a (usually more complicated and stateful) way that can return after reading any amount of incomplete input, without lots of deep reworking.

gojomo
+1  A: 

I also started looking around, also for XMPP server use. I have been looking around and it looks like there is only one implementation which promises NIO support: Aalto http://wiki.fasterxml.com/AaltoHome

But it seems to have released up to version 0.9.5, March 2009. So, I'm not sure how well maintained it is, but this might be a good starting point. Unless you can convince a bigger project (maybe Woodstox), to rework some of their internal classes for NIO support.

fern
Quick comment: although it may not be apparent from Aalto page, its developer base has significant overlap with Woodstox. Part of this is that internal of Aalto are very different, and its not trivially easy to make BIO-based systems work on NIO.Aalto, on the other hand, is a very good match for NIO -- it has async mode, which while bit incomplete (API not fully defined), is quite close to production ready. So if anyone is interested, feel free to join Aalto discussion forum -- developers (including myself) would love to see more participation.
StaxMan