Search code examples
javajakarta-eecachinghazelcastkryo

Using newString(bytes[]) to store as cache key in hazelcast cache


I have a cache which accepts only string as keys. This cache is a part of a legacy system and I cannot modify them. To use this cache I need to convert my cache keys into string.

To make my cache keys to string am serializing it using KRYO. Converting them to bytes[] and the creating a string out of the bytes[]. Do you see any issues in doing this? am using the below code to convert into bytes[] Getting bytes [] uses Kryo :-

final Kryo kyroInstance = serializerInstance.get();
kyroInstance.writeObject(output, target);
output.getBuffer();

Reading the key as below using KRYO

final Kryo kyroInstance = serializerInstance.get();
Object obj = kyroInstance.readObject(input, type);
return obj;

I have 2 questions here 1. Is this approach looks good to you ? Do you have any other approach for my used case. 2. Am getting errors NPE sometimes while reading the keys in a distributed environment and the issue is specific to KRYO serialization.

java.lang.IndexOutOfBoundsException: Index: 34120126, Size: 0 at
java.util.ArrayList.rangeCheck(ArrayList.java:653) at
java.util.ArrayList.get(ArrayList.java:429) at
com.esotericsoftware.kryo.util.MapReferenceResolver.getReadObject(MapReferenceResolver.java:42)
    at com.esotericsoftware.kryo.Kryo.readReferenceOrNull(Kryo.java:830)
    at com.esotericsoftware.kryo.Kryo.readObject(Kryo.java:680)

Solution

  • As you stated in the comment, you construct the key string by:

    String key =new String(byte[]);
    

    This has the following problems:

    1. To create the String it interprets the input as byte encoded characters. The encoding, or in this case the decoding, that is used, is determined by the default charset setting. Which may change depending on your environment.

    2. Your input is an arbitrary byte stream. Not every byte sequence may be legal in the character encoding. See the methods comments:

    The behavior of this constructor when the given bytes are not valid in the default charset is unspecified.

    1. The encoding implementation may change in future JDK versions. From JDK 7 to JDK 8 the UTF8 encoding implementation changed, see: Java 8 change in UTF-8 decoding

    In short: Stay away from this constructor.

    For your purpose you can use, for example:

    • Arrays.toString(byte[]);
    • Base 64 encoding from Java 8: Base64.Encoder.ecodeToString(byte[])