You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by Richard Frazer <Ri...@haht.com> on 2002/07/24 20:50:29 UTC

RE: TLD's in jars don't work (was: RE: Help please: DirContextURL Stre amHandler/Jasper question and possible bug...)

OK, I think that this problem can be solved by making two fixes.

1. In StandardContext, stop unbinding
Thread.currentThread().getContextClassloader from
DirContextURLStreamHandler.
2. In StandardContext, when setting
Thread.currentThread().setContextClassloader, I can save off the current
classloader and restore it as the context classloader when leaving start(),
stop(), and reload().  The WebappClassLoader will then get set gain as the
current context classloader by StandardHostValve.invoke().

If this sounds reasonable to people, I can create a patch and submit it.

Richard

-----Original Message-----
From: Richard Frazer [mailto:Richard.Frazer@haht.com]
Sent: Wednesday, July 24, 2002 1:16 PM
To: 'Tomcat Developers List'
Subject: TLD's in jars don't work (was: RE: Help please:
DirContextURLStre amHandler/Jasper question and possible bug...)


It occurs to me that I didn't explain very well how this problem manifests
itself.  The problem occurs when you have a tld inside a jar file.  Here's
the scenario:

App 1:
1. Request for App1 comes into the server
2. Request is assigned to thread1.
3. App1 is loaded on thread1.
4. Request is processed on thread1

App2:
5. Request for App2 comes into the server
6. Request is assigned to thread1.
7. App2 is loaded on thread1.
8. Request is processed on thread1.

Now, if the request for App2 is for an uncompiled jsp that uses a tld that
is stored in a jar file under WEB-INF/lib, an exception is thrown.  The
exception is thrown from DirContextURLStreamHandler.get().

Here's the top of the stack:

java.lang.IllegalStateException: Illegal class loader binding at
org.apache.naming.resources.DirContextURLStreamHandler.getDirContextURLStrea
mHandler.java:246) 
at
org.apache.naming.resources.DirContextURLStreamHandler.openConnection(DirCon
textURLStreamHandler.java:134) 
at java.net.URL.openConnection(URL.java:938) 
at
sun.net.www.protocol.jar.JarURLConnection.<init>(JarURLConnection.java:64)
at sun.net.www.protocol.jar.Handler.openConnection(Handler.java:24)
at java.net.URL.openConnection(URL.java:938)
at
org.apache.jasper.compiler.TagLibraryInfoImpl.<init>(TagLibraryInfoImpl.java
:209) 
at org.apache.jasper.compiler.Parser.parseTaglibDirective(Parser.java:358)
at org.apache.jasper.compiler.Parser.parseDirective(Parser.java:385)
at org.apache.jasper.compiler.Parser.parseElements(Parser.java:794)
at org.apache.jasper.compiler.Parser.parse(Parser.java:122) 

I would like to fix this problem and submit a patch, but I don't know if the
correct solution is to not have StandardContext.start() for App2 unbind
App1's DirContext, or to bind the DirContext for every request.

Thanks in advance.
Richard

-----Original Message-----
From: Richard Frazer [mailto:Richard.Frazer@haht.com]
Sent: Wednesday, July 24, 2002 12:18 PM
To: Tomcat-Dev (E-mail)
Subject: Help please: DirContextURLStreamHandler/Jasper question and
possi ble bug...


I'm running with Tomcat 4.1 and am seeing the following problem (and have
actually been seeing the problem since 4.0.4):

Jasper relies on the fact that the DirContext is bound in
DirContextURLStreamHandler based on the app classloader.  This is bound when
the StandardContext is started, stopped, or reloaded.  The code in Jasper
that relies on it is the TagLibraryInfoImpl class.  It uses a
JarURLConnection which in turn uses DirContextURLStreamHandler to lookup the
DirContext based on Thread.currentThread().getContextClassloader().

This all works fine as long as the DirContext stays bound to the
DirContextURLStreamHandler for the lifetime of the application. However, the
DirContext gets unbound if another app is started later on on the same
thread as the first app.  If you look in StandardContext.start(), the code
looks like this:

                // Binding thread
                oldCCL = bindThread();
			.
			.
			.
                unbindThread(oldCCL);

The unbindThread method unbinds the DirContext from the
DirContextURLStreamHandler.  Why would the StandardContext.start() method
unbind a classloader from DirContextURLStreamHandler when it doesn't even
know whether it's still in use?

I'm by no means an expert here, so there may be something fairly obvious
that I'm missing.  Please help.

Thanks,
Richard