StAX parsing from Java NIO channel
Asked Answered
S

3

8

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!

Stewpan answered 25/6, 2009 at 18:38 Comment(2)
Like Fern mentioned, Aalto xml processor has async mode, which is designed for such use cases. There hasn't been very much interest (not that many NIO-based systems... yet) for async mode -- all existing users seem to use BIO -- but it actually would be a very good fit.Nixon
And finally with version 0.9.7, there's small bit of documentation to show how to non-blocking parsing, see: cowtowncoder.com/blog/archives/2011/03/entry_451.htmlNixon
B
4

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.

Barehanded answered 3/7, 2009 at 20:49 Comment(1)
NIO isn't granted to be faster than default I/O. But it can be.Elide
F
2

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.

Frilling answered 13/10, 2009 at 23:28 Comment(1)
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.Nixon
M
0

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.

Mistrustful answered 25/6, 2009 at 18:54 Comment(4)
Yes, noticed that after I posted, I've added the configureBlocking call which should fix method 3.Mistrustful
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 neededStewpan
You and me both: #1024259Mistrustful
Well now, we are trying to solve exactly the same problem for exactly the same application. Funny.Stewpan

© 2022 - 2024 — McMap. All rights reserved.