You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Gerwood Stewart <gs...@une.edu.au> on 2009/11/09 22:57:46 UTC

WebappClassLoader and undeploy

I originally started down this path trying to find a memory leak (involving commons-logging etc). I now have a more general question:

I've created an almost empty context. It contains 1 servlet which contains an arraylist (just to create a large object that is easier to see in memory graphs) and a default jsp page (as created by the maven webapp archetype).

I deploy this along with the tomcat manager into tomcat 5.5.28, which is the standard tar.gz download with all the extra webapps stripped out of server/webapps (except for manager) and webapps. 

This means that there are 2 WebappClassLoader instances in memory, one for each context. This seems correct.
There are also 2 WebappLoader instances in memory, I assume one for each context which also seems correct.

Now my understanding of the WebappClassLoader is that there is and instance for each context and eacg class loader is used to load classes for that context. This allows for dynamic class loading and some (?) isolation for each context. My assumption (partially from what I have read) is that when the context is undeployed tomcat severs its references to the class loader and thus the gc process can clean up all the leftovers...

Is this incorrect?

I've deployed the very minimal context into tomcat and then undeployed it via the manager. I used VisualVM to look and the heapdumps from before and after.

>From the before heapdump I saw what I expected: 2 WebappClassLoaders and 2 WebappLoaders.
After I saw:  2 WebappClassLoaders and 1 WebappLoader, which is not what I expected. 

Tomact seems to have retained 1 on the WebappClassLoader instances.

I have two questions at this point:

1. From the Javadocs both WebappClassLoader and WebappLoader are class loaders. What are the differences and why does Tomcat use both? 

2. Why would Tomcat be cleaning up the WebappLoader instance everytime successfully but seems to 'hang-on' to the WebappClassLoader instance?

Thanks
Gerwood
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


RE: WebappClassLoader and undeploy

Posted by "Caldarale, Charles R" <Ch...@unisys.com>.
> From: Jorge Medina [mailto:jmedina@e-dialog.com]
> Subject: RE: WebappClassLoader and undeploy
> 
> Does the JVM perform class unloading by default?

Usually.  However, the JVM version and the choice of GC algorithm may make it impossible to unload classes.  For example, the concurrent collectors were unable to discard classes in their early days.

 - 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.


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


RE: WebappClassLoader and undeploy

Posted by Jorge Medina <jm...@e-dialog.com>.
 
Does the JVM perform class unloading by default?
I usually add the option -XX:+CMSClassUnloadingEnabled so that classes also get garbage collected. (Otherwise I was running into out of PermGen memory space)

Would that solve your problem?


-----Original Message-----
From: Elli Albek [mailto:elli@sustainlane.com] 
Sent: Monday, November 09, 2009 5:53 PM
To: Tomcat Users List
Subject: Re: WebappClassLoader and undeploy

Managing class loaders is done in the JVM. Tomcat cannot force the JVM to garbage collect class loaders, in the same way that it cannot force the JVM to garbage collect any object.
If the class loader is unreachable, and all other objects that this class loader provided are also unreachable, then the JVM can garbage collect it like any other object.

This garbage collection is heavier than simple object reference. I assume the JVM will do it only in major garbage collections and maybe even not in every major one. If your test app is not doing anything, there is no reason for the JVM to actually do something about it since memory is not consumed. If you try to force major garbage collections, eventually it should happen. If you run a load test, which will force tomcat to consume memory, then you will eventually get to a major garbage collection. This can take much longer than what you would think. If the code is simple (like JSP page and hello world type of
servlet) it can be optimized by the JVM to consume memory on a local stack based heap (per thread), and not use the JVM main heaps.

If you keep a reference to one object that was created from this class loader, then the Class object of this object is reachable, and the class loader is reachable via the Class. Since it is reachable, it cannot be garbage collected.

WebappLoader is a class that has the code to manage a webapp lifecycle. It is not a class loader. The JVM to track references to it like any other simple object (String). In addition, it is an internal tomcat object, so it is a lot simpler to keep track of references to it in the tomcat code. It is not visible to the webapps or exposed to user code that can leak it.

WebappClassLoader is the opposite: It is a real class loader. Garbage collecting it is not a simple matter. My guess is that:

1.	If you constantly load the memory, then eventually it will be
garbage collected.
2.	If it is not garbage collected in that case, there is a reference
leak, something is keeping a reference to either the class loader or to an object that was loaded by from it.

