Ignite 2.8.1 ContinuousQueryWithTransformer: ClassCastException on PME

classic Classic list List threaded Threaded
4 messages Options
Ivan.Fedorenkov-2 Ivan.Fedorenkov-2
Reply | Threaded
Open this post in threaded view
|

Ignite 2.8.1 ContinuousQueryWithTransformer: ClassCastException on PME

Hi everyone!

I am getting the ClassCastException when a node from my cluster fails over. It looks like the root cause is that nodes are loading some keys from their backups and the CacheContinousQueryHandler is assuming that the entries are already converted by the remote side which is a false expectation.

The stacktrace is:

Caused by: java.lang.ClassCastException: org.apache.ignite.internal.binary.BinaryObjectImpl cannot be cast to java.lang.String

...

        at org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousQueryHandler.notifyLocalListener(CacheContinuousQueryHandler.java:1114)

        at org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousQueryHandler.notifyCallback0(CacheContinuousQueryHandler.java:940)

        at org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousQueryHandler.notifyCallback(CacheContinuousQueryHandler.java:881)

        at org.apache.ignite.internal.processors.continuous.GridContinuousProcessor.addBackupNotification(GridContinuousProcessor.java:1161)

        at org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousQueryHandler$2.flushBackupQueue(CacheContinuousQueryHandler.java:498)

        at org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousQueryManager.flushBackupQueue(CacheContinuousQueryManager.java:687)

        at org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsExchangeFuture.onDone(GridDhtPartitionsExchangeFuture.java:2261)

        at org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsExchangeFuture.processFullMessage(GridDhtPartitionsExchangeFuture.java:4375)

        at org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsExchangeFuture.access$1500(GridDhtPartitionsExchangeFuture.java:148)

        at org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsExchangeFuture$4.apply(GridDhtPartitionsExchangeFuture.java:4054)

        at org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsExchangeFuture$4.apply(GridDhtPartitionsExchangeFuture.java:4042)

        at org.apache.ignite.internal.util.future.GridFutureAdapter.notifyListener(GridFutureAdapter.java:399)

        at org.apache.ignite.internal.util.future.GridFutureAdapter.listen(GridFutureAdapter.java:354)

        at org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsExchangeFuture.onReceiveFullMessage(GridDhtPartitionsExchangeFuture.java:4042)

        at org.apache.ignite.internal.processors.cache.GridCachePartitionExchangeManager.processFullPartitionUpdate(GridCachePartitionExchangeManager.java:1886)

        at org.apache.ignite.internal.processors.cache.GridCachePartitionExchangeManager$3.onMessage(GridCachePartitionExchangeManager.java:429)

        at org.apache.ignite.internal.processors.cache.GridCachePartitionExchangeManager$3.onMessage(GridCachePartitionExchangeManager.java:416)

        at org.apache.ignite.internal.processors.cache.GridCachePartitionExchangeManager$MessageHandler.apply(GridCachePartitionExchangeManager.java:3667)

        at org.apache.ignite.internal.processors.cache.GridCachePartitionExchangeManager$MessageHandler.apply(GridCachePartitionExchangeManager.java:3646)

        at org.apache.ignite.internal.processors.cache.GridCacheIoManager.processMessage(GridCacheIoManager.java:1142)

        at org.apache.ignite.internal.processors.cache.GridCacheIoManager.onMessage0(GridCacheIoManager.java:591)

        at org.apache.ignite.internal.processors.cache.GridCacheIoManager.handleMessage(GridCacheIoManager.java:392)

        at org.apache.ignite.internal.processors.cache.GridCacheIoManager.handleMessage(GridCacheIoManager.java:318)

        at org.apache.ignite.internal.processors.cache.GridCacheIoManager.access$100(GridCacheIoManager.java:109)

        at org.apache.ignite.internal.processors.cache.GridCacheIoManager$1.onMessage(GridCacheIoManager.java:308)

        at org.apache.ignite.internal.managers.communication.GridIoManager.invokeListener(GridIoManager.java:1847)

        at org.apache.ignite.internal.managers.communication.GridIoManager.processRegularMessage0(GridIoManager.java:1472)

        at org.apache.ignite.internal.managers.communication.GridIoManager.access$5200(GridIoManager.java:229)

        at org.apache.ignite.internal.managers.communication.GridIoManager$9.run(GridIoManager.java:1367)

