Win a copy of Java Concurrency Live Lessons this week in the Threads forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Convert ByteBuffer to an object  RSS feed

 
Ravi Kumarasinghe
Greenhorn
Posts: 12
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi all,
Can somebody please give me some idea of how to convert a nio.ByteBuffer object to an object.
I'm sending an object through a nio.SocketChannel. After I receive it I cant convert the received ByteBuffer to the original object.
I'm getting an Invalid stream header exception when I try to create the object back using an ObjectInputStream and a ByteArrayInputStream
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well, it's hard to say what the problem is without seeing the code. I'd recommend that you use methods in the Channels class to bypass using ByteBuffers entirely, and convert directly between the SocketChannels and streams. E.g. to write an object:

And to read:
 
Ravi Kumarasinghe
Greenhorn
Posts: 12
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Jim,
But I have set socketChannel.configureBlocking(false);
when I used
ObjectInputStream ois = new ObjectInputStream(Channels.newInputStream(socketChannel));
Object obj = ois.readObject();
I got the following exception
java.nio.channels.IllegalBlockingModeException
currently what I have done is
while (selector.select(500) > 0)
{
// Get set of ready objects
Set readyKeys = selector.selectedKeys();
Iterator readyItor = readyKeys.iterator();

// Walk through set
while (readyItor.hasNext())
{

// Get key from set
SelectionKey key = (SelectionKey) readyItor.next();

// Remove current entry
readyItor.remove();

// Get channel
SocketChannel keyChannel = (SocketChannel) key.channel();

if (key.isConnectable())
{

// Finish connection
if (keyChannel.isConnectionPending())
{
while (!keyChannel.finishConnect())
{
}
}

// Send request
keyChannel.write(encoder.encode(CharBuffer.wrap(request)));
}
else if (key.isReadable())
{
// Read what's ready in response
keyChannel.read(buffer);

buffer.flip();
// Decode buffer
decoder.decode(buffer, charBuffer, false);
// Display
charBuffer.flip();

String str = charBuffer.toString();

System.out.println(str);

// Clear for next pass
buffer.clear();
charBuffer.clear();
}
else
{
System.err.println("Ooops");
}
}
when I print the charBuffer I can see the object code of the java object sent through the stream.
But I am still unable to reconstruct the java object out of the ByteBuffer or the CharBuffer
 
David Weitzman
Ranch Hand
Posts: 1365
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ravi, your code is extremely likely to only send and attempt to parse partial o jects. Ultimately your code will probably look something like this (I'm on a laptop with low battery power, so forgive me for not looking up all the API references):


Notes:
The implementation of containsCompleteObject() is necessary if you want to be able to read complete objects as they arrive (instead of waiting until the end of the stream), and will require you to wade through the serialization specs for implementation details.
You might want to use a custom InputStream subclass instead of ByteArrayInputStream so that serialization back references are properly handled (which they won't be if you create a new ObjectOutputStream each time).
Also, there isn't any provision made for the socket being remotely closed in the middle of the write operation. It would be possible to make reading and writing simutanious interestOps to deal with that. I'm not sure if the code above would lead to an exception, infinate hang, or what. I would expect an exception, but unit test it to be sure.
 
Ravi Kumarasinghe
Greenhorn
Posts: 12
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks David,
I was able to extract the object from the byte buffer. Now I'm getting an invalid serialVersionID exception.
If anybody had tried reading an object written out to an ObjectOutputStream from a http servlet using a nio.SocketChannel can you please give me a hint how to do that
[ August 16, 2003: Message edited by: Ravi Kumarasinghe ]
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hmmm. Was that actually the serialVersionUID that the error message is about? As a guess, it sounds like there may be two different .class files for one of hte classes you're serializing. The reader and the writer may not be agreeing on what the class definition is. The easiest solution may be to recompile all the class files and make sure that everyone's got the same version. Alternately you may be able to set the serialVersionUID on your new code to match the old serialVersionUID - this can be accomplished by including the following static field in the class:
private static final long serialVersionUID = 3487495895819393L;
The value can be whatever long value is necessary to make the new code compatible with existing code. Consult your error message carefully - it probably tells you what serialVersionUID was expected.
If problems persists, I'd say, forget about servlets and channels for a moment. Try to just read and write the object correctly using plain ObjectOutputStream and ObjectInputStream connected to something simple like FileOutputStream and FileInputStream. Make sure you can do that first, then try doing it through a servlet,and using a SocketChannel. That way you'll have a better idea if the problem is with how you use the channel, or with something more basic.
 
Ravi Kumarasinghe
Greenhorn
Posts: 12
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Jim,
I got that version problem solved.
Is there any guarantee that I would get all the bytes of the object at one read from the socketChannel. If not (i.e. if I get a part of the object at one read and the other part in the next read) how do I identify that.
Since I'm connected to a http servlet I'm getting html headers as well. So is there any way of identifying the start and end of the object. (any special characters etc.)
Thanks and regards
Ravi
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!