Tomcat is releasing references to objects on its side, but the user code can do other things.

If the web app contains one servlet and one JSP page, that should be easy to follow. Tomcat keeps references to those objects (both should be servlets), but also releases them when you redeploy. You can verify that the objects are gone. The actual instances should be gone very quickly since they are simple objects. JSP page is turned into a class, you should see it in the memory management tool.

Notice that if the web app is reloaded, the new class loader will load the same classes again, so they will have the same class name, but they will have separate Class instances. You will have two objects that have the same class name, but are different class.

Other possible reference leaks from the webapp to the outside:
Threads that are left running
JNDI
Sessions
Thread local
Any library in a class loader above the webapp (in class loaders app, system, common and shared, possibly even in Catalina but less likely) Logging and reflection libraries always star as favorite leakers.

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: WebappClassLoader and undeploy

Posted by Mark Thomas <ma...@apache.org>.
Gerwood Stewart wrote:
> Mark
> 
> Thanks. I suppose I'd better get back to identifying the real problems then. :D

See my other mail - it has a fix for the problem you are seeing. The fix
even has comments so you'll get an explanation too :)

Mark

> 
> Gerwood
> ________________________________________
> From: Mark Thomas [markt@apache.org]
> Sent: Tuesday, 10 November 2009 10:48 AM
> To: Tomcat Users List
> Subject: Re: WebappClassLoader and undeploy
> 
> Gerwood Stewart wrote:
>> Elli
>>
>> I understand most of this. I do several things such as forcing a GC before doing the heap dump, from what you are say this may not be enough?
>> Either way I'm not looking for an instance of the class to simply be there I'm looking at the GC Roots.
>>
>> I also tried an additional step of after undeploying and finding I still had 2 GC roots I did a redeploy/undeploy. The results are:
>>
>> redeploy WebappClassLoader +1 (total 3)
>> undeploy WebappClassLoader -1 (total 2)
>>
>> So generally the behaviour appears to be correct after the initial issue with the 1 class loader. It would also appear that at that point some form of GC has occured and cleaned up other instances. What I'm left with is that the rogue instance is is reachable and that it probably shouldn't be. As per the response to Mark and the JDK version it appears the gcroot is though sun.awt.AppContext
>>
>> Any thoughts?
>>
>> Additionally I'm going to try and find a slightly old version of java and check it's behaviour...
> 
> I'll save you the effort. You won't see it in 1.6.0_14 and earlier.
> 
> Mark
> 
> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
> 




---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


RE: WebappClassLoader and undeploy

Posted by Gerwood Stewart <gs...@une.edu.au>.
Mark

Thanks. I suppose I'd better get back to identifying the real problems then. :D

Gerwood
________________________________________
From: Mark Thomas [markt@apache.org]
Sent: Tuesday, 10 November 2009 10:48 AM
To: Tomcat Users List
Subject: Re: WebappClassLoader and undeploy

Gerwood Stewart wrote:
> Elli
>
> I understand most of this. I do several things such as forcing a GC before doing the heap dump, from what you are say this may not be enough?
> Either way I'm not looking for an instance of the class to simply be there I'm looking at the GC Roots.
>
> I also tried an additional step of after undeploying and finding I still had 2 GC roots I did a redeploy/undeploy. The results are:
>
> redeploy WebappClassLoader +1 (total 3)
> undeploy WebappClassLoader -1 (total 2)
>
> So generally the behaviour appears to be correct after the initial issue with the 1 class loader. It would also appear that at that point some form of GC has occured and cleaned up other instances. What I'm left with is that the rogue instance is is reachable and that it probably shouldn't be. As per the response to Mark and the JDK version it appears the gcroot is though sun.awt.AppContext
>
> Any thoughts?
>
> Additionally I'm going to try and find a slightly old version of java and check it's behaviour...

I'll save you the effort. You won't see it in 1.6.0_14 and earlier.

Mark




---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: WebappClassLoader and undeploy

