Make leak prevention listener more configurable
authormarkt <markt@13f79535-47bb-0310-9956-ffa450edef68>
Thu, 29 Oct 2009 12:03:48 +0000 (12:03 +0000)
committermarkt <markt@13f79535-47bb-0310-9956-ffa450edef68>
Thu, 29 Oct 2009 12:03:48 +0000 (12:03 +0000)
git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@830908 13f79535-47bb-0310-9956-ffa450edef68

java/org/apache/catalina/core/JreMemoryLeakPreventionListener.java
webapps/docs/config/listeners.xml

index 86c7aae..a4be86b 100644 (file)
@@ -51,7 +51,30 @@ public class JreMemoryLeakPreventionListener implements LifecycleListener {
         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;
+    }
+
     @Override
     public void lifecycleEvent(LifecycleEvent event) {
         // Initialise these classes when Tomcat starts
@@ -71,7 +94,9 @@ public class JreMemoryLeakPreventionListener implements LifecycleListener {
             // Trigger a call to sun.awt.AppContext.getAppContext(). This will
             // pin the common class loader in memory but that shouldn't be an
             // issue.
-            ImageIO.getCacheDirectory();
+            if (appContextProtection) {
+                ImageIO.getCacheDirectory();
+            }
             
             /*
              * Several components end up opening JarURLConnections without first
@@ -84,19 +109,21 @@ public class JreMemoryLeakPreventionListener implements LifecycleListener {
              * - javax.xml.bind.JAXBContext.newInstance()
              */
             
-            // Set the default JAR URL caching policy to not to cache
-            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);
+            // 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);
+                }
             }
         }
     }
index c4245f1..566b13b 100644 (file)
@@ -227,19 +227,36 @@ service:jmx:rmi://&lt;hostname&gt;:10002/jndi/rmi://&lt;hostname&gt;:10001/jmxrm
     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
     this listener starts as Tomcat's common class loader is the context class
-    loader at that time.</p>
+    loader at that time. It also provides work-arounds for known issues that
+    can result in locked JAR files.</p>
     
-    <p>Currently the <strong>JRE Memory Leak Prevention Listener</strong>
-    provides work-arounds for the following:</p>
-    <ul>
-      <li><code>sun.awt.AppContext.getAppContext()</code></li>
-    </ul>
-
     <p>This listener must only be nested within <a href="server.html">Server</a>
     elements.</p>
 
-    <p>No additional attributes are supported by the <strong>JRE Memory Leak
-    Prevention Listener</strong>.</p>
+    <p>The following additional attributes are supported by the <strong>JRE
+    Memory Leak Prevention Listener</strong>:</p>
+
+    <attributes>
+
+      <attribute name="appContextProtection" required="false">
+        <p>Enables protection so that calls to
+        <code>sun.awt.AppContext.getAppContext()</code> triggered by a web
+        application do not result in a memory leak. Note that a call to this
+        method will be triggered as part of the web application stop process so
+        it is strongly recommended that this protection is enabled. The default
+        is <code>true</code></p>
+      </attribute>
+
+      <attribute name="urlCacheProtection" required="false">
+        <p>Enables protection so that reading resources from JAR files using
+        <code>java.net.URLConnection</code>s does not result in the JAR file
+        being locked. Note that enabling this protection disables caching by
+        default for all resources obtained via
+        <code>java.net.URLConnection</code>s. Caching may be re-enabled on a
+        case by case basis is required. Defaults to <code>true</code>.</p>
+      </attribute>
+
+    </attributes>
 
   </subsection>