6 Replies Latest reply: Jun 6, 2013 12:41 PM by robvarga RSS

    java.lang.ClassCastException when executing an AbstractAggregator

      I'm trying to run an agregator over a distributed cache and I'm getting this exception:
      (Wrapped: Failed request execution for NPDistributedCache service on Member(Id=2, Timestamp=2013-03-16 09:46:09.907, Address=, MachineId=27728, Location=site:,machine:proto1,process:716)) java.lang.ClassCastException: com.tangosol.util.extractor.ReflectionExtractor cannot be cast to com.tangosol.util.InvocableMap$EntryAggregator
              at com.tangosol.util.Base.ensureRuntimeException(Base.java:288)
              at com.tangosol.coherence.component.util.daemon.queueProcessor.service.Grid.tagException(Grid.CDB:36)
              at com.tangosol.coherence.component.util.daemon.queueProcessor.service.grid.partitionedService.PartitionedCache.validateRequestForStorage(PartitionedCache.CDB:37)
              at com.tangosol.coherence.component.util.daemon.queueProcessor.service.grid.partitionedService.PartitionedCache.onAggregateFilterRequest(PartitionedCache.CDB:16)
              at com.tangosol.coherence.component.util.daemon.queueProcessor.service.grid.partitionedService.PartitionedCache$AggregateFilterRequest.run(PartitionedCache.CDB:1)
              at com.tangosol.coherence.component.net.message.requestMessage.DistributedCacheRequest.onReceived(DistributedCacheRequest.CDB:12)
              at com.tangosol.coherence.component.util.daemon.queueProcessor.service.Grid.onMessage(Grid.CDB:34)
              at com.tangosol.coherence.component.util.daemon.queueProcessor.service.Grid.onNotify(Grid.CDB:33)
              at com.tangosol.coherence.component.util.daemon.queueProcessor.service.grid.PartitionedService.onNotify(PartitionedService.CDB:3)
              at com.tangosol.coherence.component.util.daemon.queueProcessor.service.grid.partitionedService.PartitionedCache.onNotify(PartitionedCache.CDB:3)
              at com.tangosol.coherence.component.util.Daemon.run(Daemon.CDB:42)
              at java.lang.Thread.run(Thread.java:662)
      Caused by: java.lang.ClassCastException: com.tangosol.util.extractor.ReflectionExtractor cannot be cast to com.tangosol.util.InvocableMap$EntryAggregator
              at com.tangosol.coherence.component.util.daemon.queueProcessor.service.grid.partitionedService.PartitionedCache$AggregateFilterRequest.read(PartitionedCache.CDB:7)
              at com.tangosol.coherence.component.util.daemon.queueProcessor.service.Grid.deserializeMessage(Grid.CDB:19)
              at com.tangosol.coherence.component.util.daemon.queueProcessor.service.Grid.onNotify(Grid.CDB:31)
              ... 4 more
      The agregator extends from the AbstractAgregator class and I'm using an IdentityExtractor. Here is a piece of code of the agregator:
      public class MyAggregator extends AbstractAggregator {
          public MyAggregator() {
              // IdentityExtractor because I want the stored entry
          protected Object finalizeResult(boolean isFinal) {
              // Simple aggregation operation, with no interaction with the coherence env
          protected void init(boolean isFinal) {
           // Initialize aggregators vars    
          protected void process(Object value, boolean isFinal) {
              // Here we might access named caches using the cache factory to get entries related to the current one
              // i.e. If we are processing a product entry, we will go get from another cache the 'owner' (company entry)
      To execute the aggregator, I'm using the InvocableMap.aggregate() method from the NamedCache get from the CacheFactory.getCache(). As filter, I'm using a simple EqualsFilter("getClass", type).

      All the caches that are used by this aggregator are cofigured using this schema (even those that are get within the process() method)
      Why coherence is trying to cast an extractor to an Aggregator? Which coherence component is using a ReflectionExtractor in my scenario? IMO, I'm using the InvocableMap API to execute a simple aggregator with an IdentityExtractor. Maybe getting others entries within the process() method are causing this? And if it is the case: how can I get others related entries within an aggregator? (I know the problem of getting entries within a Processor (for edition), but for agregation (for read only) this should be feasible right?

      Important info:
      * We are using Coherence 3.7 with the development license and the idea is to deploy the application in production with the standard licence
      * When there is only one single member in the cluster, the agregation works as expected.

      Edited by: ggarciao.com on Mar 16, 2013 11:59 AM
      Adding coherence version

      Edited by: ggarciao.com on Mar 16, 2013 2:48 PM
        • 1. Re: java.lang.ClassCastException when executing an AbstractAggregator

          At the end of your post you say that when there is only a single member in the cluster that it works as expected so this could suggest you have a serialization issue. Do you have the same serializer configured everywhere? If you are using POF is the POF configuration correct and are the serializiation methods in your extractor correct?

          Another point - it is not a good idea to access other caches using Cachefactory.getCache() from inside the aggregator's process method. This would cause re-entrant calls - i.e. calls from one worker thread in the cache service to another worker thread and can cause either thread starvation and in the worst case can cause your cluster to deadlock due to running out of worker threads.

          You say in the code comments that the caches you want to get are to get related data - if you use key association to co-locate related data in other caches in the same cache service onto the same partition then there are more reliable and safer ways to get related data directly from the backing maps.

          If you are going to go down the route of accessing other caches directly you need to be very careful about what services those other caches are in and what code you execute against those caches.

          • 2. Re: java.lang.ClassCastException when executing an AbstractAggregator
            To answer your question regarding which Coherence component is using the ReflectionExtractor.

            When you used this "EqualsFilter("getClass", type)", it will cause Coherence to use ReflectionExtractor since you were asking Coherence to use reflection to invoke getClass() method.
            • 3. Re: java.lang.ClassCastException when executing an AbstractAggregator

              Thanks for this info! So getting entries from another cache within an Aggregator has the same disadvantage that getting them from a Processor? I though that this was related only to the lock get over the keys that the processor is 'editing' but because an agregator is suppose to not edit anything, not locks should be taken ... I'm right on this?

              About association keys, I'm having hard time to understand how to use it in my case: With key associations you need a kind of 'parent key' ... but my business objects cannot have a single parent key because they can be associated to several different kind of objects (and in my case is even worse because these associations (metamodel) can change at runtime - is a dynamic graph). In conclusion: For me the 'key association' mechanism is useful to depicts aggregations (parent-child) instead than weak associations (linked by the id only). What do you think about this?

              Thanks is advance,

              PS: I'm working on the serialization issues to see if the problem is there ... thx
              • 4. Re: java.lang.ClassCastException when executing an AbstractAggregator

                I got it know ... But event with this I cannot understand how a value extractor is been casted to an aggregator.

                Thx any way ...
                • 5. Re: java.lang.ClassCastException when executing an AbstractAggregator

                  Any wisdom you wanna share about this?

                  Thanks in advance,
                  • 6. Re: java.lang.ClassCastException when executing an AbstractAggregator

                    we had the same issue in one of our dev systems, and what caused the issue there is that there was an issue at deserializing the filter on the storage node (could not instantiate the Filter on the other end due to the lack of public parameterless constructor), and that exception was swallowed temporarily, but that caused that the read method of the AggregateFilter message continued read from an incorrect place and therefore the deserialized object what Coherence believed to be the aggregator was in fact part of the filter (the ReflectionExtractor in your case), and blew up again with the ClassCastException, and that ClassCastException overwrote the first one so you did not see the original cause of the error in the log at all.

                    In short, most likely there is an issue with the deserialization of your filter. E.g. I am not sure if deserializing a java.lang.Class object is supported... So for example try replacing
                    new EqualsFilter("getClass", classObject)
                    new EqualsFilter("getClass.getName", classObject.getName())
                    Best regards,