I've been hitting against getCanonicalPath myself recently in the context 
of Cocoon 2 and Tomcat 4 under Mac OS X.

I've taken a look through some of the code of Tomcat and it appears that 
there are opportunities to cut down on calls to getCanonicalPath, but I'm 
conscious that I really am not at all familiar with the code and the 
possible underlying issues.

Here are some examples of bits of code in the current Tomcat source which 
appear open to optimization, perhaps you could comment on whether such 
optimizations would work:

StandardContext.java:

>         if (directory.exists() && directory.canRead() &&
>             directory.isDirectory()) {
>             String filenames[] = directory.list();
>             for (int i = 0; i < filenames.length; i++) {
>                 if (!filenames[i].endsWith(".jar"))
>                     continue;
>                 File file = new File(directory, filenames[i]);
>                 try {
>                     URL url = new URL("file", null, file.getCanonicalPath(
> ));
>                     newLoader.addRepository(url.toString());
>                 } catch (IOException e) {
>                     throw new IllegalArgumentException(e.toString());
>                 }
>             }
>         }

Couldn't we get the Canonical path of the directory and then assume that 
the absolute path of the filenames returned would be Canonical too, 
thereby taking getCanonicalPath out of the loop?

>       // Create this directory if necessary
>       File dir = new File(workDir);
>       if (!dir.isAbsolute()) {
>             File catalinaHome = new 
> File(System.getProperty("catalina.home"));
>             String catalinaHomePath = null;
>             try {
>                 catalinaHomePath = catalinaHome.getCanonicalPath();
>                 dir = new File(catalinaHomePath, workDir);
>             } catch (IOException e) {
>             }
>         }

Isn't getAbsolutePath sufficient here?

Similar issues exist in Bootstrap.java.

HostConfig:

>                 // Deploy the application in this directory
>                 if (debug >= 1)
>                     log(sm.getString("hostConfig.deployDir", files[i]));
>                 try {
>                     URL url = new URL("file", null, dir.getCanonicalPath(
> ));
>                     ((Deployer) host).install(contextPath, url);
>                 } catch (Throwable t) {
>                     log(sm.getString("hostConfig.deployDir.error", files[
> i]),
>                         t);
>                 }

dir is derived using the list method on the appBase variable (not shown on 
listing) which is canonical.  Do we need to use getCanonicalPath here or 
can we just use getAbsolutePath?

Finally, how about having some form of cached getCanonicalPath method 
which returns results from cache for requests for the same file path?  I 
tried replacing the actual getCanonicalPath method in the main Java 
classes with a simple unlimited hashTable and the performance improvements 
running Tomcat and Cocoon were very visible.  Clearly the hash table would 
need to be time and size limited, but are there any other fundamental 
issues with this idea?

Stuart.


On Friday, June 15, 2001, at 10:52  pm, [EMAIL PROTECTED] wrote:

>
> Thanks for the report - if you can think of a patch we can use it for
> 3.2.3. The reloading system has been almost completely rewritten for 3.3,
> with far fewer accesses to the file system.
>
> Have you tried with a different VM ? ( I don't think we can avoid
> getCanonicalPath, is a very useful call and is very important for security
> too )
>
> Costin
>
>
>
>
>
> On Fri, 15 Jun 2001, Brett M. Bergquist wrote:
>
>> I just upgraded or application from Tomcat 3.1 to Tomcat 3.2.2 and
> noticed a dramatic slowdown and increased CPU utilization.  This is on
> WinN  4.0 SP5.  To figure out what was happening, I fired up OptimizeIT
> and  ook a look.  I found that 68% time was being spent in
> "org.apache.tomcat.core.ServletWrapper.handleReload" and of the time
> within this method, 51% of the time was being spent in
> "java.io.File.getCanonicalPath" and of the time spend within this method,
> all of it was spent within "java.io.Win32FileSystem.canonicalize".
>>
>> My question is is this normal and what in the hell is taking so long in
> "java.io.Win32FileSystem.canonacalize"?  Once I disabled class reloading,
> by performance and CPU utilization went back to what was present with
> 3.1.
>>
>> Thanks for any input.
>>
>> Brett M. Bergquist
>> Canoga Perkins Corp.
>>
>


-------------------------------------------------------------------------
Stuart Roebuck, BSc, MBA        Tel.: 0131 228 4853 / Fax.: 0870 054 8322
Managing Director
ADOLOS                                           <http://www.adolos.com/>

Reply via email to