The workaround is:

public abstract class CqWithTransformerLocalListenerAdapter<T>
   implements ContinuousQueryWithTransformer.EventListener<T>
{
   private final Function<BinaryObject, T> localTransformer;

   protected CqWithTransformerLocalListenerAdapter(Function<BinaryObject, T> localTransformer) {
      this.localTransformer = localTransformer;
   }

   /**
    * The same as {@link ContinuousQueryWithTransformer.EventListener#onUpdated(Iterable)},
    * but guarantees that entities are transformed.
    */
   protected abstract void onUpdatedTransformed(Iterable<T> entities);

   @Override
   public final void onUpdated(Iterable entities) {
      onUpdatedTransformed(new IterableAdapter(entities));
   }

   private class IterableAdapter implements Iterable<T> {
      private final Iterable<?> entities;

      public IterableAdapter(Iterable<?> entities) {
         this.entities = entities;
      }

      @NotNull
      @Override
      public Iterator<T> iterator() {
         return new IteratorWrapper(entities.iterator());
      }
   }

   private class IteratorWrapper implements Iterator<T> {
      private final Iterator<?> underlying;

      public IteratorWrapper(Iterator<?> underlying) {
         this.underlying = underlying;
      }

      @Override
      public boolean hasNext() {
         return underlying.hasNext();
      }

      @Override
      public T next() {
         Object o = underlying.next();
         // Sometimes an entity may be in a binary form (see javadoc of the enclosing class).
         if (o instanceof BinaryObject) {
            return localTransformer.apply((BinaryObject) o);
         }
         // The entity has been converted by a remote transformer
         return (T) o;
      }
   }
}

Best regards,
Ivan Fedorenkov
ilya.kasnacheev ilya.kasnacheev
Reply | Threaded
Open this post in threaded view
|

Re: Ignite 2.8.1 ContinuousQueryWithTransformer: ClassCastException on PME

Hello!

Do you have a reproducer for this issue? I think I could validate it and create an issue if you do.

Can you please also check if it works or not on e.g. Apache Ignite 2.9RC2?

Regards,
--
Ilya Kasnacheev


вт, 6 окт. 2020 г. в 14:30, <[hidden email]>:
Hi everyone!

I am getting the ClassCastException when a node from my cluster fails over. It looks like the root cause is that nodes are loading some keys from their backups and the CacheContinousQueryHandler is assuming that the entries are already converted by the remote side which is a false expectation.

The stacktrace is:

Caused by: java.lang.ClassCastException: org.apache.ignite.internal.binary.BinaryObjectImpl cannot be cast to java.lang.String

