javax.jdo.spi.I18NHelper causes NullPointerException
----------------------------------------------------

         Key: JDO-178
         URL: http://issues.apache.org/jira/browse/JDO-178
     Project: JDO
        Type: Bug
 Environment: Debian GNU/Linux sid
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_02-b09)
Jakarta-Tomcat 5.5.9
KODO JDO 3.3.4
    Reporter: Marcin Owsiany
    Priority: Minor


In the above environment, I encountered exception being thrown on 
JDOHelper.getPersistenceManagerFactory(p) invocation. The exception was a 
tricky one, because .printStackTrace() called on it caused another exception to 
be thrown, forcing me to manually inspect it by iterating on result of 
.getStackTrace().

Anyway, here is what I found after a loooong battle:

On JDOHelper class init, an I18NHelper instance is instantiated. On that 
instantiation, an attempt is made to load a resource bundle, using 
ResourceBundle.getBundle(s, locale, classloader). The classloader is obtained 
by calling (javax.jdo.spi.I18NHelper.class).getClassLoader(). However in my 
case, this getClassLoader() call returned null, which, to my surprise, is fine 
according to J2SE API.
http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Class.html#getClassLoader() 
says that:

    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.

Anyway, when that null is passed to ResourceBundle.getBundle, it throws a 
NullPointerException.

Furthermore, that exception is wrapped in another exception, 
JDOFatalInternalException if I recall correctly, whose superclass' toString() 
uses (surprise, surprise) an I18NHelper instance to get the exception 
description. This makes it impossible to investigate such exception using 
toString() (for example via log4j).

OK, in truth, the above is a simplified version :-) In fact the exception is 
saved for later use by I18NHelper, and makes it to the JDO user only when the 
JDO implementation being used throws another, possibly unrelated, exception 
during its PersistenceManagerFactory instantiation (in my case it was a trial 
kodo version throwing a LicenseException). But the exception thrown by the JDO 
implementation gets lost, and the user only gets a quite unexpected JDO 
exception, which is hard to debug because of the aforementioned attachment of 
the exception to I18NHelper.

Fortunately, the fix is quite easy:

--- javax/jdo/spi/I18NHelper.java       2005-10-06 21:26:17.000000000 +0200
+++ javax/jdo/spi/I18NHelper.java       2005-10-06 21:26:11.000000000 +0200
@@ -114,7 +114,10 @@
         ResourceBundle resourcebundle = (ResourceBundle)bundles.get(s);
         if(resourcebundle == null)
         {
+            if(classloader != null)
             resourcebundle = ResourceBundle.getBundle(s, locale, classloader);
+            else
+                resourcebundle = ResourceBundle.getBundle(s, locale);
             bundles.put(s, resourcebundle);
         }
         return resourcebundle;

This uses another ResourceBundle method if bootstrap classloader is to be used. 
Another way could possibly be to use a thread context classloader before trying 
the system classloader, but that's just my guess (I didn't try if the other 
classloader turns out non-null).

I hope that my convoluted description can be understood. The above patch fixes 
the problem for me.

regards,

Marcin

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira

Reply via email to