Jason Collins wrote:

> Auto-reloading is one thing, caching is another. JServ
> caches instances of objects, not just classes, correct?
>
> If this is the case, I can't have the instances being
> cached - my library packages aren't built for it.
>
> (BTW, I do have autoreload.classes=true in my properties file.)
>
> To restate the problem:
>
>   I need a way of having different CLASSPATHs (the "non-caching"
>   kind) for each servlet zone. It sounds as though the only way
>   to do that is to use multiple JServ VMs.
>

It is not real obvious what you mean by "caching" versus "non-caching" class
loaders, or what it means to say your classes library classes are not built
for caching.  On its own behalf, JServ loads the class of a referenced
servlet and creates one or more instances of that servlet (depending on
whether it implements SingleThreadModel or not).  The classes and instances
are all thrown away if a reload is triggered.  Could you please explain this
a little more?

The following is a more in-depth description of how Apache JServ class
loading works.  I will distinguish two possible sources of classes to be
loaded:

* System classes -- those found on the system class path.  If you are using
  automatic JServ starting, this is set up with the "wrapper.classpath"
parameter.
  If you are starting JServ manually, it is the system CLASSPATH that you set

  up for that instance.  Classes loaded from the system classpath (whether
servlet
  or not does not matter) cannot be automatically reloaded without a server
restart.

* Zone classes -- those found on the zone classpath.  This is configured
  by using the "repositories" parameter in the zone properties file.  Classes
loaded
  from the zone classpath can be automatically reloaded if they are modified,
and
  you have set the appropriate autoreload configuration parameter.  Again, it
does
  not matter whether the class in question is a servlet or not.

Let's consider what Apache JServ does if, in your servlet, you execute a
statement like this:

    MyClass myObject = new MyClass(...);

The class loader that is used is the class loader for the zone this servlet
is running in (see below for some implications of this fact).  The following
things happen:

*    Has the "MyClass" class been loaded already by this classloader?

    *    NO:  Search first in the System classpath, and then in
        the Zone classpath, for the "MyClass.class" file to load.

    *    YES:  The existing class is reused.

*    The MyClass class is asked to instantiate a new instance.

Now, what happens when automatic reloading is triggered?

*    All classes loaded from the zone classpath (servlet or not
    does not matter) are thrown away.

*    Therefore, all instances of objects created by those classes
    are also thrown away.  (If they are servlets, destroy() and
    init() are called at the appropriate times).

*    Any classes loaded from the system classpath are *not*
    thrown away (auto-reload is the reason that a custom
    class loader is used at all).

*    Therefore, the instances of objects created from these
    system classes are also not thrown away (although if you've
    only referenced them from servlets, they will ultimately
    get garbage collected).

*    You have total control over whether your classes, and
    instances of objects created from those classes, are reloaded
    or not -- all you have to do is make sure they do or do not
    appear on the system classpath.

As you can see, the key issue is which classpath the class file was found on
(system versus zone).  It makes no difference whether the particular class is
a servlet or not, and also makes no difference whether the class file was
loaded directly from the filesystem, loaded from a remote server, or
extracted from a JAR or ZIP file.

There are a couple of interesting ramificatons of this that are important:

*    Each servlet zone has it's own instance of a custom
    class loader.

*    Classes loaded from the system classpath are shared
    across all zones in the same JVM.

*    Classes loaded from the zone classpath are *not*
    shared between zones, even if it is the same file!

In our scenario above, let's assume that the "MyClass.class" file can be
found on the zone classpath (but not the system classpath) of both zone A and
zone B, and that the statement creating a new object is executed by a servlet
in each of the two zones.  Then, the following facts are true:

*    There are two instances of the MyClass class itself
    (one in each zone's class loader).

*    There are two instances of an object of class MyClass,
    but they are not considered to be of the same class
    (because the underlying classes were loaded by two
    different class loaders).

*    If class MyClass has a static variable in it (which you
    would normally think is global to the entire JVM), it is
    *not* shared with the MyClass object in the other zone.

*    If automatic reloading is triggered in zone A, then
    Zone A's instance of the MyClass object is thrown away --
    but Zone B's instance is *not* thrown away.

*    If you really want things like static variables to be shared
    across zones, you need to make sure that those classes are
    loaded from the system classpath (not the zone classpath),
    and that you maintain references to those objects in some
    system-classpath-loaded object so that they don't get
    garbage collected away.

For most intents and purposes, the use of a separate class loader per zone
gives you a lot of the insulation benefits that running a separate JVM per
zone would give you, but without the extra overhead.  The only downside is
that a JVM crash triggered in one zone will affect all the zones.

Craig




-- --------------------------------------------------------------
To subscribe:        [EMAIL PROTECTED]
To unsubscribe:      [EMAIL PROTECTED]
READ THE FAQ!!!!     <http://java.apache.org/faq/>
Archives and Other:  <http://java.apache.org/main/mail.html/>
Problems?:           [EMAIL PROTECTED]

Reply via email to