...

        at org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousQueryHandler.notifyLocalListener(CacheContinuousQueryHandler.java:1114)

        at org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousQueryHandler.notifyCallback0(CacheContinuousQueryHandler.java:940)

        at org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousQueryHandler.notifyCallback(CacheContinuousQueryHandler.java:881)

        at org.apache.ignite.internal.processors.continuous.GridContinuousProcessor.addBackupNotification(GridContinuousProcessor.java:1161)

        at org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousQueryHandler$2.flushBackupQueue(CacheContinuousQueryHandler.java:498)

        at org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousQueryManager.flushBackupQueue(CacheContinuousQueryManager.java:687)

        at org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsExchangeFuture.onDone(GridDhtPartitionsExchangeFuture.java:2261)

        at org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsExchangeFuture.processFullMessage(GridDhtPartitionsExchangeFuture.java:4375)

        at org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsExchangeFuture.access$1500(GridDhtPartitionsExchangeFuture.java:148)

        at org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsExchangeFuture$4.apply(GridDhtPartitionsExchangeFuture.java:4054)

        at org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsExchangeFuture$4.apply(GridDhtPartitionsExchangeFuture.java:4042)

        at org.apache.ignite.internal.util.future.GridFutureAdapter.notifyListener(GridFutureAdapter.java:399)

        at org.apache.ignite.internal.util.future.GridFutureAdapter.listen(GridFutureAdapter.java:354)

        at org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsExchangeFuture.onReceiveFullMessage(GridDhtPartitionsExchangeFuture.java:4042)

        at org.apache.ignite.internal.processors.cache.GridCachePartitionExchangeManager.processFullPartitionUpdate(GridCachePartitionExchangeManager.java:1886)

        at org.apache.ignite.internal.processors.cache.GridCachePartitionExchangeManager$3.onMessage(GridCachePartitionExchangeManager.java:429)

        at org.apache.ignite.internal.processors.cache.GridCachePartitionExchangeManager$3.onMessage(GridCachePartitionExchangeManager.java:416)

        at org.apache.ignite.internal.processors.cache.GridCachePartitionExchangeManager$MessageHandler.apply(GridCachePartitionExchangeManager.java:3667)

        at org.apache.ignite.internal.processors.cache.GridCachePartitionExchangeManager$MessageHandler.apply(GridCachePartitionExchangeManager.java:3646)

        at org.apache.ignite.internal.processors.cache.GridCacheIoManager.processMessage(GridCacheIoManager.java:1142)

        at org.apache.ignite.internal.processors.cache.GridCacheIoManager.onMessage0(GridCacheIoManager.java:591)

        at org.apache.ignite.internal.processors.cache.GridCacheIoManager.handleMessage(GridCacheIoManager.java:392)

        at org.apache.ignite.internal.processors.cache.GridCacheIoManager.handleMessage(GridCacheIoManager.java:318)

        at org.apache.ignite.internal.processors.cache.GridCacheIoManager.access$100(GridCacheIoManager.java:109)

        at org.apache.ignite.internal.processors.cache.GridCacheIoManager$1.onMessage(GridCacheIoManager.java:308)

        at org.apache.ignite.internal.managers.communication.GridIoManager.invokeListener(GridIoManager.java:1847)

        at org.apache.ignite.internal.managers.communication.GridIoManager.processRegularMessage0(GridIoManager.java:1472)

        at org.apache.ignite.internal.managers.communication.GridIoManager.access$5200(GridIoManager.java:229)

        at org.apache.ignite.internal.managers.communication.GridIoManager$9.run(GridIoManager.java:1367)

The workaround is:

public abstract class CqWithTransformerLocalListenerAdapter<T>
   implements ContinuousQueryWithTransformer.EventListener<T>
{
   private final Function<BinaryObject, T> localTransformer;

   protected CqWithTransformerLocalListenerAdapter(Function<BinaryObject, T> localTransformer) {
      this.localTransformer = localTransformer;
   }

   /**
    * The same as {@link ContinuousQueryWithTransformer.EventListener#onUpdated(Iterable)},
    * but guarantees that entities are transformed.
    */
   protected abstract void onUpdatedTransformed(Iterable<T> entities);

   @Override
   public final void onUpdated(Iterable entities) {
      onUpdatedTransformed(new IterableAdapter(entities));
   }

   private class IterableAdapter implements Iterable<T> {
      private final Iterable<?> entities;

      public IterableAdapter(Iterable<?> entities) {
         this.entities = entities;
      }

      @NotNull
      @Override
      public Iterator<T> iterator() {
         return new IteratorWrapper(entities.iterator());
      }
   }

   private class IteratorWrapper implements Iterator<T> {
      private final Iterator<?> underlying;

      public IteratorWrapper(Iterator<?> underlying) {
         this.underlying = underlying;
      }

      @Override
      public boolean hasNext() {
         return underlying.hasNext();
      }

      @Override
      public T next() {
         Object o = underlying.next();
         // Sometimes an entity may be in a binary form (see javadoc of the enclosing class).
         if (o instanceof BinaryObject) {
            return localTransformer.apply((BinaryObject) o);
         }
         // The entity has been converted by a remote transformer
         return (T) o;
      }
   }
}

Best regards,
Ivan Fedorenkov
Ivan.Fedorenkov-2 Ivan.Fedorenkov-2
Reply | Threaded
Open this post in threaded view
|

Re: Ignite 2.8.1 ContinuousQueryWithTransformer: ClassCastException on PME

Could you please guide be through the process? Should I create just a simple project anywhere and share it here or I should create a test case in the Ignite project?

From: Ilya Kasnacheev <[hidden email]>
Reply-To: "[hidden email]" <[hidden email]>
Date: Tuesday, October 6, 2020 at 3:44 PM
To: "[hidden email]" <[hidden email]>
Subject: Re: Ignite 2.8.1 ContinuousQueryWithTransformer: ClassCastException on PME

