-
Notifications
You must be signed in to change notification settings - Fork 1.8k
java.lang.ArrayIndexOutOfBoundsException when using Streams sorting #5902
Description
We are having an issue in our production environment. I have a work around to it, but figured I would submit this to the group, just in case it is an actual bug in OpenJDK.
Has anyone seen this problem?
The following code:
public Object createSomeObject(final Map<Object, Object> map) {
....
....
....
final Set<Object> keySet = map.keySet();
// This is the line of code that is throwing the exception
// We need to sort the keys for a reason. And we are not
// guaranteed to have a SortedMap,
final List<Object> keys = keySet.stream().sorted().collect(Collectors.toList());
....
....
....
}
Is throwing the following exception:
java.lang.ArrayIndexOutOfBoundsException: Index 9 out of bounds for length 9
at java.base/java.util.stream.SortedOps$SizedRefSortingSink.accept(SortedOps.java:369)
at java.base/java.util.Iterator.forEachRemaining(Iterator.java:133)
at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1845)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:682)
at our.name.space.OurClass.createSomeObject(....)
I can not reproduce this in a test. And, because our production environment can have different types of Map objects with different types of keys; I am not sure which type of Map, or key, is being passed in the method.
With that said, I am pretty sure streams should not be throwing ArrayIndexOutOfBoundsException. Part of the reason for streams is not have to worry about this type of issue.
Also, there is no concurrency issues. Usually, you get a ConcurrentModificationException when a collection is modified by 2 different threads, at least we do.
I switched the code to what’s below and it works fine.
....
....
....
final Set<?> keySet = map.keySet();
final List<Object> keys = new ArrayList<>(keySet);
keys.sort((o1, o2) -> {
if (o1 == null && o2 == null) {
return 0;
} else if (o1 != null && o2 == null) {
return 1;
} else if (o1 == null) {
return -1;
} else if (o1 instanceof final String string1 && o2 instanceof final String string2) {
return string1.compareTo(string2);
} else if (o1 instanceof final String string1) {
final String string2 = o2.toString();
return string1.compareTo(string2);
} else if (o2 instanceof final String string2) {
final String string1 = o1.toString();
return string1.compareTo(string2);
}
final String string1 = o1.toString();
final String string2 = o2.toString();
return string1.compareTo(string2);
});
....
....
....
Using the List.sort() works, but sorting via Streams didn’t. This is an odd one.
My environment:
GraalVM version 22.2.0
CE or EE: CE
JDK version: JDK17
OS and OS Version: CentOS Linux release 7.9.2009
Architecture: amd64
$ java -version
openjdk version "17.0.4" 2022-07-19
OpenJDK Runtime Environment GraalVM CE 22.2.0 (build 17.0.4+8-jvmci-22.2-b06)
OpenJDK 64-Bit Server VM GraalVM CE 22.2.0 (build 17.0.4+8-jvmci-22.2-b06, mixed mode, sharing)
$ java -Xinternalversion
OpenJDK 64-Bit Server VM (17.0.4+8-jvmci-22.2-b06) for linux-amd64 JRE (17.0.4+8-jvmci-22.2-b06), built on Jul 20 2022 18:51:07 by "buildslave" with gcc 10.3.0