public void write(D datum, Encoder out) throws IOException {
    Objects.requireNonNull(out, "Encoder cannot be null");
    try {
      write(root, datum, out);
    } catch (TracingNullPointException | TracingClassCastException | TracingAvroTypeException e) {
      throw e.summarize(root);
    }
  }
@Test
  void arrayConcurrentModification() throws Exception {
    String json = "{\"type\": \"array\", \"items\": \"int\" }";
    Schema s = new Schema.Parser().parse(json);
    final GenericArray<Integer> a = new GenericData.Array<>(1, s);
    ByteArrayOutputStream bao = new ByteArrayOutputStream();
    final GenericDatumWriter<GenericArray<Integer>> w = new GenericDatumWriter<>(s);

    CountDownLatch sizeWrittenSignal = new CountDownLatch(1);
    CountDownLatch eltAddedSignal = new CountDownLatch(1);

    final TestEncoder e = new TestEncoder(EncoderFactory.get().directBinaryEncoder(bao, null), sizeWrittenSignal,
        eltAddedSignal);

    // call write in another thread
    ExecutorService executor = Executors.newSingleThreadExecutor();
    Future<Void> result = executor.submit(() -> {
      w.write(a, e);
      return null;
    });
    sizeWrittenSignal.await();
    // size has been written so now add an element to the array
    a.add(7);
    // and signal for the element to be written
    eltAddedSignal.countDown();
    try {
      result.get();
      fail("Expected ConcurrentModificationException");
    } catch (ExecutionException ex) {
      assertTrue(ex.getCause() instanceof ConcurrentModificationException);
    }
  }