com.mysql.jdbc.Messages static ctor bug report and fix
Posted by: Jason Winnebeck
Date: January 11, 2005 10:19AM

There are actually two problems in the com.mysql.jdbc.Messages static constructor for Connector/J 3.1.6 that I downloaded from the MySQL site 1/7/05.

com.mysql.jdbc.Messages class fails to load because of null pointer exception in some JVMs.

Occurs in: 3.1.6
Does not occur in: 3.0.11

First problem:
static constructor catch clause crashes for any exception thrown.
Util.stackTraceToString calls static method Message.getString. As the Message class is not yet initialized, RESOURCE_BUNDLE is null, and NPE is thrown in the exception handler.
Solution: Do not call Util.stackTraceToString, and instead do the work directly in catch handler for Throwable.

Second problem:
ResourceBundle.getBundle(BUNDLE_NAME, Locale.getDefault(), Messages.class.getClassLoader()); throws NullPointerException on some JVMs.
Contract for getBundle specifies that none of the three parameters may be null, and getBundle will throw NPE if any of them are. This does occur. Contract for Class.getClassLoader() says that it may return null: javadoc: "Some implementations may use null to represent the bootstrap class loader. This method will return null in such implementations if this class was loaded by the bootstrap class loader."
This is true for my JVM. I am using Sun's CVM, the reference implementation for Java CDC 1.1 (compatible with Java 1.3), as I am running in an embedded environment.
There is no need to pass the "default" for the last two parameters. Although the documentation for ResourceBundle says: "Calling this method is equivalent to calling getBundle(baseName, Locale.getDefault(), this.getClass().getClassLoader())", this is not technically correct for when the class loader is null. Fortunately, the code for ResourceBundle handles this pedantic case. The solution then is to call the one-parameter version of getBundle.

Code changes:
Remove import for Util.
Add imports:

Change code for static constructor to:
static {
try {
RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME);
} catch (Throwable t) {
//We can't use Util.stackTraceToString because it
//calls Messages.getString which uses RESOURCE_BUNDLE.
StringWriter out = new StringWriter();
PrintWriter printOut = new PrintWriter(out);
throw new RuntimeException("Can't load resource bundle due to underlying exception " + t.toString() + "\n\nStack Trace:\n\n" + out);

Having never seen the MySQL Connector/J code before, I nievely tried to implement a good alternative for Util.stackTraceToString in the catch block. A Connector/J developer might want to tweak the code here.

Options: ReplyQuote

Written By
com.mysql.jdbc.Messages static ctor bug report and fix
January 11, 2005 10:19AM

Sorry, you can't reply to this topic. It has been closed.

Content reproduced on this site is the property of the respective copyright holders. It is not reviewed in advance by Oracle and does not necessarily represent the opinion of Oracle or any other party.