Skip to Content.
Sympa Menu

mace-opensaml-users - Re: [OpenSAML] XMLConfigirator: Bug respecting JDK 1.6?

Subject: OpenSAML user discussion

List archive

Re: [OpenSAML] XMLConfigirator: Bug respecting JDK 1.6?


Chronological Thread 
  • From: Brent Putman <>
  • To:
  • Cc: Xiang Yang <>
  • Subject: Re: [OpenSAML] XMLConfigirator: Bug respecting JDK 1.6?
  • Date: Fri, 21 May 2010 15:18:03 -0400



On 5/21/2010 3:32 AM, Xiang Yang wrote:
> ------------------
>
> This works fine if I run it directly, for example in Eclipse. However,
> if I run it as a tomcat webapp I got following exception:
> ---------------------------
> DEBUG - 2010-05-21 01:01:47:615
> [org.opensaml.xml.XMLConfigurator#initializeObjectProviders:230] ::
> Initializing object provider {urn:dynfed:protocol}TDSRequest
> ERROR - 2010-05-21 01:01:47:617
> [org.opensaml.xml.XMLConfigurator#createClassInstance:358] :: Can not
> create instance of de.mpg.dynfed.core.TDSRequestBuilder
> java.lang.ClassNotFoundException: de.mpg.dynfed.core.TDSRequestBuilder
>
>



This is almost certainly an issue with the differences in classloader
environments between Eclipse and Tomcat. Tomcat's is hierarchical:

http://tomcat.apache.org/tomcat-6.0-doc/class-loader-howto.html


Do you have the OpenSAML jar files placed in Tomcat's "common"
classloader directory (or in another Tomcat classloader), rather than in
you webapp's war/directory? And your new XMLObject implementations in
your webapp war/directory? If so, that would account for the problem.
More below. But the solution is to place the OpenSAML jars in your
webapp, and only your webapp.



> I found two bug reports at sun:
> http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6500212
>
> http://bugs.sun.com/view_bug.do?bug_id=6434149
>


I don't believe these have anything to do with your problem. They are
referring to issues specifically with reflection and how it works with
arrays. Not the case here.


> It says following:
> -------------------------
> Generally speaking reflective loading of a class by name should be
> accomplished by using this static method in java.lang.Class:
>
> public static Class<?> forName(String name, boolean initialize,
> ClassLoader loader)
> throws ClassNotFoundException
>
> The ClassLoader.loadClass() method is more typically used for class loader
> delegation.
> Invocation of Class.forName() may eventually invoke ClassLoader.loadClass()
> after handling
> VM name resolution. In particular, for array classes, this would involve
> loading the array's
> component type.
> Thus, we highly recommend replacement of this code:
>
> myClassLoader.loadClass(className);
>
> With this code:
>
> Class.forName(className,false,myClassLoader);
>
>


Where does it say this? Some official Java docs, or the opinion of some
particular person on a forum? I don't think this is a "universal"
recommendation. These methods behave in certain ways and you pick the
right one for your needs.


I had to refresh my memory, there are differences between the 2
approaches above. In general the single-arg Class.forName(className) is
considered by many to be bad, because it uses the caller's classloader.
The 3-arg is not as bad, since you specify the Classloader explicitly.
One main practical difference between the
Classloader.loadClass(className) and Class.forName(className) modulo
potentially different Classloader's being used (depending on the
caller), is that the Class.forName results in Class being initialized
during the call, as where Classloader.loadClass is not; the Class will
be initialized later when it is first used. The 3-arg forName also lets
you specify the class initialization explicitly.


Not sure if we had a conscious reason for choosing one over the other.
But the main issue here is which Classloader is chosen to be used in
XMLConfigurator. See below.



> -----------------------------
>
> Can that the reason of the ClassNotFoundException I got? The
> XMLConfigurator uses exatly the loadClass method:
> ---------
>
> 353 ClassLoader classLoader = this.getClass().getClassLoader();
> 354 Class clazz = classLoader.loadClass(className);
> 355 Constructor constructor = clazz.getConstructor();
> ------------
>
> But why is its behavior different in tomcat environment than in Eclipse?



If your OpenSAML is in Tomcat's common classloader (or any classloader
hierarchically) above your web app, and your XMLObject classes are in
your webapp's classloader, then what happens is: The XMLConfigurator
class is loaded in the Tomcat common classloader. The classloader used
above to load the XMLObject config is the XMLConfigurator's classloader
(via this.getClass().getClassLoader()). Class resolution in
classloaders only goes up, never down (e.g. looks in its parent
classloader, never its children's classloaders). So the classes in your
webapp aren't visible to it.

If you put your XMLObject classes in the same classloader of the
XMLConfigurator (or a parent classloader, not that it probably makes
sense), then it would work.

Now arguably, perhaps, we should instead use in the XMLConfigurator the
current Thread's context classloader, rather than the XMLConfigurator's
classloader, which would avoid problems like this. I can't think of any
downsides off-hand, but there may be some. Not sure if we did it this
way for some conscious reason. But in general I'd say we (perhaps
implicitly) assume that you will locate the OpenSAML jars in the same
classloader as the app code that will be using it.



> And why it affects every class of
> mine but in the sun bug report only array class is mentioned? Confusing ....
>


Like I said, those bug reports are for that specific case with arrays,
and don't I believe have anything to do with your problem.



> By the way, I have following java and tomcat environment:
> java:
> java version "1.6.0_18"
> OpenJDK Runtime Environment (IcedTea6 1.8) (6b18-1.8-0ubuntu1)
> OpenJDK Client VM (build 14.0-b16, mixed mode, sharing)
>


And of course if you're running OpenJDK, then bug reports against
behavior of the Sun JDK are probably not relevant, at least not
something that specific. Only if it's part of the Java spec itself.




Archive powered by MHonArc 2.6.16.

Top of Page