JDK-6456678 : SQLException throws a NPE, is not thread-safe and is not coherent
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.sql
  • Affected Version: 6
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2006-08-03
  • Updated: 2011-02-16
  • Resolved: 2006-08-25
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 6
6 b98Fixed
Description
FULL PRODUCT VERSION :
java version "1.6.0-rc"
Java(TM) SE Runtime Environment (build 1.6.0-rc-b92)
Java HotSpot(TM) Client VM (build 1.6.0-rc-b92, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [version 5.1.2600]


A DESCRIPTION OF THE PROBLEM :
SQLException has a mechanism to link throwable to a root SQLException
using setNextException().

In mustang, SQLException implements Iterable in order to provide a way
to iterate over next exceptions using a foreach loop.

The current implementation has two major bugs :
  - first a vector that contains next exceptions is lazily ininitalized
    but there is no test againt null in the method iterator().
  - second, in my opinion using a Vector here is a non sense because :
    - next exception are store twice
    - the linked list of exception can be changed without a change
      in the vector.
    - it's not thread-safe, i can iterate over the vector without synchronization.

The solution here is to use the same algorithms as ConcurrentLinkedList,
i.e remove the vector, mark next as volatile, use a CAS to update next,
create a real iterator that iterate by using next.

REGRESSION.  Last worked in version mustang

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
run the test

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
No NPE for the first test,

the second one must print e2 and e3
ACTUAL -
NPE for the first test and the second one only prints e2

ERROR MESSAGES/STACK TRACES THAT OCCUR :
The first test throws a NPE:

Exception in thread "main" java.lang.NullPointerException
	at java.sql.SQLException.iterator(SQLException.java:317)
	at SQLExceptionTest.main(SQLExceptionTest.java:11)

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.sql.SQLException;

public class SQLExceptionTest {
    public static void main(String[] args) {
        // first test
        //new SQLException().iterator();
        
        // second test
        SQLException e1=new SQLException("e1");
        SQLException e2=new SQLException("e2");
        
        SQLException e3=new SQLException("e3");
        e2.setNextException(e3);
        
        e1.setNextException(e2);
        
        for(Throwable t:e1)
          System.out.println(t);
    }
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
No workaround

Comments
SUGGESTED FIX Taken suggested bug fix by Forax. For more details go to url https://jdk-collaboration.dev.java.net/servlets/ProjectForumMessageView?forumID=1463&messageID=14641 A small change though : Iterator start from this exception itself. And it iterate over chain of causes as well. check in logs : Checking in SQLException.java; /m/jws/jdbc4.0/src/java/sql/SQLException.java,v <-- SQLException.java new revision: 1.22; previous revision: 1.21 done
25-08-2006

EVALUATION Contribution forum : https://jdk-collaboration.dev.java.net/servlets/ProjectForumMessageView?forumID=1463&messageID=14641
06-08-2006