[ 
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 ObjectOutputStream 
or just a DataOutputStream.

With ObjectOutputStream DataSerializer.writeObject just calls writeObject on 
the underlying ObjectOutputStream. With DataOutputStream, DataSerializer 
constructs a new ObjectOutputStream.

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 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}


> 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 
> ObjectOutputStream or just a DataOutputStream.
> With ObjectOutputStream DataSerializer.writeObject just calls writeObject on 
> the underlying ObjectOutputStream. With DataOutputStream, DataSerializer 
> constructs a new ObjectOutputStream.
> 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