Posted by Mark Thomas <ma...@apache.org>.
Gerwood Stewart wrote:
> Elli 
> 
> I understand most of this. I do several things such as forcing a GC before doing the heap dump, from what you are say this may not be enough?
> Either way I'm not looking for an instance of the class to simply be there I'm looking at the GC Roots.
> 
> I also tried an additional step of after undeploying and finding I still had 2 GC roots I did a redeploy/undeploy. The results are:
> 
> redeploy WebappClassLoader +1 (total 3) 
> undeploy WebappClassLoader -1 (total 2)
> 
> So generally the behaviour appears to be correct after the initial issue with the 1 class loader. It would also appear that at that point some form of GC has occured and cleaned up other instances. What I'm left with is that the rogue instance is is reachable and that it probably shouldn't be. As per the response to Mark and the JDK version it appears the gcroot is though sun.awt.AppContext
> 
> Any thoughts?
> 
> Additionally I'm going to try and find a slightly old version of java and check it's behaviour...

I'll save you the effort. You won't see it in 1.6.0_14 and earlier.

Mark




---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


RE: WebappClassLoader and undeploy

Posted by Gerwood Stewart <gs...@une.edu.au>.
Elli 

I understand most of this. I do several things such as forcing a GC before doing the heap dump, from what you are say this may not be enough?
Either way I'm not looking for an instance of the class to simply be there I'm looking at the GC Roots.

I also tried an additional step of after undeploying and finding I still had 2 GC roots I did a redeploy/undeploy. The results are:

redeploy WebappClassLoader +1 (total 3) 
undeploy WebappClassLoader -1 (total 2)

So generally the behaviour appears to be correct after the initial issue with the 1 class loader. It would also appear that at that point some form of GC has occured and cleaned up other instances. What I'm left with is that the rogue instance is is reachable and that it probably shouldn't be. As per the response to Mark and the JDK version it appears the gcroot is though sun.awt.AppContext

Any thoughts?

Additionally I'm going to try and find a slightly old version of java and check it's behaviour...



Gerwood
________________________________________
From: Elli Albek [elli@sustainlane.com]
Sent: Tuesday, 10 November 2009 9:52 AM
To: Tomcat Users List
Subject: Re: WebappClassLoader and undeploy

Managing class loaders is done in the JVM. Tomcat cannot force the JVM
to garbage collect class loaders, in the same way that it cannot force
the JVM to garbage collect any object.
If the class loader is unreachable, and all other objects that this
class loader provided are also unreachable, then the JVM can garbage
collect it like any other object.

This garbage collection is heavier than simple object reference. I
assume the JVM will do it only in major garbage collections and maybe
even not in every major one. If your test app is not doing anything,
there is no reason for the JVM to actually do something about it since
memory is not consumed. If you try to force major garbage collections,
eventually it should happen. If you run a load test, which will force
tomcat to consume memory, then you will eventually get to a major
garbage collection. This can take much longer than what you would
think. If the code is simple (like JSP page and hello world type of
servlet) it can be optimized by the JVM to consume memory on a local
stack based heap (per thread), and not use the JVM main heaps.

If you keep a reference to one object that was created from this class
loader, then the Class object of this object is reachable, and the
class loader is reachable via the Class. Since it is reachable, it
cannot be garbage collected.

WebappLoader is a class that has the code to manage a webapp
lifecycle. It is not a class loader. The JVM to track references to it
like any other simple object (String). In addition, it is an internal
tomcat object, so it is a lot simpler to keep track of references to
it in the tomcat code. It is not visible to the webapps or exposed to
user code that can leak it.

WebappClassLoader is the opposite: It is a real class loader. Garbage
collecting it is not a simple matter. My guess is that:

1.      If you constantly load the memory, then eventually it will be
garbage collected.
2.      If it is not garbage collected in that case, there is a reference
leak, something is keeping a reference to either the class loader or
to an object that was loaded by from it.

Tomcat is releasing references to objects on its side, but the user
code can do other things.

If the web app contains one servlet and one JSP page, that should be
easy to follow. Tomcat keeps references to those objects (both should
be servlets), but also releases them when you redeploy. You can verify
that the objects are gone. The actual instances should be gone very
quickly since they are simple objects. JSP page is turned into a
class, you should see it in the memory management tool.

Notice that if the web app is reloaded, the new class loader will load
the same classes again, so they will have the same class name, but
they will have separate Class instances. You will have two objects
that have the same class name, but are different class.

Other possible reference leaks from the webapp to the outside:
Threads that are left running
JNDI
Sessions
Thread local
Any library in a class loader above the webapp (in class loaders app,
system, common and shared, possibly even in Catalina but less likely)
Logging and reflection libraries always star as favorite leakers.

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: WebappClassLoader and undeploy

