Friday, July 9, 2010

Oracle Coherence, java.lang.IllegalArgumentException: Unsupported key or value

When I define one replicated cluster, and Setup the unit-calculator to binary. hopefully, from the Coherence Mbeans, I should be able to see the object size vs units. By default, size is the same with unit.  When I put some data to the replicated cluster. From the cluster jvm console, I get the following Errors.  the cache extend client didn’t get any error. But when you query the cluster, No objects founds. they are all gone.

2010-07-09 15:50:47.790/300.414 Oracle Coherence GE 3.5.3/465 <Error> (thread=ReplicatedCache, member=1):
java.lang.IllegalArgumentException: Unsupported key or value: Key=9, Value=ID 9PMName PM9PoAmount   135.0PoNumber  null
       at com.tangosol.net.cache.BinaryMemoryCalculator.calculateUnits(BinaryMemoryCalculator.java:43)
        at com.tangosol.net.cache.OldCache$Entry.calculateUnits(OldCache.java:2397)
        at com.tangosol.net.cache.OldCache$Entry.onAdd(OldCache.java:1990)
        at com.tangosol.util.SafeHashMap.put(SafeHashMap.java:244)
        at com.tangosol.net.cache.OldCache.put(OldCache.java:266)
        at com.tangosol.coherence.component.util.CacheHandler.onLeaseUpdate(CacheHandler.CDB:45)
        at com.tangosol.coherence.component.util.daemon.queueProcessor.service.grid.ReplicatedCache.performUpdate(Replic
atedCache.CDB:11)
        at com.tangosol.coherence.component.util.daemon.queueProcessor.service.grid.ReplicatedCache.onLeaseUpdateRequest
(ReplicatedCache.CDB:22)
        at com.tangosol.coherence.component.util.daemon.queueProcessor.service.grid.ReplicatedCache$LeaseUpdateRequest.o
nReceived(ReplicatedCache.CDB:5)
        at com.tangosol.coherence.component.util.daemon.queueProcessor.service.Grid.onMessage(Grid.CDB:9)
        at com.tangosol.coherence.component.util.daemon.queueProcessor.service.Grid.onNotify(Grid.CDB:136)
        at com.tangosol.coherence.component.util.daemon.queueProcessor.service.grid.ReplicatedCache.onNotify(ReplicatedC
ache.CDB:3)
        at com.tangosol.coherence.component.util.Daemon.run(Daemon.CDB:42)
        at java.lang.Thread.run(Thread.java:619)

What does this error means?  it looks like there are something wrong with the BinaryMemoryCalculator.calculateUnits

what’s the logic in this method. we can turn to JD-GUI [ java decompilers, like the .net reflector. ] I get the code here

/*    */   public int calculateUnits(Object oKey, Object oValue)
/*    */   {
/* 35 */     if ((oKey instanceof Binary) && (oValue instanceof Binary))
/*    */     {
/* 37 */       return padMemorySize(SIZE_ENTRY + 2 * SIZE_BINARY + ((Binary)oKey).length() + ((Binary)oValue).length());
/*    */     }
/*    */
/* 43 */     throw new IllegalArgumentException("Unsupported key or value: Key=" + oKey + ", Value=" + oValue);
/*    */   }

cache configuration

  <replicated-scheme>
      <scheme-name>repl-default</scheme-name>
      <service-name>ReplicatedCache</service-name>
      <serializer>
        <class-name>com.tangosol.io.pof.ConfigurablePofContext</class-name>
      </serializer>
      <lease-granularity>member</lease-granularity>
      <backing-map-scheme>
        <local-scheme>
        <unit-calculator>BINARY</unit-calculator>
        </local-scheme>
      </backing-map-scheme>
      <autostart>true</autostart>
    </replicated-scheme>

So the error means either Key or Object is not a Binary type. How comes it is not a Binary? the system controls the internal storage.

how about dumping out the class type of key and the value?

BTrace is my friend then , basically, I want to print out the class of okey/ovalue before the method get called. 

here is the Btrace script

/* BTrace Script Template */

import com.sun.btrace.BTraceUtils;
import com.sun.btrace.annotations.*;
import com.tangosol.net.cache.*;
import static com.sun.btrace.BTraceUtils.*;

@BTrace
public class TracingScript {
    /* put your code here */
    @OnMethod(clazz="com.tangosol.net.cache.BinaryMemoryCalculator",method="calculateUnits",location=@Location(where=Where.BEFORE))
        public static void oncalculateUnits(@Self com.tangosol.net.cache.BinaryMemoryCalculator self,
                Object a, Object b) {
        print("a  ");
        println( a);
        println(  BTraceUtils.classOf(a));
        print("b  ");
        println( b);
        println(  BTraceUtils.classOf(b));
     }
}

then your can trace the cacheserver either by startuping btrace.bat pidofthejvm pathoftrace.java, or using btrace plugin for jvisualvm

as the error implys, it do store the object as the native format instead of the binary format

 

a  98
class java.lang.Integer
b  POFLib.PurchaseOrder@12fc61a
class POFLib.PurchaseOrder
a  99
class java.lang.Integer
b  POFLib.PurchaseOrder@cef65
class POFLib.PurchaseOrder

if I change the cachem schema back to distributed. No error, and the object is stored as Binary format.

a  com.tangosol.util.Binary@153b2cb
class com.tangosol.util.Binary
b  com.tangosol.util.Binary@1ff2e1b
class com.tangosol.util.Binary

C# code

INamedCache cache = CacheFactory.GetCache("repl-customer");
                      PurchaseOrder o = new PurchaseOrder();
                   o.ID = i;
                   o.PMName = "PM" + i;
                    o.PoAmount=rand.Next(50000);
                   cache.Add( i , o);
          

 

conclusion:

  • if you use the replicated cache. the unit-calculator has to be Fixed.
  • Objects is stored in different format. Native vs Binary  for replicated mode and distributed mode
  • if Object is stored in native format, will there be more footprint?
  • replicated mode doesn’t support Index, check the blog here.
 
Locations of visitors to this page