1

I am migrating my java application from JDK8 to JDK11 but during migration one of my test is failing in java11. It is throwing Index -1 out of bounds for length 3 but this test is passing with JDK8.

According to ArrayIndexOutOfBoundsException java documentation nothing is changed in Java 8 and Java11 but still this test is failing. According to documentation if the index is negative number then program will throw ArrayIndexOutOfBoundsException. So for Java8 it is throwing ArrayIndexOutOfBoundsException and test is passing. In Java11 it is throwing IndexOutOfBoundsException instead of ArrayIndexOutOfBoundsException and failing my test. Attaching my stack-trace below:

Index -1 out of bounds for length 3
java.lang.IndexOutOfBoundsException: Index -1 out of bounds for length 3
at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64)
at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:70)

Any help in this regard will be appreciated.

Mutahir Kiani
  • 83
  • 1
  • 1
  • 11

1 Answers1

2

Change your test method to check for IndexOutOfBoundsException.

From the documentation of the List.get method:

Returns the element at the specified position in this list.

Parameters:
index - index of the element to return

Returns:
the element at the specified position in this list

Throws:
IndexOutOfBoundsException - if the index is out of range (index < 0 || index >= size())

Nowhere does the documentation mention ArrayIndexOutOfBoundsException. (The documentation is exactly the same for Java 8.)

The documentation states that callers can safely assume that the method will throw IndexOutOfBoundsException, or some subclass of it, if the argument is negative or out of range. There has never been any guarantee that any particular subclass of IndexOutOfBoundsException would be thrown.

You observed one particular version of Java throwing a subclass of IndexOutOfBoundsException, and you incorrectly assumed that you could rely on the method throwing that subclass. But that was never a safe assumption, because the method’s contract never promised that. ArrayList (like all implementations of List) was always free to change exactly which subclass of IndexOutOfBoundsException, if any, was thrown.

If you want your code to be guaranteed to work with future versions of Java, do not assume anything that isn’t in the official documentation.

Side note: You should remove the try/catch from your unit test, and annotate the method with @Test(expected = IndexOutOfBoundsException.class). This allows the test report to show the underlying error, and it will make your test method shorter and cleaner.

VGR
  • 40,506
  • 4
  • 48
  • 63