Posted by Elli Albek <el...@sustainlane.com>.
Managing class loaders is done in the JVM. Tomcat cannot force the JVM
to garbage collect class loaders, in the same way that it cannot force
the JVM to garbage collect any object.
If the class loader is unreachable, and all other objects that this
class loader provided are also unreachable, then the JVM can garbage
collect it like any other object.

This garbage collection is heavier than simple object reference. I
assume the JVM will do it only in major garbage collections and maybe
even not in every major one. If your test app is not doing anything,
there is no reason for the JVM to actually do something about it since
memory is not consumed. If you try to force major garbage collections,
eventually it should happen. If you run a load test, which will force
tomcat to consume memory, then you will eventually get to a major
garbage collection. This can take much longer than what you would
think. If the code is simple (like JSP page and hello world type of
servlet) it can be optimized by the JVM to consume memory on a local
stack based heap (per thread), and not use the JVM main heaps.

If you keep a reference to one object that was created from this class
loader, then the Class object of this object is reachable, and the
class loader is reachable via the Class. Since it is reachable, it
cannot be garbage collected.

WebappLoader is a class that has the code to manage a webapp
lifecycle. It is not a class loader. The JVM to track references to it
like any other simple object (String). In addition, it is an internal
tomcat object, so it is a lot simpler to keep track of references to
it in the tomcat code. It is not visible to the webapps or exposed to
user code that can leak it.

WebappClassLoader is the opposite: It is a real class loader. Garbage
collecting it is not a simple matter. My guess is that:

1.	If you constantly load the memory, then eventually it will be
garbage collected.
2.	If it is not garbage collected in that case, there is a reference
leak, something is keeping a reference to either the class loader or
to an object that was loaded by from it.

Tomcat is releasing references to objects on its side, but the user
code can do other things.

If the web app contains one servlet and one JSP page, that should be
easy to follow. Tomcat keeps references to those objects (both should
be servlets), but also releases them when you redeploy. You can verify
that the objects are gone. The actual instances should be gone very
quickly since they are simple objects. JSP page is turned into a
class, you should see it in the memory management tool.

Notice that if the web app is reloaded, the new class loader will load
the same classes again, so they will have the same class name, but
they will have separate Class instances. You will have two objects
that have the same class name, but are different class.

Other possible reference leaks from the webapp to the outside:
Threads that are left running
JNDI
Sessions
Thread local
Any library in a class loader above the webapp (in class loaders app,
system, common and shared, possibly even in Catalina but less likely)
Logging and reflection libraries always star as favorite leakers.

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: [OT] WebappClassLoader and undeploy

Posted by Elli Albek <el...@sustainlane.com>.
Actually Mark can you take a quick look at the class I sent and see if
it makes sense. I swapped juli with commons logging (which is in bin)
but now I am not sure this is necessary, this library may already be
loaded regardless of this filter.

E

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: [OT] WebappClassLoader and undeploy

Posted by Elli Albek <el...@sustainlane.com>.
Tomcat 5.5 version + log message when executed:

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.catalina.core;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

import javax.imageio.ImageIO;

import org.apache.catalina.Lifecycle;
import org.apache.catalina.LifecycleEvent;
import org.apache.catalina.LifecycleListener;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.tomcat.util.res.StringManager;

/**
 * Provide a workaround for known places where the Java Runtime environment can
 * cause a memory leak or lock files.
 * <p>
 * Memory leaks occur when JRE code uses
 * the context class loader to load a singleton as this will cause a memory leak
 * if a web application class loader happens to be the context class loader at
 * the time. The work-around is to initialise these singletons when Tomcat's
 * common class loader is the context class loader.
 * <p>
 * Locked usually files occur when a resource inside a JAR is accessed without
 * first disabling Jar URL connection caching. The workaround is to disable this
 * caching by default.
 */
public class JreMemoryLeakPreventionListener implements LifecycleListener {

    protected static final Log log =
        LogFactory.getLog(JreMemoryLeakPreventionListener.class);
    protected static final StringManager sm =
        StringManager.getManager(Constants.Package);

    /**
     * Protect against the memory leak caused when the first call to
     * <code>sun.awt.AppContext.getAppContext()</code> is triggered by a web
     * application. Defaults to <code>true</code>.
     */
    protected boolean appContextProtection = true;
    public boolean isAppContextProtection() { return appContextProtection; }
    public void setAppContextProtection(boolean appContextProtection) {
        this.appContextProtection = appContextProtection;
    }

