[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