JDK-8080156 : Integer.toString(int value) sometimes throws NPE
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 8u45,9
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2015-05-07
  • Updated: 2017-08-07
  • Resolved: 2015-05-22
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 8 JDK 9
8u60Fixed 9 b69Fixed
Related Reports
Duplicate :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]

A DESCRIPTION OF THE PROBLEM :
Integer.toString(int value) sometimes throws a NullPointerException.  I am not entirely certain what circumstances are required, but the attached source can reproduce the problem quite easily.  Note that other test cases, where I'm not assigning random values, does not seem to reproduce the problem.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile the attached code and run the test.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The test should complete without output.
ACTUAL -
An NPE is often thrown, and the value of the primitive that was attempted to be converted to a String is printed.  The test terminates after the first NPE.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
NPE converting ??? to a String!
Exception in thread "main" java.lang.NullPointerException
        at java.lang.Integer.getChars(Unknown Source)
        at java.lang.Integer.toString(Unknown Source)
        at IntegerToStringNPE.doStuff(IntegerToStringNPE.java:19)
        at IntegerToStringNPE.main(IntegerToStringNPE.java:4)

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
public class IntegerToStringNPE {
    public static void main(String[] args) {
        for (int i = 0; i < 1000000; i++) {
            String a = doStuff();
        }
    }
    
    public static String doStuff() {
        int a = Integer.MIN_VALUE;
        int bounds = (int) (Math.random() * 150);
        for (int i = 0; i < bounds; i++) {
            int random = (int) (Math.random() * 1000);
            if (random > a) {
                a = random;
            }
        }
        
        try {
            return Integer.toString(a);
        } catch (NullPointerException e) {
            System.err.println("NPE converting " + a + " to a String!");
            throw e;
        }
    }
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Wrap the Integer.toString() call in a try/catch block.  If an exception is caught, just make the call again.  This doesn't guarantee that it will work on the second attempt, but it is extremely unlikely to fail.


Comments
Fix verified by regression test.
07-08-2017

Agreed with Vladimir K. to use this bug to push the regression test http://mail.openjdk.java.net/pipermail/hotspot-compiler-dev/2015-May/018057.html
21-05-2015

The problem is wrong type information in C2. At the point where we compute the type of 174 CmpU === _ 173 42 [[ 175 ]] !jvms: ItoaNPE::doStuff @ bci:48 top the values of the other nodes look like this 20 ConI === 0 [[ 156 26 ]] #int:min int:min 141 SubI === _ 230 41 [[ 156 ]] !jvms: ItoaNPE::doStuff @ bci:31 int 156 Phi === 100 141 20 [[ 173 158 ]] #int !jvms: ItoaNPE::doStuff @ bci:25 int:min 172 RShiftI === _ 171 42 [[ 173 ]] !jvms: ItoaNPE::doStuff @ bci:45 int:-1073741824..1073741823:www 173 SubI === _ 172 156 [[ 182 174 ]] !jvms: ItoaNPE::doStuff @ bci:47 int Node "156 Phi" should not have the type "int:min" if the two input nodes have types "int:min" and "int". The problem is that we use type information from two levels above to compute the type of CmpU. Therefore, we should visit the CmpU again if the type of 156 Phi is updated to the right value because otherwise we rely on wrong/incomplete type information. I verified that this is a duplicate of JDK-8060036.
21-05-2015