Hello!

Do you have a reproducer for this issue? I think I could validate it and create an issue if you do.

Can you please also check if it works or not on e.g. Apache Ignite 2.9RC2?

Regards,
--
Ilya Kasnacheev


вт, 6 окт. 2020 г. в 14:30, <[hidden email]<mailto:[hidden email]>>:
Hi everyone!

I am getting the ClassCastException when a node from my cluster fails over. It looks like the root cause is that nodes are loading some keys from their backups and the CacheContinousQueryHandler is assuming that the entries are already converted by the remote side which is a false expectation.

The stacktrace is:

Caused by: java.lang.ClassCastException: org.apache.ignite.internal.binary.BinaryObjectImpl cannot be cast to java.lang.String

...

        at org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousQueryHandler.notifyLocalListener(CacheContinuousQueryHandler.java:1114)

        at org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousQueryHandler.notifyCallback0(CacheContinuousQueryHandler.java:940)

        at org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousQueryHandler.notifyCallback(CacheContinuousQueryHandler.java:881)

        at org.apache.ignite.internal.processors.continuous.GridContinuousProcessor.addBackupNotification(GridContinuousProcessor.java:1161)

        at org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousQueryHandler$2.flushBackupQueue(CacheContinuousQueryHandler.java:498)

        at org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousQueryManager.flushBackupQueue(CacheContinuousQueryManager.java:687)

        at org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsExchangeFuture.onDone(GridDhtPartitionsExchangeFuture.java:2261)

        at org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsExchangeFuture.processFullMessage(GridDhtPartitionsExchangeFuture.java:4375)

        at org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsExchangeFuture.access$1500(GridDhtPartitionsExchangeFuture.java:148)

        at org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsExchangeFuture$4.apply(GridDhtPartitionsExchangeFuture.java:4054)

        at org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsExchangeFuture$4.apply(GridDhtPartitionsExchangeFuture.java:4042)

        at org.apache.ignite.internal.util.future.GridFutureAdapter.notifyListener(GridFutureAdapter.java:399)

        at org.apache.ignite.internal.util.future.GridFutureAdapter.listen(GridFutureAdapter.java:354)

        at org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsExchangeFuture.onReceiveFullMessage(GridDhtPartitionsExchangeFuture.java:4042)

        at org.apache.ignite.internal.processors.cache.GridCachePartitionExchangeManager.processFullPartitionUpdate(GridCachePartitionExchangeManager.java:1886)

        at org.apache.ignite.internal.processors.cache.GridCachePartitionExchangeManager$3.onMessage(GridCachePartitionExchangeManager.java:429)

        at org.apache.ignite.internal.processors.cache.GridCachePartitionExchangeManager$3.onMessage(GridCachePartitionExchangeManager.java:416)

        at org.apache.ignite.internal.processors.cache.GridCachePartitionExchangeManager$MessageHandler.apply(GridCachePartitionExchangeManager.java:3667)

        at org.apache.ignite.internal.processors.cache.GridCachePartitionExchangeManager$MessageHandler.apply(GridCachePartitionExchangeManager.java:3646)

        at org.apache.ignite.internal.processors.cache.GridCacheIoManager.processMessage(GridCacheIoManager.java:1142)

        at org.apache.ignite.internal.processors.cache.GridCacheIoManager.onMessage0(GridCacheIoManager.java:591)

        at org.apache.ignite.internal.processors.cache.GridCacheIoManager.handleMessage(GridCacheIoManager.java:392)

        at org.apache.ignite.internal.processors.cache.GridCacheIoManager.handleMessage(GridCacheIoManager.java:318)

        at org.apache.ignite.internal.processors.cache.GridCacheIoManager.access$100(GridCacheIoManager.java:109)

        at org.apache.ignite.internal.processors.cache.GridCacheIoManager$1.onMessage(GridCacheIoManager.java:308)

        at org.apache.ignite.internal.managers.communication.GridIoManager.invokeListener(GridIoManager.java:1847)

        at org.apache.ignite.internal.managers.communication.GridIoManager.processRegularMessage0(GridIoManager.java:1472)

        at org.apache.ignite.internal.managers.communication.GridIoManager.access$5200(GridIoManager.java:229)

        at org.apache.ignite.internal.managers.communication.GridIoManager$9.run(GridIoManager.java:1367)

