Saturday August 10, 2002
Explanation of Tomcat's Class Loader from the Chief Developer of Tomcat and Struts:
> On Fri, 9 Aug 2002, Matt Raible wrote:
>
> Struts Dev Team - please verify my hypothesis below.
>
> I believe the Struts JARs and the DBCP JARs from common should be the
> same. After all, Struts does use the DBCP in it's distribution. You
> might want to upgrade to the latest build of Struts (which includes
> DBCP and Logging, among others). I know they're planning on releasing
> 1.1 Beta 2 this weekend.
>
The story is somewhat convoluted (I *hate* class loaders :-), but it goes
like this:
If you are going to use a JNDI datasource, then both your webapp AND
Tomcat need to see the same copy of the JDBC driver and the dbcp classes
(for 4.1.x) -- and the way to make that happen is to put the driver into
common/lib.
Because commons-dbcp.jar is there, it's dependent jars (such as
commons-collections.jar, jdbc2_0-stdext.jar, and (recently added)
commons-lang.jar) need to be in common/lib as well. Plus, of course,
jndi.jar if you're on a 1.2 system.
Having any of these JARs duplicated inside the webapp causes a problem
in 4.x based systems, because they try to use the local copy first -- and a
copy if foo.bar.MyClass loaded from the webapp is *not* the same class
as a copy of foo.bar.MyClass loaded from common/lib. This is a place where
Tomcat's modified class loader model causes grief (but only because you're
trying to use the same classes that Tomcat internally is trying to use -- if you
were using something like GenericDataSource with your own copy of the
connection pool, it would not be a problem).
One workaround for this would be to try turning off the modified loader
delegation model, by putting something like this in your server.xml file (or in
a context configuration file on Tomcat 4.1.x.):
<Context path="/myapp" ...>
<Loader delegate="false"/>
</Context>
This *should* let you have a copy of all the JAR files inside your webapp,
as well as in common/lib, but not cause any conflicts.
Please let me know, one way or the other, if this works -- it's clearly a
desireable goal that you can ship a WAR file with all the included commons
JARs but not have problems like this. I want to review how Tomcat's default
configuration can make this easier. And, from a Struts application perspective
(not just for Roller), this is a pretty serious usability issue.
> HTH,
>
> Matt
>
Craig McClanahan
PS: In Tomcat 4.1.x, the "deploy" command of the manager app lets you include
a context configuration file in the WAR, at location "META-INF/context.xml". So it
might still be possible to configure a single WAR that works correctly in Tomcat
4.1.x and still works in other servers (that would obviously ignore such a file).
Thanks for the clear and concise definition of how this all works Craig. So basically, in Tomcat 4.x, don't keep duplicates of your JARs in $CATALINA_HOME/common/lib AND in yourApp/WEB-INF/lib, OR turn off the modified loader delegation as specified above. Tomcat 4.1.x looks very cool, I'm just curious to know why they're on a Beta Release of 4.1.8, but still no official release?
Posted in Java
at Aug 10 2002, 12:49:00 AM MDT
Add a Comment
Search This Site
Recent Entries
- Secure JSON Services with Play Scala and SecureSocial
- My What's New in Spring 3.1 Presentation
- Twitter's Open Source Summit: Bootstrap 2.0 Edition
- Refreshing AppFuse's UI with Twitter Bootstrap
- 2011 - A Year in Review
- Upgrading AppFuse to Spring Security 3.1 and Spring 3.1
- What have I been working on at Taleo?
- Our Engaging Trip to Paris and Antwerp
- My HTML5 with Play Scala, CoffeeScript and Jade Presentation from Devoxx 2011
- Deploying Java and Play Framework Apps to the Cloud with James Ward