In the course of fixing a problem I was having getting Apache Cocoon to run, I came
across a bug in Java in the File.toURL() method. This fault, combined with the use of
the URLClassLoader resulted in a classloading issue.
As a result of finding this bug I thought I would check through the Tomcat 4
sourcecode and see if there may be the potential for a similar problem.
Consequently I have found a few points in the code which may be at risk:
catalina/src/share/org/apache/catalina/startup/Bootstrap.java:172: URL
url = new URL("file", null, file.getAbsolutePath());
catalina/src/share/org/apache/catalina/startup/Bootstrap.java:204: URL
url = new URL("file", null,
catalina/src/share/org/apache/catalina/startup/Bootstrap.java:228: URL
url = new URL("file", null, file.getAbsolutePath());
catalina/src/share/org/apache/catalina/startup/Bootstrap.java:269: URL
url = new URL("file", null, file.getAbsolutePath());
catalina/src/share/org/apache/catalina/startup/ContextConfig.java:841:
workURL = new URL("file", null, workDir.getAbsolutePath());
catalina/src/share/org/apache/catalina/startup/HostConfig.java:293:
URL url = new URL("file", null, dir.getAbsolutePath());
catalina/src/share/org/apache/catalina/startup/HostConfig.java:316:
URL url = new URL("file", null, dir.getAbsolutePath());
tester/src/tester/org/apache/tester/TestClient.java:299: URL url = new
URL("http", host, port, request);
In particular the Bootstrap.java file makes a number of calls for classloader
purposes, which could be suffering the same problems as cocoon was.
Now the detail:
The three and four parameter constructors for java.net.URL do *not* normalize
(canonicalize?) filepaths when they generate a URL instance. All other URL
constructors do. So:
new URL("file:/Users/stuart/Documents/../temp/").toString() =
"file:/Users/stuart/temp/"
but
new URL("file", null, "/Users/stuart/Documents/../temp/").toString() =
"file:/Users/stuart/Documents/../temp/"
Presumably one of these versions of the URL constructor is used by
java.io.File.toURL() which also demonstrates the same symptom.
Finally, File.getAbsolutePath() does not normalize the pathname.
File.getCanonicalPath() does, and therefore returns an absolute path at the same time.
The URLClassLoader requires normalized URLs. If you add two identical non-normalized
URLs to a URLClassLoader it accepts them both as different. If you add two identical
normalized URLs, getURLs() returns a single entry. These problems can manifest
themselves in a failure to load requested classes.
In a number of places in Bootstrap.jar it appears that the three parameter form of the
URL() constructor is being used with a non-normalized absolute path parameter. I am
not familiar with the code to be absolutely sure, but I thing these should be changed
so that all the getAbsolutePath() calls are replaced by getCanonicalPath().
I hope this is helpful, please contact me if you require further information.
Stuart.
-------------------------------------------------------------------------
Stuart Roebuck [EMAIL PROTECTED]
Lead Developer Mac OS X, Java, XML, etc.
ADOLOS http://www.adolos.com/