[jcifs] java.net.MalformedURLException further analysis

Allen, Michael B (RSCH) Michael_B_Allen at ml.com
Thu Dec 12 12:48:31 EST 2002


> -----Original Message-----
> From:	Glass, Eric [SMTP:eric.glass at capitalone.com]
> Sent:	Wednesday, December 11, 2002 8:02 AM
> To:	'andrea.lanza at frameweb.it'; jcifs at lists.samba.org
> Subject:	RE: [jcifs] java.net.MalformedURLException further analysis
> 
> OK, I have figured out what is going on here.
> 
> This should work if you install the jCIFS jar as an extension (move it into
> the "lib/ext" directory under $JAVA_HOME), specify it in your classpath, or
> otherwise make it available to the system classloader.
> 
> When the URL class attempts to find a protocol handler, it first checks the
> cache of loaded handlers.  When no handler is found it then looks to see if
> the installed URLStreamHandlerFactory (if any) can create a handler.  If
> not, it looks to the java.protocol.handler.pkgs property.  This is where
> things start to get relevant to us.
> 
> For each token in the property string, the URL class builds a class name
> <token> + "." + <protocol> + ".Handler" (in our case, "jcifs.smb.Handler").
> It then attempts to obtain the Class object for this class as follows:
> 
> Class cls = null;
> try {
>     cls = Class.forName(clsName);
> } catch (ClassNotFoundException e) {
>     ClassLoader cl = ClassLoader.getSystemClassLoader();
>     if (cl != null) {
>         cls = cl.loadClass(clsName);
>     }
> }
> 
> The main problem here is that the above will (under normal circumstances)
> ONLY load classes from the system class loader;  the first call uses the
> defining class loader of the URL class, which will almost always be the
> system class loader (unless you are have defined the
> "java.system.class.loader" property and changed the default class loader).
> I am not sure if this is a bug in the URL class or intentional; a seemingly
> more useful statement would have been:
> 
> Class cls = null;
> try {
>     cls = Class.forName(clsName);
> } catch (ClassNotFoundException e) {
>     try {
>         ClassLoader threadLoader = Thread.getContextClassLoader();
>         if (threadLoader != null) {
>             cls = threadLoader.loadClass(clsName);
>         }
>     } catch (ClassNotFoundException ignore) {
>         ClassLoader cl = ClassLoader.getSystemClassLoader();
>         if (cl != null) {
>             cls = cl.loadClass(clsName);
>         }
>     }
> }
> 
	Perhaps this does not dovetail with RMI class loading which uses URLs to
	load classes over the network from their java.rmi.server.codebase.

> which would further attempt to load the class using the context classloader
> for the current thread (which is set to the web application classloader by
> Tomcat).
> 
	This is the one thing that I still do not quite understand. A Resin user also
	reported a case just like Andrea's:

	  http://lists.samba.org/pipermail/jcifs/2002-November/002799.html

	So java.net.URL cannot see jcifs.smb.Handler because it is only in the thread
	context classloader?

	This is great work Eric.




More information about the jcifs mailing list