I was trying to use a Java Record Typed key for an Apache Ignite Cache & got the below error.
Anyone else tried using record types & seen this?
Does this mean custom handling of marshalling is needed when using record types? I am using Java 17.0.12 (openjdk version "17.0.12" 2024-07-16) & Gridgain ignite 8.8.39.
java.lang.UnsupportedOperationException: can't get field offset on a record class: private final long *...TestIgniteCache$TestKey.ttlInMillis at jdk.unsupported/sun.misc.Unsafe.objectFieldOffset(Unknown Source) at org.apache.ignite.internal.util.GridUnsafe.objectFieldOffset(GridUnsafe.java:1193) at org.apache.ignite.internal.binary.BinaryFieldAccessor$AbstractPrimitiveAccessor.(BinaryFieldAccessor.java:223) at org.apache.ignite.internal.binary.BinaryFieldAccessor$LongPrimitiveAccessor.(BinaryFieldAccessor.java:387) at org.apache.ignite.internal.binary.BinaryFieldAccessor.create(BinaryFieldAccessor.java:75) at org.apache.ignite.internal.binary.BinaryClassDescriptor.(BinaryClassDescriptor.java:368) at org.apache.ignite.internal.binary.BinaryClassDescriptor.(BinaryClassDescriptor.java:155) at org.apache.ignite.internal.binary.BinaryContext.createDescriptorForClass(BinaryContext.java:648) at org.apache.ignite.internal.binary.BinaryContext.descriptorForClass(BinaryContext.java:606) at org.apache.ignite.internal.binary.BinaryWriterExImpl.marshal0(BinaryWriterExImpl.java:181) at org.apache.ignite.internal.binary.BinaryWriterExImpl.marshal(BinaryWriterExImpl.java:164) at org.apache.ignite.internal.binary.BinaryWriterExImpl.marshal(BinaryWriterExImpl.java:151) at org.apache.ignite.internal.binary.GridBinaryMarshaller.marshal(GridBinaryMarshaller.java:250) at org.apache.ignite.internal.processors.cache.binary.CacheObjectBinaryProcessorImpl.marshalToBinary(CacheObjectBinaryProcessorImpl.java:506) at org.apache.ignite.internal.processors.cache.binary.CacheObjectBinaryProcessorImpl.toBinary(CacheObjectBinaryProcessorImpl.java:1360) at org.apache.ignite.internal.processors.cache.binary.CacheObjectBinaryProcessorImpl.toCacheKeyObject(CacheObjectBinaryProcessorImpl.java:1137) at org.apache.ignite.internal.processors.cache.GridCacheContext.toCacheKeyObject(GridCacheContext.java:1841) at org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicCache$12.apply(GridDhtAtomicCache.java:476) at org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicCache$12.apply(GridDhtAtomicCache.java:474) at org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicCache.asyncOp(GridDhtAtomicCache.java:766) at org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicCache.getAsync(GridDhtAtomicCache.java:474) at org.apache.ignite.internal.processors.cache.GridCacheAdapter.get0(GridCacheAdapter.java:4376) at org.apache.ignite.internal.processors.cache.GridCacheAdapter.get(GridCacheAdapter.java:4357) at org.apache.ignite.internal.processors.cache.GridCacheAdapter.get(GridCacheAdapter.java:1432) at org.apache.ignite.internal.processors.cache.IgniteCacheProxyImpl.get(IgniteCacheProxyImpl.java:1116) at org.apache.ignite.internal.processors.cache.GatewayProtectedCacheProxy.get(GatewayProtectedCacheProxy.java:637) at ..**..cache.TestIgniteCache.get(TestIgniteCache.java:123)
Here is the record typed key class definition:
public static record TestKey<K>(K k, long ttlInMillis) {
// default is 5 minutes for now.
private static final long defaultTTLInMillis = 300000L;
/**
* @param k
* @param ttlInMillis
*
* A key with the specified TTL in Milliseconds
*/
public TestKey {
if (Objects.isNull(k)) {
throw new IllegalArgumentException("Key must not be null!");
}
if (0 >= ttlInMillis) {
throw new IllegalArgumentException("ttlInMillis must not be zero or negative!");
}
}
/**
* @param k
*
* A key that has the default TTL as returned by {@link TestKey#defaultTTLInMillis()}
*
*/
public TestKey (K k) {
this(k, defaultTTLInMillis);
}
/**
* @return the defaultttlinmillis
*/
public static final long defaultTTLInMillis() {
return defaultTTLInMillis;
}
}
Unfortunately, record types are not currently supported out of the box. As you suggest, you'd need a custom marshaller. (The default marshaller instantiates a default object and then sets its properties individually. Records are immutable.)