    /**
     * Protect against resources being read for JAR files and, as a side-effect,
     * the JAR file becoming locked. Note this disables caching for all
     * {@link URLConnection}s, regardless of type. Defaults to
     * <code>true</code>.
     */
    protected boolean urlCacheProtection = true;
    public boolean isUrlCacheProtection() { return urlCacheProtection; }
    public void setUrlCacheProtection(boolean urlCacheProtection) {
        this.urlCacheProtection = urlCacheProtection;
    }

    public void lifecycleEvent(LifecycleEvent event) {
        // Initialise these classes when Tomcat starts
        if (Lifecycle.INIT_EVENT.equals(event.getType())) {
        	log.info("Running JreMemoryLeakPreventionListener
(appContextProtection="
        			+ appContextProtection + ", urlCacheProtection=" +
urlCacheProtection + ')');
        	/*
             * Several components end up calling:
             * sun.awt.AppContext.getAppContext()
             *
             * Those libraries / components known to trigger memory leaks due to
             * eventual calls to getAppContext() are:
             * - Google Web Toolkit via its use of javax.imageio
             * - Tomcat via its use of java.beans.Introspector.flushCaches() in
             *   1.6.0_15 onwards
             * - others TBD
             */

            // Trigger a call to sun.awt.AppContext.getAppContext(). This will
            // pin the common class loader in memory but that shouldn't be an
            // issue.
            if (appContextProtection) {
                ImageIO.getCacheDirectory();
            }

            /*
             * Several components end up opening JarURLConnections without first
             * disabling caching. This effectively locks the file. Whilst more
             * noticeable and harder to ignore on Windows, it affects all
             * operating systems.
             *
             * Those libraries/components known to trigger this issue include:
             * - log4j versions 1.2.15 and earlier
             * - javax.xml.bind.JAXBContext.newInstance()
             */

            // Set the default URL caching policy to not to cache
            if (urlCacheProtection) {
                try {
                    // Doesn't matter that this JAR doesn't exist -
just as long as
                    // the URL is well-formed
                    URL url = new URL("jar:file://dummy.jar!/");
                    URLConnection uConn = url.openConnection();
                    uConn.setDefaultUseCaches(false);
                } catch (MalformedURLException e) {
                    log.error(sm.getString(
                            "jreLeakListener.jarUrlConnCacheFail"), e);
                } catch (IOException e) {
                    log.error(sm.getString(
                    "jreLeakListener.jarUrlConnCacheFail"), e);
                }
            }
        }
    }
}

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: [OT] WebappClassLoader and undeploy

Posted by Mark Thomas <ma...@apache.org>.
Elli Albek wrote:
> Sorry Mark.
> 
> Well this class loading scheme (context class loader -> static
> variable) sounds little like a bug.

Indeed.

> Thanks for that startup class. I think it will solve a problem that we
> have (using imageio). So you just add it as high up as possible in the
> server.xml hierarchy?

It should be added alongside the other lifecycle listeners at the start of
server.xml

Mark

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: [OT] WebappClassLoader and undeploy

Posted by Elli Albek <el...@sustainlane.com>.
Sorry Mark.

Well this class loading scheme (context class loader -> static
variable) sounds little like a bug.

Thanks for that startup class. I think it will solve a problem that we
have (using imageio). So you just add it as high up as possible in the
server.xml hierarchy?

E

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: [OT] WebappClassLoader and undeploy

Posted by Christopher Schultz <ch...@christopherschultz.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Mark,

On 11/9/2009 6:47 PM, Mark Thomas wrote:
> Give this a go:
> http://svn.apache.org/repos/asf/tomcat/trunk/java/org/apache/catalina/core/JreMemoryLeakPreventionListener.java

You gotta love Sun:

    private static boolean defaultUseCaches = true;
...

    protected boolean useCaches = defaultUseCaches;

...

