JDK-7103957 : NegativeArraySizeException while initializing class IntegerCache
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.lang
  • Affected Version: 6u26
  • Priority: P5
  • Status: Closed
  • Resolution: Fixed
  • OS: windows_7
  • CPU: x86
  • Submitted: 2011-10-23
  • Updated: 2013-06-26
  • Resolved: 2013-01-10
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7 JDK 8
7u40Fixed 8 b73Fixed
Related Reports
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.6.0_27"
Java(TM) SE Runtime Environment (build 1.6.0_27-b07)
Java HotSpot(TM) 64-Bit Server VM (build 20.2-b06, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]

A DESCRIPTION OF THE PROBLEM :
It is possible to cause a NegativeArraySizeException in the class initializer of java.lang.Integer.IntegerCache by specifying a value for the System property java.lang.Integer.IntegerCache.high greater than or equal to 2147483519 (Integer.MAX_VALUE - -low).

This is because the maximum array size for the cache is computed as:

h = Math.min(i, Integer.MAX_VALUE - -low);

Unfortunately, this does not account for caching Integer 0 for large enough values of the System property as noted above. The correct computation is:

h = Math.min(i, Integer.MAX_VALUE - -low - 1);

For the noted values, the NegativeArraySizeException occurs at the line that allocates the array:

cache = new Integer[(high - low) + 1];

Notice that caching Integer 0 is account for here by adding 1. However, (high - low) + 1 equates to Integer.MAX_VALUE + 1, thus causing overflow and the NegativeArraySizeException.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile the following class:

public class IntegerCacheSizeTest {
    public static void main(String[] args) {
        Integer i = 0; // Any value will do
    }
}

Run the class with any value greater than or equal to 2147483519 for the System property java.lang.Integer.IntegerCache.high. For example:

java -Djava.lang.Integer.IntegerCache.high=2147483519 IntegerCacheSizeTest


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
No error, except perhaps a java.lang.OutOfMemoryError due to the attempted allocation of the cache array with insufficient memory.
ACTUAL -
A stack trace indicating java.lang.NegativeArraySizeException during class initialization of Integer$IntegerCache.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "main" java.lang.ExceptionInInitializerError
        at java.lang.Integer.valueOf(Unknown Source)
        at IntegerCacheSizeTest.main(IntegerCacheSizeTest.java:3)
Caused by: java.lang.NegativeArraySizeException
        at java.lang.Integer$IntegerCache.<clinit>(Unknown Source)
        ... 2 more

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
public class IntegerCacheSizeTest {
    public static void main(String[] args) {
        Integer i = 0; // Any value will do
    }
}

---------- END SOURCE ----------

Comments
The cause of the problem and its solution were both accurately stated in the issue description.
10-01-2013

Attach regression test (not to be committed).
09-01-2013

EVALUATION A very minor correctness problem to address.
09-01-2012