5

I'm writing tests for my program. Sometimes my tests work, and sometimes they fail. I'm trying to track down all of the sources of nondeterminism.

Here's a simple, self-contained example of my problem:

import java.util.ArrayList;

public class ArrayExceptions {
    public static void main(String[] args) {
        final int ITERATIONS = 10000;
        ArrayList<Integer> list = new ArrayList<>();
        try {
            list.get(-1);
        } catch(ArrayIndexOutOfBoundsException e) {
            e.printStackTrace();
        }
        for(int i = 0; i < ITERATIONS; i++) {
            try{
                list.get(-1);
            } catch (ArrayIndexOutOfBoundsException e) {
                if(e.getMessage() == null) {
                    System.out.println(i);
                    break;
                }
            }
        }
        for(int i = 0; i < 10; i++) {
            try {
                list.get(-1);
            } catch(ArrayIndexOutOfBoundsException e) {
                e.printStackTrace();
            }
        }
    }
}

This program creates an ArrayList. It tries to access element -1 repeatedly. Initially, this creates a detailed backtrace and a message alongside the ArrayIndexOutOfBoundsException. However, if you call it enough times (where 'enough' seems to be about 5500) the thrown exception lacks a backtrace and a message.

The output of this program varies from run to run. Here it exits early, at 5494 iterations:

java.lang.ArrayIndexOutOfBoundsException: -1
    at java.util.ArrayList.elementData(ArrayList.java:418)
    at java.util.ArrayList.get(ArrayList.java:431)
    at ArrayExceptions.main(ArrayExceptions.java:8)
5494
java.lang.ArrayIndexOutOfBoundsException
java.lang.ArrayIndexOutOfBoundsException
java.lang.ArrayIndexOutOfBoundsException
java.lang.ArrayIndexOutOfBoundsException
java.lang.ArrayIndexOutOfBoundsException
java.lang.ArrayIndexOutOfBoundsException
java.lang.ArrayIndexOutOfBoundsException
java.lang.ArrayIndexOutOfBoundsException
java.lang.ArrayIndexOutOfBoundsException
java.lang.ArrayIndexOutOfBoundsException

Here it fails late, at 5540 iterations:

java.lang.ArrayIndexOutOfBoundsException: -1
    at java.util.ArrayList.elementData(ArrayList.java:418)
    at java.util.ArrayList.get(ArrayList.java:431)
    at ArrayExceptions.main(ArrayExceptions.java:8)
5540
java.lang.ArrayIndexOutOfBoundsException
java.lang.ArrayIndexOutOfBoundsException
java.lang.ArrayIndexOutOfBoundsException
java.lang.ArrayIndexOutOfBoundsException
java.lang.ArrayIndexOutOfBoundsException
java.lang.ArrayIndexOutOfBoundsException
java.lang.ArrayIndexOutOfBoundsException
java.lang.ArrayIndexOutOfBoundsException
java.lang.ArrayIndexOutOfBoundsException
java.lang.ArrayIndexOutOfBoundsException

Why's it doing this?

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
Nick ODell
  • 15,465
  • 3
  • 32
  • 66

1 Answers1

6

Nevermind, figured it out.

Pass -XX:-OmitStackTraceInFastThrow as a command line option to the JVM to turn this behavior off. See also NullPointerException stack trace not available without debug agent

Nick ODell
  • 15,465
  • 3
  • 32
  • 66