This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch 8.5.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/8.5.x by this push:
     new 2c5e826  Align with 9.0.m and 10.0.x
2c5e826 is described below

commit 2c5e826d33cdd7a97659e1a159688e8abc476579
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Mon Dec 7 17:56:06 2020 +0000

    Align with 9.0.m and 10.0.x
    
    Adds support for skipMemoryLeakChecksOnJvmShutdown to Context
---
 java/org/apache/catalina/core/StandardContext.java | 16 ++++++++
 java/org/apache/catalina/filters/CorsFilter.java   | 21 +++-------
 .../catalina/filters/CsrfPreventionFilter.java     |  2 +-
 .../org/apache/catalina/filters/ExpiresFilter.java |  6 +--
 .../catalina/filters/RequestDumperFilter.java      |  3 ++
 .../catalina/filters/RestCsrfPreventionFilter.java |  3 +-
 .../apache/catalina/loader/JdbcLeakPrevention.java |  3 +-
 .../apache/catalina/loader/LocalStrings.properties |  2 +
 .../catalina/loader/LocalStrings_fr.properties     |  2 +
 .../catalina/loader/LocalStrings_ja.properties     |  2 +
 .../catalina/loader/LocalStrings_ko.properties     |  2 +
 .../catalina/loader/LocalStrings_zh_CN.properties  |  2 +
 .../catalina/loader/WebappClassLoaderBase.java     | 45 ++++++++++++++++++----
 webapps/docs/changelog.xml                         |  7 ++++
 webapps/docs/config/context.xml                    |  7 ++++
 15 files changed, 93 insertions(+), 30 deletions(-)

diff --git a/java/org/apache/catalina/core/StandardContext.java 
b/java/org/apache/catalina/core/StandardContext.java
index db04227..b3673ec 100644
--- a/java/org/apache/catalina/core/StandardContext.java
+++ b/java/org/apache/catalina/core/StandardContext.java
@@ -753,6 +753,12 @@ public class StandardContext extends ContainerBase
     private boolean clearReferencesThreadLocals = true;
 
     /**
+     * Should Tomcat skip the memory leak checks when the web application is
+     * stopped as part of the process of shutting down the JVM?
+     */
+    private boolean skipMemoryLeakChecksOnJvmShutdown = false;
+
+    /**
      * Should the effective web.xml be logged when the context starts?
      */
     private boolean logEffectiveWebXml = false;
@@ -2739,6 +2745,16 @@ public class StandardContext extends ContainerBase
     }
 
 
+    public boolean getSkipMemoryLeakChecksOnJvmShutdown() {
+        return skipMemoryLeakChecksOnJvmShutdown;
+    }
+
+
+    public void setSkipMemoryLeakChecksOnJvmShutdown(boolean 
skipMemoryLeakChecksOnJvmShutdown) {
+        this.skipMemoryLeakChecksOnJvmShutdown = 
skipMemoryLeakChecksOnJvmShutdown;
+    }
+
+
     public Boolean getFailCtxIfServletStartFails() {
         return failCtxIfServletStartFails;
     }
diff --git a/java/org/apache/catalina/filters/CorsFilter.java 
b/java/org/apache/catalina/filters/CorsFilter.java
index 3a4613a..4f1091a 100644
--- a/java/org/apache/catalina/filters/CorsFilter.java
+++ b/java/org/apache/catalina/filters/CorsFilter.java
@@ -20,6 +20,7 @@ import java.io.IOException;
 import java.net.URI;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
