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 <[email protected]>
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: [email protected]
For additional commands, e-mail: [email protected]