You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@struts.apache.org by "Craig R. McClanahan" <Cr...@eng.sun.com> on 2001/02/13 22:44:19 UTC

Classpaths and the "struts.jar" file

There has been some confusion around the issue of placing "struts.jar"
on your CLASSPATH at execution time, in a servlet container like Tomcat
that makes all such libraries visible to web applications.  This message
is an attempt to clarify the issues, and document why this is
prohibited.

* The "struts.jar" must appear on your classpath at
  compile time for your web application.  The easiest
  way to make this happen is to use an Ant "build.xml"
  file (like Struts itself does) that sets the classpath
  dynamically, or create a custom shell script that sets
  the classpath temporarily for compiling Struts based
  classes.

* The "servlet.jar" file (from your servlet container) must
  be on your classpath at compile time as well, because
  your application's Action classes will refer to interfaces
  that are defined here.

* For reasons discussed further below, "struts.jar" MUST NOT
  be on your system CLASSPATH when you start your servlet
  container (in particular, this applies to Tomcat).

* Placing JAR files in $JAVA_HOME/jre/lib/ext (the system
  extensions directory for Java2) is the same as placing them
  on the classpath.  In other words, you will NOT want to put
  "struts.jar" or "servlet.jar" there.

* For Tomcat, placing JAR files in the "lib" directory (as opposed
  to the WEB-INF/lib directory of your web app) causes them to
  be added to the CLASSPATH automatically.  Therefore, you should
  not put struts.jar here either.

The reason that putting "struts.jar" on your classpath is a bad idea has
to do with the way classloaders work in most servlet containers.  The
details differ between them -- but here is the scoop for Tomcat (3.x and
4.x):

* The library files that are placed on the CLASSPATH when
  Tomcat starts up are made visible through the "system"
  class loader.

* Each individual web application has a custom class loader
  created for it, which makes the classes in WEB-INF/classes
  and WEB-INF/lib visible.  The "parent" class loader of this
  custom class loader is set to the system class loader mentioned
  above.

* When classes are loaded, the JVM starts at the bottom of the
  hierarchy of class loaders, with the webapp class loader, and
  works its way up the hierarchy until it finds that class.  Thus, if
  you have struts.jar in the system classpath, classes from struts.jar
  will be loaded by the system class loader instead of the web app
  class loader.

* When a loaded class references other classes, it looks in its own
  class loader first, and then up the hierarchy.  Under NO circumstances

  will it go down the hierarchy.

* Therefore, if a Struts class is loaded from the system class path,
  that class CANNOT see any of your application classes in
WEB-INF/classes
  or WEB-INF/lib -- you will get ClassNotFoundException instead.

This is the reason that the Struts example application will not run when
you have "struts.jar" on your CLASSPATH.  The digester module of Struts
is loaded from the system class path.  Therefore, it cannot see the
"User" class of the example app, because that class is under
WEB-INF/classes.

If you find that you need to put "struts.jar" on your system classpath
to make Struts work in Tomcat, that means your Tomcat install has been
corrupted.  If you find that your own app will not work UNLESS
struts.jar is in the system classpath, there is something about your
application organization that needs to be analyzed in detail.

Craig