@@ -155,8 +156,6 @@ public class CorsFilter implements Filter {
         switch (requestType) {
         case SIMPLE:
             // Handles a Simple CORS request.
-            this.handleSimpleCORS(request, response, filterChain);
-            break;
         case ACTUAL:
             // Handles an Actual CORS request.
             this.handleSimpleCORS(request, response, filterChain);
@@ -516,15 +515,6 @@ public class CorsFilter implements Filter {
 
         switch (corsRequestType) {
         case SIMPLE:
-            request.setAttribute(
-                    CorsFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST,
-                    Boolean.TRUE);
-            request.setAttribute(CorsFilter.HTTP_REQUEST_ATTRIBUTE_ORIGIN,
-                    request.getHeader(CorsFilter.REQUEST_HEADER_ORIGIN));
-            request.setAttribute(
-                    CorsFilter.HTTP_REQUEST_ATTRIBUTE_REQUEST_TYPE,
-                    corsRequestType.name().toLowerCase(Locale.ENGLISH));
-            break;
         case ACTUAL:
             request.setAttribute(
                     CorsFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST, 
Boolean.TRUE);
@@ -749,7 +739,7 @@ public class CorsFilter implements Filter {
         this.exposedHeaders.clear();
         this.exposedHeaders.addAll(setExposedHeaders);
 
-        // For any value other then 'true' this will be false.
+        // For any value other than 'true' this will be false.
         this.supportsCredentials = Boolean.parseBoolean(supportsCredentials);
 
         if (this.supportsCredentials && this.anyOriginAllowed) {
@@ -767,7 +757,7 @@ public class CorsFilter implements Filter {
                     sm.getString("corsFilter.invalidPreflightMaxAge"), e);
         }
 
-        // For any value other then 'true' this will be false.
+        // For any value other than 'true' this will be false.
         this.decorateRequest = Boolean.parseBoolean(decorateRequest);
     }
 
@@ -892,6 +882,7 @@ public class CorsFilter implements Filter {
 
 
     // -------------------------------------------------- CORS Response Headers
+
     /**
      * The Access-Control-Allow-Origin header indicates whether a resource can
      * be shared based by returning the value of the Origin request header in
@@ -1040,8 +1031,8 @@ public class CorsFilter implements Filter {
      *       >http://www.w3.org/TR/cors/#terminology</a>
      */
     public static final Collection<String> 
SIMPLE_HTTP_REQUEST_CONTENT_TYPE_VALUES =
-            new HashSet<>(Arrays.asList("application/x-www-form-urlencoded",
-                    "multipart/form-data", "text/plain"));
+            Collections.unmodifiableSet(new HashSet<>(Arrays.asList(
+                    "application/x-www-form-urlencoded", 
"multipart/form-data", "text/plain")));
 
     // ------------------------------------------------ Configuration Defaults
     /**
diff --git a/java/org/apache/catalina/filters/CsrfPreventionFilter.java 
b/java/org/apache/catalina/filters/CsrfPreventionFilter.java
index 7be6ac0..fe7a27f 100644
--- a/java/org/apache/catalina/filters/CsrfPreventionFilter.java
+++ b/java/org/apache/catalina/filters/CsrfPreventionFilter.java
@@ -246,7 +246,7 @@ public class CsrfPreventionFilter extends 
CsrfPreventionFilterBase {
             return addNonce(super.encodeURL(url));
         }
 
-        /**
+        /*
          * Return the specified URL with the nonce added to the query string.
          *
          * @param url URL to be modified
diff --git a/java/org/apache/catalina/filters/ExpiresFilter.java 
b/java/org/apache/catalina/filters/ExpiresFilter.java
index 6394985..af3e3c0 100644
--- a/java/org/apache/catalina/filters/ExpiresFilter.java
+++ b/java/org/apache/catalina/filters/ExpiresFilter.java
@@ -523,8 +523,8 @@ public class ExpiresFilter extends FilterBase {
 
     /**
      * Expiration configuration starting point. Either the time the
-     * html-page/servlet-response was served ({@link 
StartingPoint#ACCESS_TIME})
-     * or the last time the html-page/servlet-response was modified (
+     * HTML-page/servlet-response was served ({@link 
StartingPoint#ACCESS_TIME})
+     * or the last time the HTML-page/servlet-response was modified (
      * {@link StartingPoint#LAST_MODIFICATION_TIME}).
      */
     protected enum StartingPoint {
@@ -1104,7 +1104,7 @@ public class ExpiresFilter extends FilterBase {
         if (str == null || searchStr == null) {
             return false;
         }
-        return str.indexOf(searchStr) >= 0;
+        return str.contains(searchStr);
     }
 
     /**
diff --git a/java/org/apache/catalina/filters/RequestDumperFilter.java 
b/java/org/apache/catalina/filters/RequestDumperFilter.java
index d45d901..bcbe868 100644
--- a/java/org/apache/catalina/filters/RequestDumperFilter.java
+++ b/java/org/apache/catalina/filters/RequestDumperFilter.java
@@ -263,16 +263,19 @@ public class RequestDumperFilter implements Filter {
         return ts.dateString;
     }
 
+
     @Override
     public void init(FilterConfig filterConfig) throws ServletException {
         // NOOP
     }
 
+
     @Override
     public void destroy() {
         // NOOP
     }
 
+
     private static final class Timestamp {
         private final Date date = new Date(0);
         private final SimpleDateFormat format =
diff --git a/java/org/apache/catalina/filters/RestCsrfPreventionFilter.java 
b/java/org/apache/catalina/filters/RestCsrfPreventionFilter.java
index 8587cf5..4fd6efc 100644
--- a/java/org/apache/catalina/filters/RestCsrfPreventionFilter.java
+++ b/java/org/apache/catalina/filters/RestCsrfPreventionFilter.java
@@ -79,8 +79,7 @@ public class RestCsrfPreventionFilter extends 
CsrfPreventionFilterBase {
         NON_MODIFYING_METHOD, MODIFYING_METHOD
     }
 
-    private static final Pattern NON_MODIFYING_METHODS_PATTERN = Pattern
-            .compile("GET|HEAD|OPTIONS");
+    private static final Pattern NON_MODIFYING_METHODS_PATTERN = 
Pattern.compile("GET|HEAD|OPTIONS");
 
     private Set<String> pathsAcceptingParams = new HashSet<>();
 
diff --git a/java/org/apache/catalina/loader/JdbcLeakPrevention.java 
b/java/org/apache/catalina/loader/JdbcLeakPrevention.java
index a6acd18..913fec5 100644
--- a/java/org/apache/catalina/loader/JdbcLeakPrevention.java
+++ b/java/org/apache/catalina/loader/JdbcLeakPrevention.java
@@ -25,6 +25,7 @@ import java.util.ArrayList;
 import java.util.Enumeration;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 /**
  * This class is loaded by {@link WebappClassLoaderBase} to enable it to
@@ -52,7 +53,7 @@ public class JdbcLeakPrevention {
          * ensuring that both original drivers and any loaded as a result of 
the
          * side-effects are all de-registered.
          */
-        HashSet<Driver> originalDrivers = new HashSet<>();
+        Set<Driver> originalDrivers = new HashSet<>();
         Enumeration<Driver> drivers = DriverManager.getDrivers();
         while (drivers.hasMoreElements()) {
             originalDrivers.add(drivers.nextElement());
diff --git a/java/org/apache/catalina/loader/LocalStrings.properties 
b/java/org/apache/catalina/loader/LocalStrings.properties
index 3ffd5c1..43a3bb4 100644
--- a/java/org/apache/catalina/loader/LocalStrings.properties
+++ b/java/org/apache/catalina/loader/LocalStrings.properties
@@ -44,6 +44,8 @@ webappClassLoader.loadedByThisOrChildFail=Failed to fully 
check the entries in a
 webappClassLoader.readError=Resource read error: Could not load [{0}].
 webappClassLoader.removeTransformer=Removed class file transformer [{0}] from 
web application [{1}].
 webappClassLoader.resourceModified=Resource [{0}] has been modified. The last 
modified time was [{1}] and is now [{2}]
+webappClassLoader.restrictedPackage=Security violation, attempt to use 
restricted class [{0}]
+webappClassLoader.securityException=Security exception trying to find class 
[{0}] in findClassInternal [{1}]
 webappClassLoader.stackTrace=The web application [{0}] appears to have started 
a thread named [{1}] but has failed to stop it. This is very likely to create a 
memory leak. Stack trace of thread:{2}
 webappClassLoader.stackTraceRequestThread=The web application [{0}] is still 
processing a request that has yet to finish. This is very likely to create a 
memory leak. You can control the time allowed for requests to finish by using 
the unloadDelay attribute of the standard Context implementation. Stack trace 
of request processing thread:[{2}]
 webappClassLoader.stopThreadFail=Failed to terminate thread named [{0}] for 
web application [{1}]
diff --git a/java/org/apache/catalina/loader/LocalStrings_fr.properties 
b/java/org/apache/catalina/loader/LocalStrings_fr.properties
index 1bae2cc..46ba94a 100644
--- a/java/org/apache/catalina/loader/LocalStrings_fr.properties
+++ b/java/org/apache/catalina/loader/LocalStrings_fr.properties
@@ -44,6 +44,8 @@ webappClassLoader.loadedByThisOrChildFail=Impossible de 
vérifier complètement
 webappClassLoader.readError=Erreur lors de la lecture de la resource : 
impossible de charger [{0}].
 webappClassLoader.removeTransformer=Enlevé le transformateur de fichiers de 
classe [{0}] de l''application web [{1}]
 webappClassLoader.resourceModified=La ressource [{0}] a été modifiée, la date 
de dernière modification était [{1}] et est désormais [{2}]
+webappClassLoader.restrictedPackage=Violation de sécurité en essayant 
d''utiliser à une classe à accès restreint [{0}]
+webappClassLoader.securityException=Exception de sécurité en essayant de 
trouver la classe [{0}] dans findClassInternal [{1}]
 webappClassLoader.stackTrace=L''application web [{0}] semble avoir démarré un 
thread nommé [{1}] mais ne l''a pas arrêté, ce qui va probablement créer une 
fuite de mémoire ; la trace du thread est : {2}
 webappClassLoader.stackTraceRequestThread=Une requête de l''application web 
[{0}] est toujours en cours, ce qui causera certainement une fuite de mémoire, 
vous pouvez contrôler le temps alloué en utilisant l''attribut unloadDelay de 
l''implémentation standard de Context ; trace du fil d’exécution de la requête 
: [{2}]
 webappClassLoader.stopThreadFail=Impossible de terminer le thread nommé [{0}] 
pour l''application [{1}]
diff --git a/java/org/apache/catalina/loader/LocalStrings_ja.properties 
b/java/org/apache/catalina/loader/LocalStrings_ja.properties
index cd3b15d..a3b99e7 100644
--- a/java/org/apache/catalina/loader/LocalStrings_ja.properties
+++ b/java/org/apache/catalina/loader/LocalStrings_ja.properties
@@ -43,6 +43,8 @@ webappClassLoader.loadedByThisOrChildFail=クラス [{0}] のインスタンス
 webappClassLoader.readError=リソース読み込みエラー: [{0}] が読み込めませんでした。
 webappClassLoader.removeTransformer=クラスファイル変換器 [{0}] を Web アプリケーション [{1}] 
から削除しました。
 webappClassLoader.resourceModified=リソース [{0}] は変更されています。直前の更新日時は 
[{1}]、最新の更新日時は [{2}] です。
+webappClassLoader.restrictedPackage=セキュリティー違反。制限されたクラス [{0}] を使おうとしました。
+webappClassLoader.securityException=indClassInternal 
[{1}]でクラス[{0}]を検索中のセキュリティ例外です
 
webappClassLoader.stackTrace=Webアプリケーション[{0}]は[{1}]という名前のスレッドを開始したようですが、停止に失敗しました。
 これはメモリリークを引き起こす可能性が非常に高いです。 スレッドのスタックトレース:{2}
 
webappClassLoader.stackTraceRequestThread=Webアプリケーション[{0}]はまだ完了していないリクエストを処理しています。
 これはメモリリークを引き起こす可能性が非常に高いです。 
リクエストの終了時間は、StandardContext実装のunloadDelay属性を使用して制御できます。 
陸絵鵜sと処理スレッドのスタックトレース:[{2}]
 webappClassLoader.stopThreadFail=Web アプリケーション [{1}] のスレッド [{0}] は終了できません。
diff --git a/java/org/apache/catalina/loader/LocalStrings_ko.properties 
b/java/org/apache/catalina/loader/LocalStrings_ko.properties
index e1d315f..50153c9 100644
--- a/java/org/apache/catalina/loader/LocalStrings_ko.properties
+++ b/java/org/apache/catalina/loader/LocalStrings_ko.properties
@@ -44,6 +44,8 @@ webappClassLoader.loadedByThisOrChildFail=컨텍스트 [{1}]에서 잠재적 메
 webappClassLoader.readError=리소스 읽기 오류 : [{0}]을(를) 로드할 수 없었습니다.
 webappClassLoader.removeTransformer=웹 애플리케이션 [{1}](으)로부터 클래스 파일 Transformer 
[{0}]을(를) 제거했습니다.
 webappClassLoader.resourceModified=리소스 [{0}]이(가) 변경된 적이 있습니다. 최종 변경 시간이 
[{1}]이었는데, 이제 [{2}](으)로 바뀌었습니다.
+webappClassLoader.restrictedPackage=보안 위반 행위: 제한된 클래스 [{0}]을(를) 사용하려 시도했습니다.
+webappClassLoader.securityException=findClassInternal에서, 클래스 [{0}]을(를) 찾으려 시도 
중 보안 예외 발생: [{1}]
 webappClassLoader.stackTrace=웹 애플리케이션 [{0}]이(가) [{1}](이)라는 이름의 쓰레드를 시작시킨 것으로 
보이지만, 해당 쓰레드를 중지시키지 못했습니다. 이는 메모리 누수를 유발할 가능성이 큽니다. 해당 쓰레드의 스택 트레이스:{2}
 webappClassLoader.stackTraceRequestThread=웹 애플리케이션 [{0}]이(가) 여전히 완료되지 않은 요청을 
처리하고 있습니다. 이는 메모리 누수를 유발할 가능성이 높습니다. 표준 컨텍스트 구현의 unloadDelay 속성을 이용하여, 요청 완료 허용 
시간을 통제할 수 있습니다. 요청 처리 쓰레드의 스택 트레이스:[{2}]
 webappClassLoader.stopThreadFail=웹 애플리케이션 [{1}]을 위한, [{0}](이)라는 이름의 쓰레드를 종료시키지 
못했습니다.
diff --git a/java/org/apache/catalina/loader/LocalStrings_zh_CN.properties 
b/java/org/apache/catalina/loader/LocalStrings_zh_CN.properties
index 1a43950..ace8b96 100644
--- a/java/org/apache/catalina/loader/LocalStrings_zh_CN.properties
+++ b/java/org/apache/catalina/loader/LocalStrings_zh_CN.properties
@@ -43,6 +43,8 @@ webappClassLoader.loadedByThisOrChildFail=无法完全检查[{0}]实例中的条
 webappClassLoader.readError=资源读取错误:不能加载 [{0}].
 webappClassLoader.removeTransformer=已从web应用程序[{1}]中删除类文件转换器[{0}]。
 webappClassLoader.resourceModified=资源[{0}]已被修改。上次修改时间是[{1}],现在是[{2}]
+webappClassLoader.restrictedPackage=安全冲突,尝试使用受限类[{0}]
+webappClassLoader.securityException=尝试在findClassInternal[{1}]中查找类[{0}]时出现安全异常
 
webappClassLoader.stackTrace=Web应用程序[{0}]似乎启动了一个名为[{1}]的线程,但未能停止它。这很可能会造成内存泄漏。线程的堆栈跟踪:[{2}]
 
webappClassLoader.stackTraceRequestThread=web应用程序[{0}]仍在处理一个尚未完成的请求。这很可能会造成内存泄漏。您可以使用标准上下文实现的unloadDelay属性来控制请求完成所允许的时间。请求处理线程的堆栈跟踪:[{2}]
 webappClassLoader.stopThreadFail=为web应用程序[{1}]终止线程[{0}]失败
diff --git a/java/org/apache/catalina/loader/WebappClassLoaderBase.java 
b/java/org/apache/catalina/loader/WebappClassLoaderBase.java
index 2451876..75629d9 100644
--- a/java/org/apache/catalina/loader/WebappClassLoaderBase.java
+++ b/java/org/apache/catalina/loader/WebappClassLoaderBase.java
@@ -192,8 +192,7 @@ public abstract class WebappClassLoaderBase extends 
URLClassLoader
     /**
      * The string manager for this package.
      */
-    protected static final StringManager sm =
-        StringManager.getManager(Constants.Package);
+    protected static final StringManager sm = 
StringManager.getManager(WebappClassLoaderBase.class);
 
 
     // ----------------------------------------------------------- Constructors
@@ -397,6 +396,12 @@ public abstract class WebappClassLoaderBase extends 
URLClassLoader
     private boolean clearReferencesThreadLocals = true;
 
     /**
+     * Should Tomcat skip the memory leak checks when the web application is
+     * stopped as part of the process of shutting down the JVM?
+     */
+    private boolean skipMemoryLeakChecksOnJvmShutdown = false;
+
+    /**
      * 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
@@ -652,6 +657,16 @@ public abstract class WebappClassLoaderBase extends 
URLClassLoader
     }
 
 
+    public boolean getSkipMemoryLeakChecksOnJvmShutdown() {
+        return skipMemoryLeakChecksOnJvmShutdown;
+    }
+
+
+    public void setSkipMemoryLeakChecksOnJvmShutdown(boolean 
skipMemoryLeakChecksOnJvmShutdown) {
+        this.skipMemoryLeakChecksOnJvmShutdown = 
skipMemoryLeakChecksOnJvmShutdown;
+    }
+
+
     // ------------------------------------------------------- Reloader Methods
 
     /**
@@ -855,8 +870,8 @@ public abstract class WebappClassLoaderBase extends 
URLClassLoader
                     clazz = findClassInternal(name);
                 }
             } catch(AccessControlException ace) {
-                log.warn("WebappClassLoader.findClassInternal(" + name
-                        + ") security exception: " + ace.getMessage(), ace);
+                log.warn(sm.getString("webappClassLoader.securityException", 
name,
+                        ace.getMessage()), ace);
                 throw new ClassNotFoundException(name, ace);
             } catch (RuntimeException e) {
                 if (log.isTraceEnabled())
@@ -867,8 +882,8 @@ public abstract class WebappClassLoaderBase extends 
URLClassLoader
                 try {
                     clazz = super.findClass(name);
                 } catch(AccessControlException ace) {
-                    log.warn("WebappClassLoader.findClassInternal(" + name
-                            + ") security exception: " + ace.getMessage(), 
ace);
+                    
log.warn(sm.getString("webappClassLoader.securityException", name,
+                            ace.getMessage()), ace);
                     throw new ClassNotFoundException(name, ace);
                 } catch (RuntimeException e) {
                     if (log.isTraceEnabled())
@@ -1292,8 +1307,7 @@ public abstract class WebappClassLoaderBase extends 
URLClassLoader
                     try {
                         
securityManager.checkPackageAccess(name.substring(0,i));
                     } catch (SecurityException se) {
-                        String error = "Security Violation, attempt to use " +
-                            "Restricted Class: " + name;
+                        String error = 
sm.getString("webappClassLoader.restrictedPackage", name);
                         log.info(error, se);
                         throw new ClassNotFoundException(error, se);
                     }
@@ -1592,6 +1606,21 @@ public abstract class WebappClassLoaderBase extends 
URLClassLoader
      */
     protected void clearReferences() {
 
+        // If the JVM is shutting down, skip the memory leak checks
+        if (skipMemoryLeakChecksOnJvmShutdown
+            && !resources.getContext().getParent().getState().isAvailable()) {
+            // During reloading / redeployment the parent is expected to be
+            // available. Parent is not available so this might be a JVM
+            // shutdown.
+            try {
+                Thread dummyHook = new Thread();
+                Runtime.getRuntime().addShutdownHook(dummyHook);
+                Runtime.getRuntime().removeShutdownHook(dummyHook);
+            } catch (IllegalStateException ise) {
+                return;
+            }
+        }
+
         // De-register any remaining JDBC drivers
         clearReferencesJdbc();
 
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 35ed0a6..13f7913 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -107,6 +107,13 @@
   <subsection name="Catalina">
     <changelog>
       <fix>
+        <bug>50175</bug>: Add a new attribute to the standard context
+        implementation, <code>skipMemoryLeakChecksOnJvmShutdown</code>, that
+        allows the user to configure Tomcat to skip the memory leak checks
+        usually performed during web application stop if that stop is triggered
+        by a JVM shutdown. (markt)
+      </fix>
+      <fix>
         <bug>60781</bug>: Escape elements in the access log that need to be
         escaped for the access log to be parsed unambiguously.
         (fschumacher/markt)
diff --git a/webapps/docs/config/context.xml b/webapps/docs/config/context.xml
index 37802d4..0adb5e3 100644
--- a/webapps/docs/config/context.xml
+++ b/webapps/docs/config/context.xml
@@ -829,6 +829,13 @@
         default value of <code>true</code> will be used.</p>
       </attribute>
 
+      <attribute name="skipMemoryLeakChecksOnJvmShutdown" required="false">
+        <p>If <code>true</code>, Tomcat will not perform the usual memory leak
+        checks when the web application is stopped if that web application is
+        stopped as part of a JVM shutdown. If not specified, the default value
+        of <code>false</code> will be used.</p>
+      </attribute>
+
       <attribute name="unloadDelay" required="false">
         <p>Number of ms that the container will wait for servlets to unload.
         If not specified, the default value is <code>2000</code> ms.</p>


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to