The workaround is:

public abstract class CqWithTransformerLocalListenerAdapter<T>
   implements ContinuousQueryWithTransformer.EventListener<T>
{
   private final Function<BinaryObject, T> localTransformer;

   protected CqWithTransformerLocalListenerAdapter(Function<BinaryObject, T> localTransformer) {
      this.localTransformer = localTransformer;
   }

   /**
    * The same as {@link ContinuousQueryWithTransformer.EventListener#onUpdated(Iterable)},
    * but guarantees that entities are transformed.
    */
   protected abstract void onUpdatedTransformed(Iterable<T> entities);

   @Override
   public final void onUpdated(Iterable entities) {
      onUpdatedTransformed(new IterableAdapter(entities));
   }

   private class IterableAdapter implements Iterable<T> {
      private final Iterable<?> entities;

      public IterableAdapter(Iterable<?> entities) {
         this.entities = entities;
      }

      @NotNull
      @Override
      public Iterator<T> iterator() {
         return new IteratorWrapper(entities.iterator());
      }
   }

   private class IteratorWrapper implements Iterator<T> {
      private final Iterator<?> underlying;

      public IteratorWrapper(Iterator<?> underlying) {
         this.underlying = underlying;
      }

      @Override
      public boolean hasNext() {
         return underlying.hasNext();
      }

      @Override
      public T next() {
         Object o = underlying.next();
         // Sometimes an entity may be in a binary form (see javadoc of the enclosing class).
         if (o instanceof BinaryObject) {
            return localTransformer.apply((BinaryObject) o);
         }
         // The entity has been converted by a remote transformer
         return (T) o;
      }
   }
}

Best regards,
Ivan Fedorenkov
ilya.kasnacheev ilya.kasnacheev
Reply | Threaded
Open this post in threaded view
|

Re: Ignite 2.8.1 ContinuousQueryWithTransformer: ClassCastException on PME

Hello!

You can do either one, I'll take it from there.

Regards,
--
Ilya Kasnacheev


вт, 6 окт. 2020 г. в 17:26, <[hidden email]>:
Could you please guide be through the process? Should I create just a simple project anywhere and share it here or I should create a test case in the Ignite project?

From: Ilya Kasnacheev <[hidden email]>
Reply-To: "[hidden email]" <[hidden email]>
Date: Tuesday, October 6, 2020 at 3:44 PM
To: "[hidden email]" <[hidden email]>
Subject: Re: Ignite 2.8.1 ContinuousQueryWithTransformer: ClassCastException on PME

Hello!

Do you have a reproducer for this issue? I think I could validate it and create an issue if you do.

Can you please also check if it works or not on e.g. Apache Ignite 2.9RC2?

Regards,
--
Ilya Kasnacheev


вт, 6 окт. 2020 г. в 14:30, <[hidden email]<mailto:[hidden email]>>:
Hi everyone!

I am getting the ClassCastException when a node from my cluster fails over. It looks like the root cause is that nodes are loading some keys from their backups and the CacheContinousQueryHandler is assuming that the entries are already converted by the remote side which is a false expectation.

The stacktrace is:

Caused by: java.lang.ClassCastException: org.apache.ignite.internal.binary.BinaryObjectImpl cannot be cast to java.lang.String

