You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2018/03/13 23:24:02 UTC
svn commit: r1826688 - in /tomcat/trunk: bin/ java/org/apache/catalina/core/
java/org/apache/catalina/loader/ res/ webapps/docs/ webapps/docs/config/
Author: markt
Date: Tue Mar 13 23:24:01 2018
New Revision: 1826688
URL: http://svn.apache.org/viewvc?rev=1826688&view=rev
Log:
Fix https://bz.apache.org/bugzilla/show_bug.cgi?id=51195
Avoid a false positive report of a web application memory leak by clearing ObjectStreamClass$Caches of classes loaded by the web application when the web application is stopped.
Modified:
tomcat/trunk/bin/catalina.bat
tomcat/trunk/bin/catalina.sh
tomcat/trunk/bin/service.bat
tomcat/trunk/java/org/apache/catalina/core/StandardContext.java
tomcat/trunk/java/org/apache/catalina/loader/LocalStrings.properties
tomcat/trunk/java/org/apache/catalina/loader/WebappClassLoaderBase.java
tomcat/trunk/res/tomcat.nsi
tomcat/trunk/webapps/docs/changelog.xml
tomcat/trunk/webapps/docs/config/context.xml
tomcat/trunk/webapps/docs/setup.xml
Modified: tomcat/trunk/bin/catalina.bat
URL: http://svn.apache.org/viewvc/tomcat/trunk/bin/catalina.bat?rev=1826688&r1=1826687&r2=1826688&view=diff
==============================================================================
--- tomcat/trunk/bin/catalina.bat (original)
+++ tomcat/trunk/bin/catalina.bat Tue Mar 13 23:24:01 2018
@@ -224,6 +224,7 @@ set LOGGING_MANAGER=-Djava.util.logging.
rem Configure JAVA 9 specific start-up parameters
set "JDK_JAVA_OPTIONS=%JDK_JAVA_OPTIONS% --add-opens=java.base/java.lang=ALL-UNNAMED"
+set "JDK_JAVA_OPTIONS=%JDK_JAVA_OPTIONS% --add-opens=java.base/java.io=ALL-UNNAMED"
set "JDK_JAVA_OPTIONS=%JDK_JAVA_OPTIONS% --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED"
rem Java 9 no longer supports the java.endorsed.dirs
Modified: tomcat/trunk/bin/catalina.sh
URL: http://svn.apache.org/viewvc/tomcat/trunk/bin/catalina.sh?rev=1826688&r1=1826687&r2=1826688&view=diff
==============================================================================
--- tomcat/trunk/bin/catalina.sh (original)
+++ tomcat/trunk/bin/catalina.sh Tue Mar 13 23:24:01 2018
@@ -302,6 +302,7 @@ fi
# Add the JAVA 9 specific start-up parameters required by Tomcat
JDK_JAVA_OPTIONS="$JDK_JAVA_OPTIONS --add-opens=java.base/java.lang=ALL-UNNAMED"
+JDK_JAVA_OPTIONS="$JDK_JAVA_OPTIONS --add-opens=java.base/java.io=ALL-UNNAMED"
JDK_JAVA_OPTIONS="$JDK_JAVA_OPTIONS --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED"
export JDK_JAVA_OPTIONS
Modified: tomcat/trunk/bin/service.bat
URL: http://svn.apache.org/viewvc/tomcat/trunk/bin/service.bat?rev=1826688&r1=1826687&r2=1826688&view=diff
==============================================================================
--- tomcat/trunk/bin/service.bat (original)
+++ tomcat/trunk/bin/service.bat Tue Mar 13 23:24:01 2018
@@ -184,7 +184,7 @@ if "%JvmMx%" == "" set JvmMx=256
--StartParams start ^
--StopParams stop ^
--JvmOptions "-Dcatalina.home=%CATALINA_HOME%;-Dcatalina.base=%CATALINA_BASE%;-D%ENDORSED_PROP%=%CATALINA_HOME%\endorsed;-Djava.io.tmpdir=%CATALINA_BASE%\temp;-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager;-Djava.util.logging.config.file=%CATALINA_BASE%\conf\logging.properties;%JvmArgs%" ^
- --JvmOptions9 "--add-opens=java.base/java.lang=ALL-UNNAMED#--add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED" ^
+ --JvmOptions9 "--add-opens=java.base/java.lang=ALL-UNNAMED#--add-opens=java.base/java.io=ALL-UNNAMED#--add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED" ^
--Startup "%SERVICE_STARTUP_MODE%" ^
--JvmMs "%JvmMs%" ^
--JvmMx "%JvmMx%"
Modified: tomcat/trunk/java/org/apache/catalina/core/StandardContext.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/StandardContext.java?rev=1826688&r1=1826687&r2=1826688&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/core/StandardContext.java (original)
+++ tomcat/trunk/java/org/apache/catalina/core/StandardContext.java Tue Mar 13 23:24:01 2018
@@ -737,6 +737,12 @@ public class StandardContext extends Con
private boolean renewThreadsWhenStoppingContext = true;
/**
+ * Should Tomcat attempt to clear references to classes loaded by the web
+ * application class loader from the ObjectStreamClass caches?
+ */
+ private boolean clearReferencesObjectStreamClassCaches = true;
+
+ /**
* Should the effective web.xml be logged when the context starts?
*/
private boolean logEffectiveWebXml = false;
@@ -2652,6 +2658,23 @@ public class StandardContext extends Con
this.renewThreadsWhenStoppingContext);
}
+
+ public boolean getClearReferencesObjectStreamClassCaches() {
+ return clearReferencesObjectStreamClassCaches;
+ }
+
+
+ public void setClearReferencesObjectStreamClassCaches(
+ boolean clearReferencesObjectStreamClassCaches) {
+ boolean oldClearReferencesObjectStreamClassCaches =
+ this.clearReferencesObjectStreamClassCaches;
+ this.clearReferencesObjectStreamClassCaches = clearReferencesObjectStreamClassCaches;
+ support.firePropertyChange("clearReferencesObjectStreamClassCaches",
+ oldClearReferencesObjectStreamClassCaches,
+ this.clearReferencesObjectStreamClassCaches);
+ }
+
+
public Boolean getFailCtxIfServletStartFails() {
return failCtxIfServletStartFails;
}
@@ -4901,6 +4924,8 @@ public class StandardContext extends Con
getClearReferencesStopTimerThreads());
setClassLoaderProperty("clearReferencesHttpClientKeepAliveThread",
getClearReferencesHttpClientKeepAliveThread());
+ setClassLoaderProperty("clearReferencesObjectStreamClassCaches",
+ getClearReferencesObjectStreamClassCaches());
// By calling unbindThread and bindThread in a row, we setup the
// current Thread CCL to be the webapp classloader
Modified: tomcat/trunk/java/org/apache/catalina/loader/LocalStrings.properties
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/loader/LocalStrings.properties?rev=1826688&r1=1826687&r2=1826688&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/loader/LocalStrings.properties (original)
+++ tomcat/trunk/java/org/apache/catalina/loader/LocalStrings.properties Tue Mar 13 23:24:01 2018
@@ -22,6 +22,7 @@ webappClassLoader.jdbcRemoveFailed=JDBC
webappClassLoader.stopped=Illegal access: this web application instance has been stopped already. Could not load [{0}]. The following stack trace is thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access.
webappClassLoader.readError=Resource read error: Could not load [{0}].
webappClassLoader.clearJdbc=The web application [{0}] registered the JDBC driver [{1}] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered.
+webappClassLoader.clearObjectStreamClassCachesFail=Failed to clear soft references from ObjectStreamClass$Caches for web application [{0}]
webappClassLoader.clearReferencesResourceBundlesCount=Removed [{0}] ResourceBundle references from the cache for web application [{1}]
webappClassLoader.clearReferencesResourceBundlesFail=Failed to clear ResourceBundle references for web application [{0}]
webappClassLoader.clearRmi=Found RMI Target with stub class class [{0}] and value [{1}]. This RMI Target has been forcibly removed to prevent a memory leak.
Modified: tomcat/trunk/java/org/apache/catalina/loader/WebappClassLoaderBase.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/loader/WebappClassLoaderBase.java?rev=1826688&r1=1826687&r2=1826688&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/loader/WebappClassLoaderBase.java (original)
+++ tomcat/trunk/java/org/apache/catalina/loader/WebappClassLoaderBase.java Tue Mar 13 23:24:01 2018
@@ -362,6 +362,12 @@ public abstract class WebappClassLoaderB
private boolean clearReferencesHttpClientKeepAliveThread = true;
/**
+ * Should Tomcat attempt to clear references to classes loaded by this class
+ * loader from the ObjectStreamClass caches?
+ */
+ private boolean clearReferencesObjectStreamClassCaches = true;
+
+ /**
* Holds the class file transformers decorating this class loader. The
* CopyOnWriteArrayList is thread safe. It is expensive on writes, but
* those should be rare. It is very fast on reads, since synchronization
@@ -596,6 +602,17 @@ public abstract class WebappClassLoaderB
}
+ public boolean getClearReferencesObjectStreamClassCaches() {
+ return clearReferencesObjectStreamClassCaches;
+ }
+
+
+ public void setClearReferencesObjectStreamClassCaches(
+ boolean clearReferencesObjectStreamClassCaches) {
+ this.clearReferencesObjectStreamClassCaches = clearReferencesObjectStreamClassCaches;
+ }
+
+
// ------------------------------------------------------- Reloader Methods
/**
@@ -1513,6 +1530,11 @@ public abstract class WebappClassLoaderB
// Stop any threads the web application started
clearReferencesThreads();
+ // Clear any references retained in the serialization caches
+ if (clearReferencesObjectStreamClassCaches) {
+ clearReferencesObjectStreamClassCaches();
+ }
+
// Check for leaks triggered by ThreadLocals loaded by this class loader
checkThreadLocalsForLeaks();
@@ -2132,6 +2154,36 @@ public abstract class WebappClassLoaderB
}
}
}
+
+
+ private void clearReferencesObjectStreamClassCaches() {
+ try {
+ Class<?> clazz = Class.forName("java.io.ObjectStreamClass$Caches");
+ clearCache(clazz, "localDescs");
+ clearCache(clazz, "reflectors");
+ } catch (ReflectiveOperationException | SecurityException | ClassCastException e) {
+ log.warn(sm.getString(
+ "webappClassLoader.clearObjectStreamClassCachesFail", getContextName()), e);
+ }
+ }
+
+
+ private void clearCache(Class<?> target, String mapName)
+ throws ReflectiveOperationException, SecurityException, ClassCastException {
+ Field f = target.getDeclaredField(mapName);
+ f.setAccessible(true);
+ Map<?,?> map = (Map<?,?>) f.get(null);
+ Iterator<?> keys = map.keySet().iterator();
+ while (keys.hasNext()) {
+ Object key = keys.next();
+ if (key instanceof Reference) {
+ Object clazz = ((Reference<?>) key).get();
+ if (loadedByThisOrChild(clazz)) {
+ keys.remove();
+ }
+ }
+ }
+ }
/**
Modified: tomcat/trunk/res/tomcat.nsi
URL: http://svn.apache.org/viewvc/tomcat/trunk/res/tomcat.nsi?rev=1826688&r1=1826687&r2=1826688&view=diff
==============================================================================
--- tomcat/trunk/res/tomcat.nsi (original)
+++ tomcat/trunk/res/tomcat.nsi Tue Mar 13 23:24:01 2018
@@ -322,7 +322,7 @@ Section -post
FileWrite $ServiceInstallLog "$\r$\n"
FileWrite $ServiceInstallLog '"$INSTDIR\bin\$TomcatServiceFileName" //US//$TomcatServiceName --JvmOptions "-Dcatalina.home=$INSTDIR#-Dcatalina.base=$INSTDIR#-Djava.io.tmpdir=$INSTDIR\temp#-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager#-Djava.util.logging.config.file=$INSTDIR\conf\logging.properties"'
FileWrite $ServiceInstallLog "$\r$\n"
- FileWrite $ServiceInstallLog '"$INSTDIR\bin\$TomcatServiceFileName" //US//$TomcatServiceName --JvmOptions9 "--add-opens=java.base/java.lang=ALL-UNNAMED#--add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED"'
+ FileWrite $ServiceInstallLog '"$INSTDIR\bin\$TomcatServiceFileName" //US//$TomcatServiceName --JvmOptions9 "--add-opens=java.base/java.lang=ALL-UNNAMED#--add-opens=java.base/java.io=ALL-UNNAMED#--add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED"'
FileWrite $ServiceInstallLog "$\r$\n"
FileWrite $ServiceInstallLog '"$INSTDIR\bin\$TomcatServiceFileName" //US//$TomcatServiceName --StdOutput auto --StdError auto --JvmMs 128 --JvmMx 256'
FileWrite $ServiceInstallLog "$\r$\n"
@@ -332,7 +332,7 @@ Section -post
DetailPrint "Configuring $TomcatServiceName service"
nsExec::ExecToLog '"$INSTDIR\bin\$TomcatServiceFileName" //US//$TomcatServiceName --Classpath "$INSTDIR\bin\bootstrap.jar;$INSTDIR\bin\tomcat-juli.jar" --StartClass org.apache.catalina.startup.Bootstrap --StopClass org.apache.catalina.startup.Bootstrap --StartParams start --StopParams stop --StartMode jvm --StopMode jvm'
nsExec::ExecToLog '"$INSTDIR\bin\$TomcatServiceFileName" //US//$TomcatServiceName --JvmOptions "-Dcatalina.home=$INSTDIR#-Dcatalina.base=$INSTDIR#-Djava.io.tmpdir=$INSTDIR\temp#-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager#-Djava.util.logging.config.file=$INSTDIR\conf\logging.properties"'
- nsExec::ExecToLog '"$INSTDIR\bin\$TomcatServiceFileName" //US//$TomcatServiceName --JvmOptions9 "--add-opens=java.base/java.lang=ALL-UNNAMED#--add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED"'
+ nsExec::ExecToLog '"$INSTDIR\bin\$TomcatServiceFileName" //US//$TomcatServiceName --JvmOptions9 "--add-opens=java.base/java.lang=ALL-UNNAMED#--add-opens=java.base/java.io=ALL-UNNAMED#--add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED"'
nsExec::ExecToLog '"$INSTDIR\bin\$TomcatServiceFileName" //US//$TomcatServiceName --StdOutput auto --StdError auto --JvmMs 128 --JvmMx 256'
${If} $TomcatShortcutAllUsers == "1"
Modified: tomcat/trunk/webapps/docs/changelog.xml
URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1826688&r1=1826687&r2=1826688&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/trunk/webapps/docs/changelog.xml Tue Mar 13 23:24:01 2018
@@ -48,6 +48,12 @@
<subsection name="Catalina">
<changelog>
<fix>
+ <bug>51195</bug>: Avoid a false positive report of a web application
+ memory leak by clearing <code>ObjectStreamClass$Caches</code> of classes
+ loaded by the web application when the web application is stopped.
+ (markt)
+ </fix>
+ <fix>
Ensure the MBean names for the <code>SSLHostConfig</code> and
<code>SSLHostConfigCertificate</code> are correctly formed when the
<code>Connector</code> is bound to a specific IP address. (markt)
Modified: tomcat/trunk/webapps/docs/config/context.xml
URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/context.xml?rev=1826688&r1=1826687&r2=1826688&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/config/context.xml (original)
+++ tomcat/trunk/webapps/docs/config/context.xml Tue Mar 13 23:24:01 2018
@@ -711,6 +711,18 @@
not specified, the default value of <code>true</code> will be used.</p>
</attribute>
+ <attribute name="clearReferencesObjectStreamClassCaches" required="false">
+ <p>If <code>true</code>, when the web application is stopped Tomcat
+ looks for <code>SoftReference</code>s to classes loaded by the web
+ application in the <code>ObjectStreamClass</code> class used for
+ serialization and clears any <code>SoftReference</code>s it finds. This
+ feature uses reflection to identify the <code>SoftReference</code>s and
+ therefore requires that the command line option
+ <code>-XaddExports:java.base/java.io=ALL-UNNAMED</code> is set
+ when running on Java 9 and above. If not specified, the default value of
+ <code>true</code> will be used.</p>
+ </attribute>
+
<attribute name="clearReferencesRmiTargets" required="false">
<p>If <code>true</code>, Tomcat looks for memory leaks associated with
RMI Targets and clears any it finds. This feature uses reflection to
Modified: tomcat/trunk/webapps/docs/setup.xml
URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/setup.xml?rev=1826688&r1=1826687&r2=1826688&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/setup.xml (original)
+++ tomcat/trunk/webapps/docs/setup.xml Tue Mar 13 23:24:01 2018
@@ -157,6 +157,7 @@ cd $CATALINA_HOME
following when starting jsvc to avoid warnings on shutdown.</p>
<source>...
--add-opens=java.base/java.lang=ALL-UNNAMED \
+--add-opens=java.base/java.io=ALL-UNNAMED \
--add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED \
...
</source>
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org