> From: Christopher Schultz [mailto:ch...@christopherschultz.net] > Subject: Re: tomcat 5.5.25 shared lib and sharing webapp jars > > > From: André Warnier [mailto:a...@ice-sa.com] > > Subject: Re: tomcat 5.5.25 shared lib and sharing webapp jars > > > You must have meant "shared by all webapps". Chuck, you should really > > watch your usage of the terminology here.
Yes, your wording is more better. > > - the Heap is a global structure, managed by the JVM which > > runs Tomcat > > Yes. The heap is not segmented by ClassLoader or anything like that. > The only thing that separates web apps from each other is the ClassLoader > hierarchy. Also, the HotSpot Java heap has several different discrete areas. The two pertinent to this discussion are PermGen and the rest of it (OldGen plus NewGen). There are also other non-Java heaps in the JVM, but they're not really of interest here. > > - webapps create (instantiate) objects by using classes, which are > > pieces of code which (among other things) create objects. Such > > objects are allocated on the Heap. > > - instances (copies) of classes are loaded into JVM memory (where?) > > on an "as-needed" base, for example the first time a webapp invokes > > some piece of code in the class Such a "piece of code" is termed a method. Classes themselves (including static data) are loaded into the PermGen portion of the heap, non-class objects go into the other generations. Methods are not kept in the Java heap. > PermGen is a place where Class objects often end up Not often - always (in a HotSpot JVM); and not "end up" - they are allocated there from the start. Note that PermGen is an attribute of the HotSpot JVM; most other JVMs do not have a PermGen. > I think there's also an Apache commons project that lets you > hand-assemble Java bytecode and stuff it into a running ClassLoader > if you really want to do that. Yup, it's called BCEL - we've used it quite a bit. It's a prime example that classes can be conjured up on the fly, created in any byte array you have handy. Such a byte array must conform to the class format described in the JVM spec - as all class files produced by javac do. > I'm not entirely sure if the JVM remembers the source JAR/.class > file where the class itself came from, but the ClassLoader hierarchy > keeps them separate. The JVM proper is not aware of the source of any class - the relevant API uses a byte array as input. Annotations on the class may carry origin, primarily for debugging purposes. Classloaders usually do keep track of the origin, of course. > > - it would be a bad idea anyway to have abc.jar located in a > > webapp-x/WEB-INF/lib and simultaneously in Tomcat_dir/shared/lib. > > (Why this is a bad idea is not very clear to me if the above holds > > true, but I trust previous communications here saying that it is a > > bad idea) The problem is that an instance of loaderA/class1 cannot be cast to an instance of loaderB/class1 - the qualification by classloader prevents them from being treated as type-compatible. When the same class appears in multiple locations in a particular branch of the classloader hierarchy, it's easy to get that class loaded once for each location. This usually results NoClassDefinitionFound when an attempt is made to use them together. > > - an object always holds a reference to the class it was created from > > Yes! That reference is to an instance of java.lang.Class. > > - a class instance generally does not, but can, keep a reference to > > the objects created from it. Only if static methods in the class choose to do so. The class would have to implement some sort of static factory method to create instances, and prevent any explicit use of a constructor (the "new" operator) by methods outside of the class. > > Class instances which create a singleton object > > perforce keep a reference to it. Highly likely, but that could also be done simply by convention (the user of the class agrees never to create more than one instance). > > - a class instance can be unloaded from memory when > > The webapp itself is irrelevant. A java.lang.Class object (and > therefore any code, static members, etc.) can only be dumped from > memory when the ClassLoader that loaded it is not referenced by > any live object and no live objects are referring to it. That is not true; classes can be unloaded when all instances of the class are unreachable. There's no requirement that the ClassLoader associated with the class not be reachable. You can experiment with the standard system classloader to verify this. > the ClassLoader contains a list of all Classes it ever loaded. That's not actually a requirement, although some classloaders do keep track; in general, classes may be unloaded while the corresponding classloader is still reachable. Each java.lang.Class instance has a reference to its ClassLoader, so the reverse lookup isn't really required. > > - but that class instance could not be unloaded (and maybe > > replaced by another better version) until all objects created by > > it, on behalf of any webapp, have been destroyed. "Created by it" is not quite the right terminology; "instantiated from it" would be better. > > In the practice, this could mean that it is only possible to > > unload and reload this class instance by stopping and restarting > > the entire JVM (and Tomcat). Not necessarily true in all instances, by quite likely. > My recommendation is that if your webapp needs a library in order to > run, you ought to include that library in the WAR file (or exploded WAR > directory structure). Webapps are supposed to be self-contained, so you > can simply deploy a WAR file into an app server. If you first have to > figure out what libraries are missing and install them in a shared > location, you've lost a great amount of convenience. +1 - Chuck THIS COMMUNICATION MAY CONTAIN CONFIDENTIAL AND/OR OTHERWISE PROPRIETARY MATERIAL and is thus for use only by the intended recipient. If you received this in error, please contact the sender and delete the e-mail and its attachments from all computers.