public static <T> JAXBCoder<T> of(Class<T> jaxbClass) {
    return new JAXBCoder<>(jaxbClass);
  }
@Test
  @SuppressWarnings("AssertionFailureIgnored")
  public void testEncodeDecodeMultithreaded() throws Throwable {
    final JAXBCoder<TestType> coder = JAXBCoder.of(TestType.class);
    int numThreads = 100;

    final CountDownLatch ready = new CountDownLatch(numThreads);
    final CountDownLatch start = new CountDownLatch(1);
    final CountDownLatch done = new CountDownLatch(numThreads);

    final AtomicReference<Throwable> thrown = new AtomicReference<>();

    Executor executor = Executors.newCachedThreadPool();
    for (int i = 0; i < numThreads; i++) {
      final TestType elem = new TestType("abc", i);
      final int index = i;
      executor.execute(
          () -> {
            ready.countDown();
            try {
              start.await();
            } catch (InterruptedException ignored) {
            }

            try {
              byte[] encoded = CoderUtils.encodeToByteArray(coder, elem);
              assertEquals(
                  new TestType("abc", index), CoderUtils.decodeFromByteArray(coder, encoded));
            } catch (Throwable e) {
              thrown.compareAndSet(null, e);
            }
            done.countDown();
          });
    }
    ready.await();
    start.countDown();

    done.await();
    Throwable actuallyThrown = thrown.get();
    if (actuallyThrown != null) {
      throw actuallyThrown;
    }
  }