Author: scottcarey
Date: Mon Apr 18 23:12:23 2011
New Revision: 1094812
URL: http://svn.apache.org/viewvc?rev=1094812&view=rev
Log:
AVRO-790 Java: GenericDatumReader can fail when reusing objects with unions
containing 'bytes' fields
Modified:
avro/trunk/CHANGES.txt
avro/trunk/lang/java/avro/src/main/java/org/apache/avro/generic/GenericDatumReader.java
avro/trunk/lang/java/ipc/src/test/java/org/apache/avro/TestSchema.java
Modified: avro/trunk/CHANGES.txt
URL:
http://svn.apache.org/viewvc/avro/trunk/CHANGES.txt?rev=1094812&r1=1094811&r2=1094812&view=diff
==============================================================================
--- avro/trunk/CHANGES.txt (original)
+++ avro/trunk/CHANGES.txt Mon Apr 18 23:12:23 2011
@@ -49,6 +49,9 @@ Avro 1.5.1 (unreleased)
AVRO-780. Java: Fix a NullPointerException with reflect data when
a union contains an array and null. (cutting)
+ AVRO-790. Java: GenericDatumReader can fail when reusing objects with
unions
+ containing 'bytes' fields. (scottcarey)
+
Avro 1.5.0 (10 March 2011)
INCOMPATIBLE CHANGES
Modified:
avro/trunk/lang/java/avro/src/main/java/org/apache/avro/generic/GenericDatumReader.java
URL:
http://svn.apache.org/viewvc/avro/trunk/lang/java/avro/src/main/java/org/apache/avro/generic/GenericDatumReader.java?rev=1094812&r1=1094811&r2=1094812&view=diff
==============================================================================
---
avro/trunk/lang/java/avro/src/main/java/org/apache/avro/generic/GenericDatumReader.java
(original)
+++
avro/trunk/lang/java/avro/src/main/java/org/apache/avro/generic/GenericDatumReader.java
Mon Apr 18 23:12:23 2011
@@ -330,7 +330,7 @@ public class GenericDatumReader<D> imple
* byte array representation. By default, this calls {@link
* Decoder#readBytes(ByteBuffer)}.*/
protected Object readBytes(Object old, Decoder in) throws IOException {
- return in.readBytes((ByteBuffer)old);
+ return in.readBytes(old instanceof ByteBuffer ? (ByteBuffer) old : null);
}
/** Called to read integers. Subclasses may override to use a different
Modified: avro/trunk/lang/java/ipc/src/test/java/org/apache/avro/TestSchema.java
URL:
http://svn.apache.org/viewvc/avro/trunk/lang/java/ipc/src/test/java/org/apache/avro/TestSchema.java?rev=1094812&r1=1094811&r2=1094812&view=diff
==============================================================================
--- avro/trunk/lang/java/ipc/src/test/java/org/apache/avro/TestSchema.java
(original)
+++ avro/trunk/lang/java/ipc/src/test/java/org/apache/avro/TestSchema.java Mon
Apr 18 23:12:23 2011
@@ -45,7 +45,6 @@ import org.apache.avro.io.DatumWriter;
import org.apache.avro.io.Decoder;
import org.apache.avro.io.Encoder;
import org.apache.avro.io.EncoderFactory;
-import org.apache.avro.io.JsonDecoder;
import org.apache.avro.compiler.specific.TestSpecificCompiler;
import org.apache.avro.util.Utf8;
@@ -79,7 +78,7 @@ public class TestSchema {
+ " \"name\": \"inner_union\" }\n" + " ]\n" + "}\n";
private static final int COUNT =
- Integer.parseInt(System.getProperty("test.count", "10"));
+ Integer.parseInt(System.getProperty("test.count", "30"));
@Test
public void testNull() throws Exception {
@@ -163,6 +162,18 @@ public class TestSchema {
check("{\"type\":\"map\", \"values\":\"long\"}", "{\"a\":1}", map);
checkParseError("{\"type\":\"map\"}"); // values required
}
+
+ @Test
+ public void testUnionMap() throws Exception {
+ String unionMapSchema = "{\"name\":\"foo\", \"type\":\"record\"," +
+ " \"fields\":[ {\"name\":\"mymap\", \"type\":" +
+ " [{\"type\":\"map\", \"values\":" +
+ " [\"int\",\"long\",\"float\",\"string\"]}," +
+ " \"null\"]" +
+ " }]" +
+ " }";
+ check(unionMapSchema, true);
+ }
@Test
public void testRecord() throws Exception {
@@ -558,6 +569,7 @@ public class TestSchema {
throws Exception {
Schema schema = Schema.parse(jsonSchema);
checkProp(schema);
+ Object reuse = null;
for (Object datum : new RandomData(schema, COUNT)) {
if (induce) {
@@ -570,7 +582,10 @@ public class TestSchema {
checkBinary(schema, datum,
new GenericDatumWriter<Object>(),
- new GenericDatumReader<Object>());
+ new GenericDatumReader<Object>(), null);
+ reuse = checkBinary(schema, datum,
+ new GenericDatumWriter<Object>(),
+ new GenericDatumReader<Object>(), reuse);
checkDirectBinary(schema, datum,
new GenericDatumWriter<Object>(),
new GenericDatumReader<Object>());
@@ -603,6 +618,14 @@ public class TestSchema {
DatumWriter<Object> writer,
DatumReader<Object> reader)
throws IOException {
+ checkBinary(schema, datum, writer, reader, null);
+ }
+
+ public static Object checkBinary(Schema schema, Object datum,
+ DatumWriter<Object> writer,
+ DatumReader<Object> reader,
+ Object reuse)
+ throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
writer.setSchema(schema);
Encoder encoder = EncoderFactory.get().binaryEncoder(out, null);
@@ -613,10 +636,11 @@ public class TestSchema {
reader.setSchema(schema);
Object decoded =
- reader.read(null, DecoderFactory.get().binaryDecoder(
+ reader.read(reuse, DecoderFactory.get().binaryDecoder(
data, null));
assertEquals("Decoded data does not match.", datum, decoded);
+ return decoded;
}
public static void checkDirectBinary(Schema schema, Object datum,