Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-6992722

JdbcOdbcDriver.finalize causes NullPointerException

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed
    • Priority: P5
    • Resolution: Future Project
    • Affects Version/s: 6u7
    • Fix Version/s: None
    • Component/s: core-libs
    • Labels:

      Description

      FULL PRODUCT VERSION :
      java version "1.6.0_07"
      Diablo Java(TM) SE Runtime Environment (build 1.6.0_07-b02)
      Diablo Java HotSpot(TM) Client VM (build 10.0-b23, mixed mode, sharing)

      ADDITIONAL OS VERSION INFORMATION :
      FreeBSD fawkes.research.stellent.com 7.1-PRERELEASE FreeBSD 7.1-PRERELEASE #1: Wed Dec 17 13:57:06 CST 2008 ###@###.###:/usr/obj/usr/src/sys/DDB i386

      EXTRA RELEVANT SYSTEM CONFIGURATION :
      Nothing is relevant except for the source file:
      j2se/src/share/classes/sun/jdbc/odbc/JdbcOdbcDriver.java

      A DESCRIPTION OF THE PROBLEM :
      When anyone uses java.sql.DriverManager to register a driver or to enumerate over the drivers, it causes the loading and creation of an instance of sun.jdbc.odbc.JdbcOdbcDriver. However, the static field JdbcOdbcDriver.OdbcApi is not initialized unless JdbcOdbcDriver.initialize() is called (which only happens when calling the methods: getPropertyInfo, connect, or EEconnect). Various places in JdbcOdbcDriver expect that OdbcApi is not null.

      In particular, the JdbcOdbcDriver.finalize() method expects this in its first line:
          if (OdbcApi.getTracer().isTracing ()
      This causes a NullPointerException to occur very repeatably, such as occurs when the JdbcOdbcDriver objects are finalized by the finalizer/garbage-collector.

      At the very least, the finalize() method should check OdbcApi against null before attempting to do tracing, or else the remainder of the finalize() does not get executed and the NPE propagates up. This normally does not cause a problem unless you are running in an IDE environment like Eclipse which allows breakpoints on exceptions (and NullPointerExceptions) or in J2EE environments which report all exceptions (even ones caught by the garbage collection).

      My recommendation is to remove all possibilities of NPEs by either checking all references against null or by enforcing that this field is initialized under every condition (and thus by any constructor or static initializer).

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Use a jdbc driver that does not involve JdbcOdbcDriver (e.g. postgresql's 8.2.508 jdbc driver). When that driver tries to register in DriverManager, at least two JdbcOdbcDriver instances will be created. At some point in the future, one will be finalized and an NPE is produced. To observe this, use Eclipse and enable breakpoints on NullPointerException (caught and uncaught).

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      No NullPointerException should have been generated by the jdbc layers.
      ACTUAL -
      A NullPointerException is generated on line 96 of JdbcOdbcDriver, which is at the "if" conditional which is the first line in JdbcOdbcDriver.finalize().

      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      A stack trace at the time of the NPE:

      java.lang.NullPointerException
        at sun.jdbc.odbc.JdbcOdbcDriver.finalize() line: 96
        at java.lang.ref.Finalizer.invokeFinalizeMethod(Object) line: not available [native method]
        at java.lang.ref.Finalizer.runFinalizer() line: 83
        at java.lang.ref.access$100(Finalizer) line: 14
        at java.lang.ref.Finalizer$FinalizerThread.run() line: 160



      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      Class.forName("org.postgresql.Driver");
      // Do other stuff which causes memory to be consumed and encourages
      // the garbage collector to finalize the JdbcOdbcDriver object.
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Modify JdbcOdbcDriver.finalize() method to start with the following:

      if (OdbcApi != null && OdbcApi.getTracer().isTracing ()) {
      OdbcApi.getTracer().trace ("Driver.finalize");
      }

      // I've added the text "OdbcApi != null &&".

        Attachments

          Activity

            People

            Assignee:
            lancea Lance Andersen
            Reporter:
            ndcosta Nelson Dcosta (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Dates

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: