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?