From 3b4e242207e71962d159e0162a090eb57c9e533f Mon Sep 17 00:00:00 2001
From: markt sun.awt.AppContext.getAppContext() is triggered by a web
+ * application. Defaults to true.
+ */
+ 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
+ * true.
+ */
+ 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);
+ }
}
}
}
diff --git a/webapps/docs/config/listeners.xml b/webapps/docs/config/listeners.xml
index c4245f1ea..566b13b3f 100644
--- a/webapps/docs/config/listeners.xml
+++ b/webapps/docs/config/listeners.xml
@@ -227,19 +227,36 @@ service:jmx:rmi://<hostname>:10002/jndi/rmi://<hostname>: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.
Currently the JRE Memory Leak Prevention Listener - provides work-arounds for the following:
-sun.awt.AppContext.getAppContext()This listener must only be nested within Server elements.
-No additional attributes are supported by the JRE Memory Leak - Prevention Listener.
+The following additional attributes are supported by the JRE + Memory Leak Prevention Listener:
+ +Enables protection so that calls to
+ sun.awt.AppContext.getAppContext() 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 true
Enables protection so that reading resources from JAR files using
+ java.net.URLConnections does not result in the JAR file
+ being locked. Note that enabling this protection disables caching by
+ default for all resources obtained via
+ java.net.URLConnections. Caching may be re-enabled on a
+ case by case basis is required. Defaults to true.