...

        at org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousQueryHandler.notifyLocalListener(CacheContinuousQueryHandler.java:1114)

        at org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousQueryHandler.notifyCallback0(CacheContinuousQueryHandler.java:940)

        at org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousQueryHandler.notifyCallback(CacheContinuousQueryHandler.java:881)

        at org.apache.ignite.internal.processors.continuous.GridContinuousProcessor.addBackupNotification(GridContinuousProcessor.java:1161)

        at org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousQueryHandler$2.flushBackupQueue(CacheContinuousQueryHandler.java:498)

        at org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousQueryManager.flushBackupQueue(CacheContinuousQueryManager.java:687)

        at org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsExchangeFuture.onDone(GridDhtPartitionsExchangeFuture.java:2261)

        at org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsExchangeFuture.processFullMessage(GridDhtPartitionsExchangeFuture.java:4375)

        at org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsExchangeFuture.access$1500(GridDhtPartitionsExchangeFuture.java:148)

        at org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsExchangeFuture$4.apply(GridDhtPartitionsExchangeFuture.java:4054)

        at org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsExchangeFuture$4.apply(GridDhtPartitionsExchangeFuture.java:4042)

        at org.apache.ignite.internal.util.future.GridFutureAdapter.notifyListener(GridFutureAdapter.java:399)

        at org.apache.ignite.internal.util.future.GridFutureAdapter.listen(GridFutureAdapter.java:354)

        at org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsExchangeFuture.onReceiveFullMessage(GridDhtPartitionsExchangeFuture.java:4042)

        at org.apache.ignite.internal.processors.cache.GridCachePartitionExchangeManager.processFullPartitionUpdate(GridCachePartitionExchangeManager.java:1886)

        at org.apache.ignite.internal.processors.cache.GridCachePartitionExchangeManager$3.onMessage(GridCachePartitionExchangeManager.java:429)

        at org.apache.ignite.internal.processors.cache.GridCachePartitionExchangeManager$3.onMessage(GridCachePartitionExchangeManager.java:416)

        at org.apache.ignite.internal.processors.cache.GridCachePartitionExchangeManager$MessageHandler.apply(GridCachePartitionExchangeManager.java:3667)

        at org.apache.ignite.internal.processors.cache.GridCachePartitionExchangeManager$MessageHandler.apply(GridCachePartitionExchangeManager.java:3646)

        at org.apache.ignite.internal.processors.cache.GridCacheIoManager.processMessage(GridCacheIoManager.java:1142)

        at org.apache.ignite.internal.processors.cache.GridCacheIoManager.onMessage0(GridCacheIoManager.java:591)

        at org.apache.ignite.internal.processors.cache.GridCacheIoManager.handleMessage(GridCacheIoManager.java:392)

        at org.apache.ignite.internal.processors.cache.GridCacheIoManager.handleMessage(GridCacheIoManager.java:318)

        at org.apache.ignite.internal.processors.cache.GridCacheIoManager.access$100(GridCacheIoManager.java:109)

        at org.apache.ignite.internal.processors.cache.GridCacheIoManager$1.onMessage(GridCacheIoManager.java:308)

        at org.apache.ignite.internal.managers.communication.GridIoManager.invokeListener(GridIoManager.java:1847)

        at org.apache.ignite.internal.managers.communication.GridIoManager.processRegularMessage0(GridIoManager.java:1472)

        at org.apache.ignite.internal.managers.communication.GridIoManager.access$5200(GridIoManager.java:229)

        at org.apache.ignite.internal.managers.communication.GridIoManager$9.run(GridIoManager.java:1367)

The workaround is:

public abstract class CqWithTransformerLocalListenerAdapter<T>
   implements ContinuousQueryWithTransformer.EventListener<T>
{
   private final Function<BinaryObject, T> localTransformer;

   protected CqWithTransformerLocalListenerAdapter(Function<BinaryObject, T> localTransformer) {
      this.localTransformer = localTransformer;
   }

   /**
    * The same as {@link ContinuousQueryWithTransformer.EventListener#onUpdated(Iterable)},
    * but guarantees that entities are transformed.
    */
   protected abstract void onUpdatedTransformed(Iterable<T> entities);

   @Override
   public final void onUpdated(Iterable entities) {
      onUpdatedTransformed(new IterableAdapter(entities));
   }

   private class IterableAdapter implements Iterable<T> {
      private final Iterable<?> entities;

      public IterableAdapter(Iterable<?> entities) {
         this.entities = entities;
      }

      @NotNull
      @Override
      public Iterator<T> iterator() {
         return new IteratorWrapper(entities.iterator());
      }
   }

   private class IteratorWrapper implements Iterator<T> {
      private final Iterator<?> underlying;

      public IteratorWrapper(Iterator<?> underlying) {
         this.underlying = underlying;
      }

      @Override
      public boolean hasNext() {
         return underlying.hasNext();
      }

      @Override
      public T next() {
         Object o = underlying.next();
         // Sometimes an entity may be in a binary form (see javadoc of the enclosing class).
         if (o instanceof BinaryObject) {
            return localTransformer.apply((BinaryObject) o);
         }
         // The entity has been converted by a remote transformer
         return (T) o;
      }
   }
}

Best regards,
Ivan Fedorenkov