Bug 56016 - DigesterFactory.idFor(...) assumes that javax.servlet.jsp.resources.** are available from the same class loader that defines javax.servlet.ServletContext
Summary: DigesterFactory.idFor(...) assumes that javax.servlet.jsp.resources.** are av...
Alias: None
Product: Tomcat 6
Classification: Unclassified
Component: Catalina (show other bugs)
Version: unspecified
Hardware: All All
: P2 normal (vote)
Target Milestone: default
Assignee: Tomcat Developers Mailing List
Depends on:
Reported: 2014-01-15 23:51 UTC by Dmitri Bourlatchkov
Modified: 2014-01-17 15:46 UTC (History)
0 users

Patch for DigesterFactory.ifFor(...) method to relax assumptions related to class loading (961 bytes, patch)
2014-01-15 23:51 UTC, Dmitri Bourlatchkov
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Dmitri Bourlatchkov 2014-01-15 23:51:30 UTC
Created attachment 31214 [details]
Patch for DigesterFactory.ifFor(...) method to relax assumptions related to class loading

The idFor(String url) method in org.apache.tomcat.util.descriptor.DigesterFactory appears to try loading resources from the javax.servlet.jsp.resources package using the defining class loader of javax.servlet.ServletContext.

This is perfectly fine for standalone Tomcat, of course. However, in our application we run embedded Tomcat in an isolated class loader, which includes all of Tomcat's jar files _except_ servlet-api.jar. servlet-api.jar is part of the class loader that is a  parent of the class loader for the embedded Tomcat.

Tomcat 7.0.47 worked well in this setup. However in 7.0.50 we hit exceptions like the following:

    at org.apache.catalina.startup.TldConfig.createTldDigester(TldConfig.java:94)
    at org.apache.catalina.startup.TldConfig.init(TldConfig.java:576)
    at org.apache.catalina.startup.TldConfig.lifecycleEvent(TldConfig.java:559)
    at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:119)
    at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90)
    at org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:402)
    at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:110)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:139)
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901)
    at org.apache.catalina.core.ContainerBase.access$000(ContainerBase.java:133)
    at org.apache.catalina.core.ContainerBase$PrivilegedAddChild.run(ContainerBase.java:156)
    at org.apache.catalina.core.ContainerBase$PrivilegedAddChild.run(ContainerBase.java:145)
    at java.security.AccessController.doPrivileged(Native Method)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:875)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:634)
Caused by: java.lang.NullPointerException
    at org.apache.tomcat.util.descriptor.DigesterFactory.idFor(DigesterFactory.java:107)
    at org.apache.tomcat.util.descriptor.DigesterFactory.<clinit>(DigesterFactory.java:59)
    ... 25 more 

The reason why the resource is not found is apparently that the class loader of ServletContext does not 'see' resources from jsp-api.jar.

We can work around that by placing jsp-api.jar into the same class loader that has servlet-api.jar, however this workaround is not ideal from our design perspective.

From the source of the idFor(...) method one could guess that the fallback attempt to find the requested resource in the javax.servlet.jsp.resources package is meant to look in jsp-api.jar. For that reason, would it be appropriate to perform the fallback lookup in the defining class loader of javax.servlet.jsp.JspContext? A patch file for the proposed fix is attached. If it is accepted please credit Juan Carlos Estibariz with it.
Comment 1 Dmitri Bourlatchkov 2014-01-16 00:01:46 UTC
The affected url parameter for the idFor(...) method in this case is "web-jsptaglibrary_1_1.dtd"
Comment 2 Mark Thomas 2014-01-16 19:49:45 UTC
Thsi doe snot affect 8.0.x where all the referenced resources have been moved to the servlet-api.jar

This has been fixed in 7.0.x for 7.0.51 onwards.

This has been proposed for 6.0.x.
Comment 3 Mark Thomas 2014-01-17 15:46:14 UTC
This has been fixed in 6.0.x for 6.0.38 onwards.