cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Craig R. McClanahan" <Craig.McClana...@eng.sun.com>
Subject Re: re loading of classes in tomcat 3.2b4 is _sloooooow_@6
Date Tue, 26 Sep 2000 00:49:47 GMT
See below.

Stefano Mazzocchi wrote:

> Sebastien Sahuc wrote:
> >
> > I'm crossposting the mail to cocoon-dev and tomcat-dev, sorry for the
> > annoyance.
> >
> > "Craig R. McClanahan" wrote :
> >
> > > Sebastien Sahuc wrote:
> >
> > > > Same with Catalina .... :-(
> >
> > > >
> > > > Any hint on why is it so slow to start the Catalina ?
> > > >
> >
> > > I don't remember if 3.2 does this, but Catalina logs when it starts and
> > > stops
> > > initializing the random number generator.  It would be interesting to
> > > find
> > > out if that is the issue or not for you.  By the way, this is done once
> > > per
> > > webapp (they use independent RNGs) so the number of different webapps
> > > you
> > > have defined matters.
> >
> > I have exactly one webapp which is cocoon2. Cocoon2 comes as a big WAR
> > file, and the more a remove -unecessary- jar files from web-inf, the
> > faster is the application startup and smoother is the whole running.
> > I also noticed that having only one Xerces parser (in system classpath)
> > for both cocoon2 webapp and catalina improves notably the average
> > performance and memory footprint...
> > I don't have exact figures but we should start now to be aware of these
> > libraries sharing and Classloader issues.
>
> Oh, yes. Catalina's classloader is much slower compared to the system
> classpath. This is pretty obvious... but this is only at boot time, it
> doesn't make a real difference after you've loaded all the necessary
> classes.
>

But I can see how that would be a pain during development when you're
restarting a webapp all the time.

As it happens, over the weekend I installed a new class loader implementation
that extends the standard Java2 URLClassLoader instead of the home grown
version.  This version is also in the "milestone 1" release.  Could you guys
please try it again with the new one?

NOTE:  This classloader currently implements auto-reload for classes in
WEB-INF/classes -- not for classes inside JAR files in WEB-INF/lib.  This will
be fixed later, but should not normally be a problem in a development
environment, since most people won't waste the time to continually create JAR
files as they are modifying classes.

> As for memory footprint, this is pretty obvious, but it could lead to
> potential security problems.
>
> Craig, shouldn't we have a "safe" mode and a "normal" mode for
> classloading?
>

Webapp class loaders is one of the issues that was discussed quite a bit for
servlet 2.3.  It's worth reviewing a little background info to bring people up
to date.

The current Catalina classloading strategy is to create the following kinds of
classloaders at startup time:

* The JVM (at least the Sun one) itself sets up the bootstrap
  class loader with the contents of $JAVA_HOME/jre/lib/ext
  (the system extensions you have installed) plus its own
  basic runtime classes.

* The system class loader is configured to contain the
  $CATALINA_HOME/bin/bootstrap.jar file, plus all the
  jars in $CATALINA_HOME/lib.  Any CLASSPATH
  variable that the user currently has set is totally
  ignored (I'm negotiable on this, but I'm really tired of all
  the user problems related to class paths).  The JAR files
  here should be the ones required by more than one webapp.
  The parent of this class loader is the bootstrap class loader.

* The Catalina class loader contains all of the implementation
  classes of Catalina itself, and libraries it needs.  This is created
  automatically from the jar files in $CATALINA_HOME/server.
  These classes are *not* exposed to webapps.

* The webapp class loader (one per webapp) is configured from
  the WEB-INF/classes and WEB-INF/lib/*.jar contents of this
  webapp.  It's parent class loader is the system class loader
  (see above).

One of the big issues with any sort of "shared library" approach is, what do
you do when the same class appears in both the webapp class loader and the
system class loader?  Which one wins?

In Tomcat 3.x (<= 3.2 at least), the webapp classloader follows the standard
Java2 delegation model, and always goes to the parent first (i.e. the system
classpath), and then in the webapp.  If you've got the same class both places
(like an XML parser or a JDBC driver), the one on the system classpath wins.
By the way, this is what caused so much grief in Tomcat 3.1 with people trying
to run their own parsers that had some classes in common with the "xml.jar"
parser shipped with 3.1.

In Tomcat 4.0, Catalina by default follows the new search order articulated as
a "recommendation" in the servlet 2.3 draft spec:
* WEB-INF/classes
* WEB-INF/lib/*.jar
* System class loader
so that a library found in the webapp will always win.  This can be configured
out (although not very gracefully at the moment), but seems to meet the
majority of use cases better than the previous scheme.

>
> > So the first question would be : when an application share common library
> > (say DOM and sax packages), what are the benefits of delivering the war
> > Webapp file with the web-inf/lib conataining the duplicated library (for
> > cocoon the shared libraries are Xerces (since catalina can works with
> > it), tools.jar (which is 4mg big!), jndi.jar, etc ...)
>
> The first and basic advantage is ease of installation. Drag your war
> file and you're done.
>
> The second advantage is complete separation: no problem with class cast
> exceptions and all that since the web-inf/lib takes precedence (I like
> this very much)
>

The third advantage is that some libraries will not work correctly unless they
are installed in the webapp.  I believe Cocoon has run into this -- I'll
describe what I ran into with Struts because it's similar.

Struts includes a module called Digester (very similar to the XmlMapper that is
used inside Tomcat to configure itself from the server.xml and web.xml files).
One of the things you can do is create a new object when a particular XML
element is encountered.  But, if the digester classes are loaded from the
system class path, and the Java class of the object you're trying to create is
in the webapp (a very typical case), you're out of luck --
ClassNotFoundException because the Digester tries to use the classloader it was
itself loaded from (i.e. system class loader).

So, even though reducing the memory footprint (by sharing libraries) is very
appealing, it is not always going to be practical.


>
> --
> Stefano Mazzocchi      One must still have chaos in oneself to be
>                           able to give birth to a dancing star.
> <stefano@apache.org>                             Friedrich Nietzsche
> --------------------------------------------------------------------
>  Missed us in Orlando? Make it up with ApacheCON Europe in London!
> ------------------------- http://ApacheCon.Com ---------------------
>

Craig

====================
See you at ApacheCon Europe <http://www.apachecon.com>!
Session VS01 (23-Oct 13h00-17h00):  Sun Technical Briefing
Session T06  (24-Oct 14h00-15h00):  Migrating Apache JServ
                                    Applications to Tomcat



Mime
View raw message