diff --git a/parquet-avro/src/main/java/org/apache/parquet/avro/AvroWriteSupport.java b/parquet-avro/src/main/java/org/apache/parquet/avro/AvroWriteSupport.java index 35e3924148..48fc01ebf2 100644 --- a/parquet-avro/src/main/java/org/apache/parquet/avro/AvroWriteSupport.java +++ b/parquet-avro/src/main/java/org/apache/parquet/avro/AvroWriteSupport.java @@ -452,8 +452,24 @@ public void writeCollection(GroupType schema, Schema avroSchema, Collection array) { if (array.size() > 0) { recordConsumer.startField(OLD_LIST_REPEATED_NAME, 0); - for (Object elt : array) { - writeValue(schema.getType(0), avroSchema.getElementType(), elt); + try { + for (Object elt : array) { + writeValue(schema.getType(0), avroSchema.getElementType(), elt); + } + } catch (NullPointerException e) { + // find the null element and throw a better error message + int i = 0; + for (Object elt : array) { + if (elt == null) { + throw new NullPointerException( + "Array contains a null element at " + i + "\n" + + "Set parquet.avro.write-old-list-structure=false to turn " + + "on support for arrays with null elements."); + } + i += 1; + } + // no element was null, throw the original exception + throw e; } recordConsumer.endField(OLD_LIST_REPEATED_NAME, 0); } @@ -464,8 +480,22 @@ protected void writeObjectArray(GroupType type, Schema schema, Object[] array) { if (array.length > 0) { recordConsumer.startField(OLD_LIST_REPEATED_NAME, 0); - for (Object element : array) { - writeValue(type.getType(0), schema.getElementType(), element); + try { + for (Object element : array) { + writeValue(type.getType(0), schema.getElementType(), element); + } + } catch (NullPointerException e) { + // find the null element and throw a better error message + for (int i = 0; i < array.length; i += 1) { + if (array[i] == null) { + throw new NullPointerException( + "Array contains a null element at " + i + "\n" + + "Set parquet.avro.write-old-list-structure=false to turn " + + "on support for arrays with null elements."); + } + } + // no element was null, throw the original exception + throw e; } recordConsumer.endField(OLD_LIST_REPEATED_NAME, 0); } diff --git a/parquet-avro/src/test/java/org/apache/parquet/avro/TestReadWriteOldListBehavior.java b/parquet-avro/src/test/java/org/apache/parquet/avro/TestReadWriteOldListBehavior.java index 7c2bc27592..64caacc8b0 100644 --- a/parquet-avro/src/test/java/org/apache/parquet/avro/TestReadWriteOldListBehavior.java +++ b/parquet-avro/src/test/java/org/apache/parquet/avro/TestReadWriteOldListBehavior.java @@ -43,6 +43,7 @@ import org.apache.parquet.io.api.Binary; import org.apache.parquet.io.api.RecordConsumer; import org.apache.parquet.schema.MessageTypeParser; +import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -347,7 +348,8 @@ public void testArrayWithNullValues() throws Exception { writer.write(record); fail("Should not succeed writing an array with null values"); } catch (Exception e) { - // expected + Assert.assertTrue("Error message should provide context and help", + e.getMessage().contains("parquet.avro.write-old-list-structure")); } finally { writer.close(); }