[ 
https://issues.apache.org/jira/browse/GEODE-2130?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Bruce Schuchardt updated GEODE-2130:
------------------------------------
    Description: 
I hit this with a simple test using DataSerializer to write and read a java 
Serializable object.

The problem I'm seeing is that there is a difference in the serialized form of 
an object depending on whether DataSerializer is passed an ObjectInputStream or 
just a DataInputStream.

With ObjectInputStream DataSerializer.writeObject just calls writeObject on the 
underlying ObjectInputStream. With DataInputStream, DataSerializer constructs a 
new ObjectInputStream.

The problem is that the constructor for ObjectOutputStream actually writes two 
shorts to the stream. So the serialized form may or may not include those two 
shorts.

DataSerializer.readObject expects to read those two shorts, because it 
constructs a DSObjectInputStream unless the input is already a 
DSObjectInputStream.

Because of that, just writing and reading an object and result in an 
EOFException:
{noformat}
java.io.EOFException
        at 
java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2353)
        at 
java.io.ObjectInputStream$BlockDataInputStream.readShort(ObjectInputStream.java:2822)
        at 
java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:804)
        at java.io.ObjectInputStream.<init>(ObjectInputStream.java:301)
        at 
org.apache.geode.internal.InternalDataSerializer$DSObjectInputStream.<init>(InternalDataSerializer.java:3583)
        at 
org.apache.geode.internal.InternalDataSerializer.basicReadObject(InternalDataSerializer.java:2988)
        at org.apache.geode.DataSerializer.readObject(DataSerializer.java:3281)
        at DataSerializerJUnitTest.test(DataSerializerJUnitTest.java:20)
{noformat}

Here's a simple test of this issue:
{code}
import org.apache.geode.DataSerializer;
import org.junit.Test;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class DataSerializerJUnitTest {

  @Test
  public void test() throws IOException, ClassNotFoundException {
    final ByteArrayOutputStream byteArrayOutputStream = new 
ByteArrayOutputStream();
    ObjectOutputStream out = new ObjectOutputStream(byteArrayOutputStream);
    DataSerializer.writeObject(new MyObject(), out);
    out.close();
    ObjectInputStream in = new ObjectInputStream(new 
ByteArrayInputStream(byteArrayOutputStream.toByteArray()));
    final Object object = DataSerializer.readObject(in);
  }

  private static class MyObject implements Serializable {

  }
}
{code}

  was:
I hit this with a simple test using DataSerializer to write and read a java 
Serializable object.

The problem I'm seeing is that there is a difference in the serialized form of 
an object depending on whether DataSerializer is passed an ObjectInputStream or 
just a DataInputStream.

With ObjectInputStream DataSerializer.writeObject just calls writeObject on the 
underlying ObjectInputStream. With DataInputStream, DataSerializer constructs a 
new ObjectInputStream.

The problem is that the constructor for ObjectInputStream actually writes two 
shorts to the stream. So the serialized form may or may not include those two 
shorts.

DataSerializer.writeObject expects to read those two shorts, because it 
constructs a DSObjectInputStream unless the input is already a 
DSObjectInputStream.

Because of that, just writing and reading an object and result in an 
EOFException:
{noformat}
java.io.EOFException
        at 
java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2353)
        at 
java.io.ObjectInputStream$BlockDataInputStream.readShort(ObjectInputStream.java:2822)
        at 
java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:804)
        at java.io.ObjectInputStream.<init>(ObjectInputStream.java:301)
        at 
org.apache.geode.internal.InternalDataSerializer$DSObjectInputStream.<init>(InternalDataSerializer.java:3583)
        at 
org.apache.geode.internal.InternalDataSerializer.basicReadObject(InternalDataSerializer.java:2988)
        at org.apache.geode.DataSerializer.readObject(DataSerializer.java:3281)
        at DataSerializerJUnitTest.test(DataSerializerJUnitTest.java:20)
{noformat}

Here's a simple test of this issue:
{code}
import org.apache.geode.DataSerializer;
import org.junit.Test;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class DataSerializerJUnitTest {

  @Test
  public void test() throws IOException, ClassNotFoundException {
    final ByteArrayOutputStream byteArrayOutputStream = new 
ByteArrayOutputStream();
    ObjectOutputStream out = new ObjectOutputStream(byteArrayOutputStream);
    DataSerializer.writeObject(new MyObject(), out);
    out.close();
    ObjectInputStream in = new ObjectInputStream(new 
ByteArrayInputStream(byteArrayOutputStream.toByteArray()));
    final Object object = DataSerializer.readObject(in);
  }

  private static class MyObject implements Serializable {

  }
}
{code}


> Serialized data generated by DataSerializer.writeObject depends on the type 
> of OutputStream
> -------------------------------------------------------------------------------------------
>
>                 Key: GEODE-2130
>                 URL: https://issues.apache.org/jira/browse/GEODE-2130
>             Project: Geode
>          Issue Type: Bug
>          Components: serialization
>            Reporter: Dan Smith
>
> I hit this with a simple test using DataSerializer to write and read a java 
> Serializable object.
> The problem I'm seeing is that there is a difference in the serialized form 
> of an object depending on whether DataSerializer is passed an 
> ObjectInputStream or just a DataInputStream.
> With ObjectInputStream DataSerializer.writeObject just calls writeObject on 
> the underlying ObjectInputStream. With DataInputStream, DataSerializer 
> constructs a new ObjectInputStream.
> The problem is that the constructor for ObjectOutputStream actually writes 
> two shorts to the stream. So the serialized form may or may not include those 
> two shorts.
> DataSerializer.readObject expects to read those two shorts, because it 
> constructs a DSObjectInputStream unless the input is already a 
> DSObjectInputStream.
> Because of that, just writing and reading an object and result in an 
> EOFException:
> {noformat}
> java.io.EOFException
>       at 
> java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2353)
>       at 
> java.io.ObjectInputStream$BlockDataInputStream.readShort(ObjectInputStream.java:2822)
>       at 
> java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:804)
>       at java.io.ObjectInputStream.<init>(ObjectInputStream.java:301)
>       at 
> org.apache.geode.internal.InternalDataSerializer$DSObjectInputStream.<init>(InternalDataSerializer.java:3583)
>       at 
> org.apache.geode.internal.InternalDataSerializer.basicReadObject(InternalDataSerializer.java:2988)
>       at org.apache.geode.DataSerializer.readObject(DataSerializer.java:3281)
>       at DataSerializerJUnitTest.test(DataSerializerJUnitTest.java:20)
> {noformat}
> Here's a simple test of this issue:
> {code}
> import org.apache.geode.DataSerializer;
> import org.junit.Test;
> import java.io.ByteArrayInputStream;
> import java.io.ByteArrayOutputStream;
> import java.io.IOException;
> import java.io.ObjectInputStream;
> import java.io.ObjectOutputStream;
> import java.io.Serializable;
> public class DataSerializerJUnitTest {
>   @Test
>   public void test() throws IOException, ClassNotFoundException {
>     final ByteArrayOutputStream byteArrayOutputStream = new 
> ByteArrayOutputStream();
>     ObjectOutputStream out = new ObjectOutputStream(byteArrayOutputStream);
>     DataSerializer.writeObject(new MyObject(), out);
>     out.close();
>     ObjectInputStream in = new ObjectInputStream(new 
> ByteArrayInputStream(byteArrayOutputStream.toByteArray()));
>     final Object object = DataSerializer.readObject(in);
>   }
>   private static class MyObject implements Serializable {
>   }
> }
> {code}



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to