You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Unfortunately I'm not entirely sure how to make a minimal reproducer for this, so figured I'd drop a bug in case anyone who knows the code spots the issue.
When serializing a sufficiently crazy object graph (Micronaut compile time reflection metadata), some kind of limit gets hit in the optimized generics code and there's an ArrayIndexOutOfBoundsException. I tried to understand the code that's failing but it's a bit arcane:
Caused by: java.lang.ArrayIndexOutOfBoundsException: Index 16 out of bounds for length 16
at com.esotericsoftware.kryo.util.DefaultGenerics.pushTypeVariables(DefaultGenerics.java:127)
at com.esotericsoftware.kryo.serializers.FieldSerializer.pushTypeVariables(FieldSerializer.java:148)
at com.esotericsoftware.kryo.serializers.VersionFieldSerializer.write(VersionFieldSerializer.java:97)
at com.esotericsoftware.kryo.Kryo.writeObject(Kryo.java:642)
at io.micronaut.tasks.impl.kryo.GraphingKryo.writeObject(GraphingKryo.java:314)
at com.esotericsoftware.kryo.serializers.ReflectField.write(ReflectField.java:71)
at com.esotericsoftware.kryo.serializers.VersionFieldSerializer.write(VersionFieldSerializer.java:105)
at com.esotericsoftware.kryo.Kryo.writeObject(Kryo.java:642)
at io.micronaut.tasks.impl.kryo.GraphingKryo.writeObject(GraphingKryo.java:314)
at com.esotericsoftware.kryo.serializers.ReflectField.write(ReflectField.java:71)
at com.esotericsoftware.kryo.serializers.VersionFieldSerializer.write(VersionFieldSerializer.java:105)
at com.esotericsoftware.kryo.Kryo.writeObject(Kryo.java:642)
at io.micronaut.tasks.impl.kryo.GraphingKryo.writeObject(GraphingKryo.java:314)
at com.esotericsoftware.kryo.serializers.ReflectField.write(ReflectField.java:71)
at com.esotericsoftware.kryo.serializers.VersionFieldSerializer.write(VersionFieldSerializer.java:105)
at com.esotericsoftware.kryo.Kryo.writeObject(Kryo.java:627)
Turning off optimized generics is a functioning workaround. The failure happens here:
@OverridepublicintpushTypeVariables (GenericsHierarchyhierarchy, GenericType[] args) {
// Do not store type variables if hierarchy is empty, or we do not have arguments for all root parameters, or we have more// arguments than the hierarchy has parameters.if (hierarchy.total == 0 || hierarchy.rootTotal > args.length || args.length > hierarchy.counts.length) return0;
intstartSize = this.argumentsSize;
// Ensure arguments capacity.intsizeNeeded = startSize + hierarchy.total;
if (sizeNeeded > arguments.length) {
Type[] newArray = newType[Math.max(sizeNeeded, arguments.length << 1)];
System.arraycopy(arguments, 0, newArray, 0, startSize);
arguments = newArray;
}
// Resolve and store the type arguments.int[] counts = hierarchy.counts;
TypeVariable[] params = hierarchy.parameters;
for (inti = 0, p = 0, n = args.length; i < n; i++) {
GenericTypearg = args[i];
Classresolved = arg.resolve(this);
if (resolved == null) continue;
intcount = counts[i];
if (arg == null)
p += count;
else {
for (intnn = p + count; p < nn; p++) {
arguments[argumentsSize] = params[p]; /// <--- crash herearguments[argumentsSize + 1] = resolved;
argumentsSize += 2;
}
}
}
returnargumentsSize - startSize;
}
From a bit of debugging, the issue is that sizeNeeded seems to be calculated wrong. There are two iterations of the outer for loop, but after the first the array is full and argumentsSize points off the end. My guess is that the test suite doesn't exercise the case where the arguments array gets so full it needs to be expanded, because normal object graphs never encounter it. But I'm not sure. The for loops are structured in a rather confusing way.
The text was updated successfully, but these errors were encountered:
The whole generics optimization code is very complex and used to be quite buggy. We managed to fix almost all edge cases but apparently there are more. I'm afraid I won't be able to fix this without a minimal reproducer.
I'd recommend that you simply keep generics optimization turned off. Serialization should be faster but your serialized size will increase a bit.
Unfortunately I'm not entirely sure how to make a minimal reproducer for this, so figured I'd drop a bug in case anyone who knows the code spots the issue.
When serializing a sufficiently crazy object graph (Micronaut compile time reflection metadata), some kind of limit gets hit in the optimized generics code and there's an
ArrayIndexOutOfBoundsException
. I tried to understand the code that's failing but it's a bit arcane:Turning off optimized generics is a functioning workaround. The failure happens here:
From a bit of debugging, the issue is that
sizeNeeded
seems to be calculated wrong. There are two iterations of the outer for loop, but after the first the array is full andargumentsSize
points off the end. My guess is that the test suite doesn't exercise the case where the arguments array gets so full it needs to be expanded, because normal object graphs never encounter it. But I'm not sure. The for loops are structured in a rather confusing way.The text was updated successfully, but these errors were encountered: