United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6527572 (cs) Charset.forName can throw NullPointerException when testing bug level
JDK-6527572 : (cs) Charset.forName can throw NullPointerException when testing bug level

Details
Type:
Bug
Submit Date:
2007-02-22
Status:
Closed
Updated Date:
2011-05-17
Project Name:
JDK
Resolved Date:
2011-05-17
Component:
core-libs
OS:
linux,generic
Sub-Component:
java.nio
CPU:
x86,generic
Priority:
P3
Resolution:
Fixed
Affected Versions:
5.0
Fixed Versions:

Related Reports
Backport:
Backport:
Backport:
Backport:
Relates:

Sub Tasks

Description
A licensee has observed that Charset.forName may throw NullPointerException if several threads attempt to test the bug level property at the same time. The issue is the same as the NullPointerException with Selector.open that was fixed in jdk7 as 6427854.

                                    

Comments
SUGGESTED FIX

------- Charset.java -------
*** /tmp/sccs.FhaqDt	Thu Feb 22 17:51:08 2007
--- Charset.java	Thu Feb 22 17:40:52 2007
***************
*** 243,249 ****
  
      /* -- Static methods -- */
  
!     private static String bugLevel = null;
  
      static boolean atBugLevel(String bl) {		// package-private
  	if (bugLevel == null) {
--- 243,249 ----
  
      /* -- Static methods -- */
  
!     private static volatile String bugLevel = null;
  
      static boolean atBugLevel(String bl) {		// package-private
  	if (bugLevel == null) {
***************
*** 251,261 ****
  		return false;
  	    java.security.PrivilegedAction pa =
  		new GetPropertyAction("sun.nio.cs.bugLevel");
! 	    bugLevel = (String)AccessController.doPrivileged(pa);
! 	    if (bugLevel == null)
! 		bugLevel = "";
  	}
! 	return (bugLevel != null) && bugLevel.equals(bl);
      }
  
      /**
--- 251,260 ----
  		return false;
  	    java.security.PrivilegedAction pa =
  		new GetPropertyAction("sun.nio.cs.bugLevel");
! 	    String value = (String)AccessController.doPrivileged(pa);
! 	    bugLevel = (value != null) ? value : "";
  	}
! 	return bugLevel.equals(bl);
      }
  
      /**
                                     
2007-02-22
EVALUATION

Race condition and a data race in Charset's atBugLevel method.
                                     
2007-02-22
SUGGESTED FIX

I suggest using 

private static final String bugLevel = ...

to ensure static initialization.  There is no point to lazy initialization;
it seems that atBugLevel will certainly be called in every Java program.

Martin
                                     
2007-03-02
SUGGESTED FIX

Of course, my previous comment is completely wrong,
because initialization of "bugLevel" has to be delayed until after
System property infrastructure has been set up.

I agree with the suggested fix.... except that....

I think we can get away without a "volatile" on this variable.
This is skating on thin ice, but appears to be safe here because:
- redundant initialization of "bugLevel" is harmless
- String is one of the very few classes that is race-safe.  That is,
  if multiple threads access a String, even in the presence of a data race,
  they are guaranteed to see the same value.
                                     
2007-12-13
EVALUATION

http://hg.openjdk.java.net/jdk7/build/jdk/rev/01b6d147db50
                                     
2010-12-25



Hardware and Software, Engineered to Work Together