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]