    public void setUseCaches(boolean usecaches) {
        if (connected)
            throw new IllegalStateException("Already connected");
        useCaches = usecaches;
    }

So, not only do you have to create an instance of this class in order to
set the value of a static member (duh!), you also can't change the
default under certain circumstances that are local to the instance
you're trying to use.

Stupid, stupid, stupid. :(

- -chris
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAkr516AACgkQ9CaO5/Lv0PBeKwCdFHKLDklbGes+AdYKx7bWYSNu
bmgAn1sHYeTry1cnzu88Vek6Bk4oMzdc
=7mhb
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: WebappClassLoader and undeploy

Posted by Mark Thomas <ma...@apache.org>.
Elli Albek wrote:
> Thomas,

My given name is is Mark. Thomas is my family name.

> what is the issue with javax.imageio? Do they really use
> context class loader for loading static variables?

Yes. First call to most methods in that library trigger a call to
sun.awt.AppContext.getAppContext() which initialises a singleton
instance of AppContext using the thread context class loader.

Mark




---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: WebappClassLoader and undeploy

Posted by Elli Albek <el...@sustainlane.com>.
Thomas, what is the issue with javax.imageio? Do they really use
context class loader for loading static variables?

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: WebappClassLoader and undeploy

Posted by Mark Thomas <ma...@apache.org>.
Gerwood Stewart wrote:
> Mark
> 
>> 2. Why would Tomcat be cleaning up the WebappLoader instance everytime successfully but seems to 'hang-on' to the WebappClassLoader instance?
> My money is on it being JVM code rather than Tomcat code that is hanging
> onto the WebappClassLoader. Are you testing with JDK 1.6.0_15 or later
> by any chance?
> 
> Yes. I'm using Apple's JVM and Suns (on Ubuntu 9.04)

As I suspected.

> I traced the webappclassloader gcroot. It appears to be connected via sun.awt.AppContext?

Yep - also what I expected to see.

> Any thoughts.

Give this a go:
http://svn.apache.org/repos/asf/tomcat/trunk/java/org/apache/catalina/core/JreMemoryLeakPreventionListener.java

You'll need to add
<Listener
className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />

to your server.xml (adjust class name as necessary - it doesn't have to
be in a Tomcat package)

It should help with JAR file locking too. The plan is to add more
work-arounds to this listener as they are identified.

For those of you that like your humour with an ironic twist, you may be
amused by the first commit messages for this class:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/JreMemoryLeakPreventionListener.java?view=log&pathrev=830908

Mark




---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


RE: WebappClassLoader and undeploy

Posted by Gerwood Stewart <gs...@une.edu.au>.
Mark

> 2. Why would Tomcat be cleaning up the WebappLoader instance everytime successfully but seems to 'hang-on' to the WebappClassLoader instance?
My money is on it being JVM code rather than Tomcat code that is hanging
onto the WebappClassLoader. Are you testing with JDK 1.6.0_15 or later
by any chance?

Yes. I'm using Apple's JVM and Suns (on Ubuntu 9.04)

I traced the webappclassloader gcroot. It appears to be connected via sun.awt.AppContext?

Any thoughts.

Gerwood

________________________________________
From: Mark Thomas [markt@apache.org]
Sent: Tuesday, 10 November 2009 9:07 AM
To: Tomcat Users List
Subject: Re: WebappClassLoader and undeploy

Gerwood Stewart wrote:
> Tomact seems to have retained 1 on the WebappClassLoader instances.
>
> I have two questions at this point:
>
> 1. From the Javadocs both WebappClassLoader and WebappLoader are class loaders. What are the differences and why does Tomcat use both?
WebappClassLoader is the actual class loader, WebappLoader is the
context level object that manages the class loader.

> 2. Why would Tomcat be cleaning up the WebappLoader instance everytime successfully but seems to 'hang-on' to the WebappClassLoader instance?
My money is on it being JVM code rather than Tomcat code that is hanging
onto the WebappClassLoader. Are you testing with JDK 1.6.0_15 or later
by any chance?

Mark




---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: WebappClassLoader and undeploy

Posted by Mark Thomas <ma...@apache.org>.
Gerwood Stewart wrote:
> Tomact seems to have retained 1 on the WebappClassLoader instances.
> 
> I have two questions at this point:
> 
> 1. From the Javadocs both WebappClassLoader and WebappLoader are class loaders. What are the differences and why does Tomcat use both?
WebappClassLoader is the actual class loader, WebappLoader is the
context level object that manages the class loader.

> 2. Why would Tomcat be cleaning up the WebappLoader instance everytime successfully but seems to 'hang-on' to the WebappClassLoader instance?
My money is on it being JVM code rather than Tomcat code that is hanging
onto the WebappClassLoader. Are you testing with JDK 1.6.0_15 or later
by any chance?

Mark




---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org