Somewhat ironically, the call to java.beans.Introspector.flushCaches() that is meant...
authormarkt <markt@13f79535-47bb-0310-9956-ffa450edef68>
Wed, 21 Oct 2009 20:36:23 +0000 (20:36 +0000)
committermarkt <markt@13f79535-47bb-0310-9956-ffa450edef68>
Wed, 21 Oct 2009 20:36:23 +0000 (20:36 +0000)
Add a listener that prevents the leak.

git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@828196 13f79535-47bb-0310-9956-ffa450edef68

conf/server.xml
java/org/apache/catalina/core/JreMemoryLeakPreventionListener.java [new file with mode: 0644]

index 1f96f3f..156e542 100644 (file)
@@ -25,6 +25,8 @@
   <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
   <!--Initialize Jasper prior to webapps are loaded. Documentation at /docs/jasper-howto.html -->
   <Listener className="org.apache.catalina.core.JasperListener" />
+  <!-- Prevent memory leaks due to use of particular java/javax APIs-->
+  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
   <!-- JMX Support for the Tomcat server. Documentation at /docs/non-existent.html -->
   <Listener className="org.apache.catalina.mbeans.ServerLifecycleListener" />
   <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
diff --git a/java/org/apache/catalina/core/JreMemoryLeakPreventionListener.java b/java/org/apache/catalina/core/JreMemoryLeakPreventionListener.java
new file mode 100644 (file)
index 0000000..8ffa3ee
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * 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 javax.imageio.ImageIO;
+
+import org.apache.catalina.Lifecycle;
+import org.apache.catalina.LifecycleEvent;
+import org.apache.catalina.LifecycleListener;
+
+/**
+ * Provide a workaround for known places where the Java Runtime environment 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.
+ */
+public class JreMemoryLeakPreventionListener implements LifecycleListener {
+
+    @Override
+    public void lifecycleEvent(LifecycleEvent event) {
+        // Initialise these classes when Tomcat starts
+        if (Lifecycle.INIT_EVENT.equals(event.getType())) {
+            /*
+             * 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.
+            ImageIO.getCacheDirectory();
+            
+        }
+    }
+
+}