Static Reference/JDBC Bug

Platforms Affected

Internet Explorer's VM (3 & 4) has a problem when a static initializer of a class attempts to use a static method in another class. The VM acts like the static method was never called.

This problem does not occur in IE for Mac or UNIX.

Based on Sybase documentation, this problem also apparantly affects AIX's JDK 1.1.

Details On The Platforms Available

The pattern of calling a static method of a class from within the static initializer of another class is a JDBC pattern.

In other words, this is actually a generic problem with static classes. It is not really a problem with JDBC. However, since JDBC Drivers work this way, I have classified this as a bug associated with JDBC to draw attention to it.

Basically, in JDBC, you load/register a driver by simply referencing the class using the Class.forName() method. This works in all platforms except for IE on Windows.

The Sybase JDBC Documentation states that the registration is occuring but that IE is somehow doing it with a duplicate of the DriverManager class instead of the real copy of the class that gets called from the JVM. Obviously, there should only be one class level instance of a class, so this causes a problem.

The applet below demonstrates the bug by using the Class.forName to load MyStaticDriver class. This class's static initializer attempts to register itself with MyStaticDriverManager using a static method.

This static method (MyStaticDriverManager.register) increments a count variable to keep track of how many registrations it has performed.

On most platforms, the count will be 1 in the Buggy Applet. On IE for windows, the count will remain 0.

Static Reference/JDBC Bug Workaround

There are two workarounds.

First, you can decide not to use this method of initialization if you are writing your own classes.

The second workaround, for JDBC libraries that you do not have source code for, is to register the driver manually.

In JDBC, instead of doing a call like

Class.forName("MyJdbcDriver");

You would do the following:

DriverManager.registerDriver(
  (Driver)Class.forName("MyJdbcDriver").newInstance());

Note, this registers the driver twice on non IE virtual machines, but this really does not cause any real harm to the JDBC DriverManager implementation.

The Workaround Applet shown below the buggy one shows this method in action using MyStaticDriver and MyStaticDriverManager. IE browsers will have a value of 1 and the other browsers will have a value of 2.

References

Sybase JDBC Programmers Documentation

Applet Demonstrating Static Reference/JDBC Bug

View The Source To StaticBug.java
View The Source To MyStaticDriver.java
View The Source To MyStaticDriverManager.java

Applet With Static Reference/JDBC Bug Workaround

View The Source To StaticFix.java
View The Source To MyStaticDriver.java
View The Source To MyStaticDriverManager.java

Gunther Birznieks <gunther@clark.net>