Details
Backports
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8018667 | 7u45 | Mandy Chung | P5 | Closed | Fixed | b01 |
JDK-8007368 | 7u40 | Dmeetry Degrave | P5 | Closed | Fixed | b22 |
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 ----------
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 ----------
Attachments
Issue Links
- backported by
-
JDK-8007368 NegativeArraySizeException while initializing class IntegerCache
- Closed
-
JDK-8018667 NegativeArraySizeException while initializing class IntegerCache
- Closed
- relates to
-
JDK-6807702 Integer.valueOf cache should be configurable
- Resolved