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 2017/01/25 20:23:22 UTC

svn commit: r1780267 [2/2] - in /tomcat/tc7.0.x/trunk: ./ java/org/apache/catalina/core/ java/org/apache/tomcat/util/collections/ test/org/apache/catalina/core/ webapps/docs/

Modified: tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/StandardContext.java
URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/StandardContext.java?rev=1780267&r1=1780266&r2=1780267&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/StandardContext.java (original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/StandardContext.java Wed Jan 25 20:23:21 2017
@@ -5,9 +5,9 @@
  * 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.
@@ -206,7 +206,7 @@ public class StandardContext extends Con
      * <multipart-config> element.
      */
     protected boolean allowCasualMultipartParsing = false;
-     
+
     /**
      * Control whether remaining request data will be read
      * (swallowed) even if the request violates a data size constraint.
@@ -236,13 +236,13 @@ public class StandardContext extends Con
      */
     private boolean antiJARLocking = false;
 
-    
+
     /**
      * The antiResourceLocking flag for this Context.
      */
     private boolean antiResourceLocking = false;
 
-    
+
     /**
      * The set of application listener class names configured for this
      * application, in the order they were encountered in the resulting merged
@@ -250,7 +250,7 @@ public class StandardContext extends Con
      */
     private ApplicationListener applicationListeners[] =
             new ApplicationListener[0];
-    
+
     private final Object applicationListenersLock = new Object();
 
     /**
@@ -265,7 +265,7 @@ public class StandardContext extends Con
      * SCIs and other code may use the pluggability APIs to add listener
      * instances directly to this list before the application starts.
      */
-    private Object applicationEventListenersObjects[] = 
+    private Object applicationEventListenersObjects[] =
         new Object[0];
 
 
@@ -274,7 +274,7 @@ public class StandardContext extends Con
      * SCIs and other code may use the pluggability APIs to add listener
      * instances directly to this list before the application starts.
      */
-    private Object applicationLifecycleListenersObjects[] = 
+    private Object applicationLifecycleListenersObjects[] =
         new Object[0];
 
 
@@ -283,8 +283,8 @@ public class StandardContext extends Con
      */
     private Map<ServletContainerInitializer,Set<Class<?>>> initializers =
         new LinkedHashMap<ServletContainerInitializer,Set<Class<?>>>();
-    
-    
+
+
     /**
      * The set of application parameters defined for this application.
      */
@@ -292,13 +292,13 @@ public class StandardContext extends Con
         new ApplicationParameter[0];
 
     private final Object applicationParametersLock = new Object();
-    
+
 
     /**
-     * The broadcaster that sends j2ee notifications. 
+     * The broadcaster that sends j2ee notifications.
      */
     private NotificationBroadcasterSupport broadcaster = null;
-    
+
     /**
      * The Locale to character set mapper for this application.
      */
@@ -329,7 +329,7 @@ public class StandardContext extends Con
      */
     private volatile SecurityConstraint constraints[] =
             new SecurityConstraint[0];
-    
+
     private final Object constraintsLock = new Object();
 
 
@@ -364,12 +364,12 @@ public class StandardContext extends Con
      */
     private boolean crossContext = false;
 
-    
+
     /**
      * Encoded path.
      */
     private String encodedPath = null;
-    
+
 
     /**
      * Unencoded path for this web application.
@@ -390,13 +390,13 @@ public class StandardContext extends Con
     private String displayName = null;
 
 
-    /** 
+    /**
      * Override the default context xml location.
      */
     private String defaultContextXml;
 
 
-    /** 
+    /**
      * Override the default web xml location.
      */
     private String defaultWebXml;
@@ -470,7 +470,7 @@ public class StandardContext extends Con
     /**
      * The mapper associated with this context.
      */
-    private org.apache.tomcat.util.http.mapper.Mapper mapper = 
+    private org.apache.tomcat.util.http.mapper.Mapper mapper =
         new org.apache.tomcat.util.http.mapper.Mapper();
 
 
@@ -554,8 +554,8 @@ public class StandardContext extends Con
      * The original document root for this web application.
      */
     private String originalDocBase = null;
-    
-    
+
+
     /**
      * The privileged flag for this web application.
      */
@@ -594,7 +594,7 @@ public class StandardContext extends Con
      */
     private HashMap<String, String> servletMappings =
         new HashMap<String, String>();
-    
+
     private final Object servletMappingsLock = new Object();
 
 
@@ -607,7 +607,7 @@ public class StandardContext extends Con
      * The notification sequence number.
      */
     private AtomicLong sequenceNumber = new AtomicLong(0);
-    
+
     /**
      * The status code error pages for this web application, keyed by
      * HTTP status code (as an Integer). Note status code zero is used for the
@@ -746,9 +746,9 @@ public class StandardContext extends Con
     private long startTime;
     private long tldScanTime;
 
-    /** 
+    /**
      * Name of the engine. If null, the domain is used.
-     */ 
+     */
     private String j2EEApplication="none";
     private String j2EEServer="none";
 
@@ -781,34 +781,34 @@ public class StandardContext extends Con
      */
     private boolean saveConfig = true;
 
-    
+
     /**
      * The name to use for session cookies. <code>null</code> indicates that
      * the name is controlled by the application.
      */
     private String sessionCookieName;
-    
-    
+
+
     /**
      * The flag that indicates that session cookies should use HttpOnly
      */
     private boolean useHttpOnly = true;
 
-    
+
     /**
      * The domain to use for session cookies. <code>null</code> indicates that
      * the domain is controlled by the application.
      */
     private String sessionCookieDomain;
-    
-    
+
+
     /**
      * The path to use for session cookies. <code>null</code> indicates that
      * the path is controlled by the application.
      */
     private String sessionCookiePath;
-    
-    
+
+
     /**
      * Is a / added to the end of the session cookie path to ensure browsers,
      * particularly IE, don't send a session cookie for context /foo with
@@ -819,7 +819,7 @@ public class StandardContext extends Con
 
     /**
      * The Jar scanner to use to search for Jars that might contain
-     * configuration information such as TLDs or web-fragment.xml files. 
+     * configuration information such as TLDs or web-fragment.xml files.
      */
     private JarScanner jarScanner = null;
 
@@ -837,13 +837,13 @@ public class StandardContext extends Con
      * some issues reported with log4j when this option is true. Applications
      * without memory leaks using recent JVMs should operate correctly with this
      * option set to <code>false</code>. If not specified, the default value of
-     * <code>false</code> will be used. 
+     * <code>false</code> will be used.
      *
      * @deprecated This option will be removed in Tomcat 8.5
      */
     @Deprecated
     private boolean clearReferencesStatic = false;
-    
+
     /**
      * Should Tomcat attempt to terminate threads that have been started by the
      * web application? Stopping threads is performed via the deprecated (for
@@ -879,14 +879,14 @@ public class StandardContext extends Con
      * StandardThreadExecutor of ThreadPoolExecutor be set to a positive value.
      */
     private boolean renewThreadsWhenStoppingContext = true;
-    
+
     /**
      * Should the effective web.xml be logged when the context starts?
      */
     private boolean logEffectiveWebXml = false;
 
     private int effectiveMajorVersion = 3;
-    
+
     private int effectiveMinorVersion = 0;
 
     private JspConfigDescriptor jspConfigDescriptor =
@@ -897,7 +897,7 @@ public class StandardContext extends Con
     private String webappVersion = "";
 
     private boolean addWebinfClassesResources = false;
-    
+
     private boolean fireRequestListenersOnForwards = false;
 
     /**
@@ -933,7 +933,7 @@ public class StandardContext extends Con
 
 
     // ----------------------------------------------------- Context Properties
-    
+
     @Override
     public void setDispatchersUseEncodedPaths(boolean dispatchersUseEncodedPaths) {
         this.dispatchersUseEncodedPaths = dispatchersUseEncodedPaths;
@@ -1156,12 +1156,12 @@ public class StandardContext extends Con
     public void setEffectiveMinorVersion(int effectiveMinorVersion) {
         this.effectiveMinorVersion = effectiveMinorVersion;
     }
-    
+
     @Override
     public void setLogEffectiveWebXml(boolean logEffectiveWebXml) {
         this.logEffectiveWebXml = logEffectiveWebXml;
     }
-    
+
     @Override
     public boolean getLogEffectiveWebXml() {
         return logEffectiveWebXml;
@@ -1171,7 +1171,7 @@ public class StandardContext extends Con
     public Authenticator getAuthenticator() {
         if (this instanceof Authenticator)
             return (Authenticator) this;
-        
+
         Pipeline pipeline = getPipeline();
         if (pipeline != null) {
             Valve basic = pipeline.getBasic();
@@ -1185,7 +1185,7 @@ public class StandardContext extends Con
         }
         return null;
     }
-    
+
     @Override
     public JarScanner getJarScanner() {
         if (jarScanner == null) {
@@ -1200,7 +1200,7 @@ public class StandardContext extends Con
         this.jarScanner = jarScanner;
     }
 
-     
+
     @Override
     public InstanceManager getInstanceManager() {
        return instanceManager;
@@ -1212,7 +1212,7 @@ public class StandardContext extends Con
        this.instanceManager = instanceManager;
     }
 
-    
+
     @Override
     public String getEncodedPath() {
         return encodedPath;
@@ -1351,7 +1351,7 @@ public class StandardContext extends Con
 
 
     /**
-     * Return the list of resource aliases. 
+     * Return the list of resource aliases.
      */
     public String getAliases() {
         return this.aliases;
@@ -1396,11 +1396,11 @@ public class StandardContext extends Con
     public void setAliases(String aliases) {
         this.aliases = aliases;
     }
-    
-    
+
+
     /**
      * Add a ServletContainerInitializer instance to this web application.
-     * 
+     *
      * @param sci       The instance to add
      * @param classes   The classes in which the initializer expressed an
      *                  interest
@@ -1411,7 +1411,7 @@ public class StandardContext extends Con
         initializers.put(sci, classes);
     }
 
-    
+
     /**
      * Return the "follow standard delegation model" flag used to configure
      * our ClassLoader.
@@ -1507,8 +1507,8 @@ public class StandardContext extends Con
         newListeners[len] = listener;
         applicationEventListenersObjects = newListeners;
     }
-    
-    
+
+
     /**
      * Return the set of initialized application lifecycle listener objects,
      * in the order they were specified in the web application deployment
@@ -1548,7 +1548,7 @@ public class StandardContext extends Con
         applicationLifecycleListenersObjects = newListeners;
     }
 
-    
+
     /**
      * Return the antiJARLocking flag for this Context.
      */
@@ -1738,12 +1738,12 @@ public class StandardContext extends Con
                                    this.cookies);
 
     }
-    
-    
+
+
     /**
      * Gets the name to use for session cookies. Overrides any setting that
      * may be specified by the application.
-     * 
+     *
      * @return  The value of the default session cookie name or null if not
      *          specified
      */
@@ -1751,12 +1751,12 @@ public class StandardContext extends Con
     public String getSessionCookieName() {
         return sessionCookieName;
     }
-    
-    
+
+
     /**
      * Sets the name to use for session cookies. Overrides any setting that
      * may be specified by the application.
-     * 
+     *
      * @param sessionCookieName   The name to use
      */
     @Override
@@ -1767,10 +1767,10 @@ public class StandardContext extends Con
                 oldSessionCookieName, sessionCookieName);
     }
 
-    
+
     /**
      * Gets the value of the use HttpOnly cookies for session cookies flag.
-     * 
+     *
      * @return <code>true</code> if the HttpOnly flag should be set on session
      *         cookies
      */
@@ -1782,7 +1782,7 @@ public class StandardContext extends Con
 
     /**
      * Sets the use HttpOnly cookies for session cookies flag.
-     * 
+     *
      * @param useHttpOnly   Set to <code>true</code> to use HttpOnly cookies
      *                          for session cookies
      */
@@ -1794,12 +1794,12 @@ public class StandardContext extends Con
                 oldUseHttpOnly,
                 this.useHttpOnly);
     }
-    
-    
+
+
     /**
      * Gets the domain to use for session cookies. Overrides any setting that
      * may be specified by the application.
-     * 
+     *
      * @return  The value of the default session cookie domain or null if not
      *          specified
      */
@@ -1807,12 +1807,12 @@ public class StandardContext extends Con
     public String getSessionCookieDomain() {
         return sessionCookieDomain;
     }
-    
-    
+
+
     /**
      * Sets the domain to use for session cookies. Overrides any setting that
      * may be specified by the application.
-     * 
+     *
      * @param sessionCookieDomain   The domain to use
      */
     @Override
@@ -1822,12 +1822,12 @@ public class StandardContext extends Con
         support.firePropertyChange("sessionCookieDomain",
                 oldSessionCookieDomain, sessionCookieDomain);
     }
-    
+
 
     /**
      * Gets the path to use for session cookies. Overrides any setting that
      * may be specified by the application.
-     * 
+     *
      * @return  The value of the default session cookie path or null if not
      *          specified
      */
@@ -1835,12 +1835,12 @@ public class StandardContext extends Con
     public String getSessionCookiePath() {
         return sessionCookiePath;
     }
-    
-    
+
+
     /**
      * Sets the path to use for session cookies. Overrides any setting that
      * may be specified by the application.
-     * 
+     *
      * @param sessionCookiePath   The path to use
      */
     @Override
@@ -1850,7 +1850,7 @@ public class StandardContext extends Con
         support.firePropertyChange("sessionCookiePath",
                 oldSessionCookiePath, sessionCookiePath);
     }
-    
+
 
     @Override
     public boolean getSessionCookiePathUsesTrailingSlash() {
@@ -1897,12 +1897,12 @@ public class StandardContext extends Con
         return defaultContextXml;
     }
 
-    /** 
+    /**
      * Set the location of the default context xml that will be used.
      * If not absolute, it'll be made relative to the engine's base dir
      * ( which defaults to catalina.base system property ).
      *
-     * @param defaultContextXml The default web xml 
+     * @param defaultContextXml The default web xml
      */
     public void setDefaultContextXml(String defaultContextXml) {
         this.defaultContextXml = defaultContextXml;
@@ -1912,12 +1912,12 @@ public class StandardContext extends Con
         return defaultWebXml;
     }
 
-    /** 
+    /**
      * Set the location of the default web xml that will be used.
      * If not absolute, it'll be made relative to the engine's base dir
      * ( which defaults to catalina.base system property ).
      *
-     * @param defaultWebXml The default web xml 
+     * @param defaultWebXml The default web xml
      */
     public void setDefaultWebXml(String defaultWebXml) {
         this.defaultWebXml = defaultWebXml;
@@ -2095,12 +2095,12 @@ public class StandardContext extends Con
     public boolean getIgnoreAnnotations() {
         return this.ignoreAnnotations;
     }
-    
-    
+
+
     /**
-     * Set the boolean on the annotations parsing for this web 
+     * Set the boolean on the annotations parsing for this web
      * application.
-     * 
+     *
      * @param ignoreAnnotations The boolean on the annotations parsing
      */
     @Override
@@ -2110,8 +2110,8 @@ public class StandardContext extends Con
         support.firePropertyChange("ignoreAnnotations", oldIgnoreAnnotations,
                 this.ignoreAnnotations);
     }
-    
-    
+
+
     /**
      * Return the login configuration descriptor for this web application.
      */
@@ -2210,7 +2210,7 @@ public class StandardContext extends Con
         }
         support.firePropertyChange("namingResources",
                                    oldNamingResources, this.namingResources);
-        
+
         if (getState() == LifecycleState.NEW ||
                 getState() == LifecycleState.INITIALIZING ||
                 getState() == LifecycleState.INITIALIZED) {
@@ -2221,12 +2221,12 @@ public class StandardContext extends Con
             // file
             // If started now, a second start will be attempted when the context
             // starts
-            
+
             // In both cases, return and let context init the namingResources
             // when it starts
             return;
         }
-        
+
         if (oldNamingResources != null) {
             try {
                 oldNamingResources.stop();
@@ -2257,7 +2257,7 @@ public class StandardContext extends Con
 
     /**
      * Set the context path for this Context.
-     * 
+     *
      * @param path The new context path
      */
     @Override
@@ -2362,7 +2362,7 @@ public class StandardContext extends Con
 
         this.originalDocBase = docBase;
     }
-    
+
 
     /**
      * Return the parent class loader (if any) for this web application.
@@ -2381,7 +2381,7 @@ public class StandardContext extends Con
         return (ClassLoader.getSystemClassLoader());
     }
 
-    
+
     /**
      * Return the privileged flag for this web application.
      */
@@ -2565,7 +2565,7 @@ public class StandardContext extends Con
     /**
      * Set the value of the unloadDelay flag, which represents the amount
      * of ms that the container will wait when unloading servlets.
-     * Setting this to a small value may cause more requests to fail 
+     * Setting this to a small value may cause more requests to fail
      * to complete when stopping a web application.
      *
      * @param unloadDelay The new value
@@ -2638,7 +2638,7 @@ public class StandardContext extends Con
         this.wrapperClassName = wrapperClassName;
 
         try {
-            wrapperClass = Class.forName(wrapperClassName);         
+            wrapperClass = Class.forName(wrapperClassName);
             if (!StandardWrapper.class.isAssignableFrom(wrapperClass)) {
                 throw new IllegalArgumentException(
                     sm.getString("standardContext.invalidWrapperClass",
@@ -2692,7 +2692,7 @@ public class StandardContext extends Con
 
     }
 
-    
+
     @Override
     public JspConfigDescriptor getJspConfigDescriptor() {
         return jspConfigDescriptor;
@@ -2750,9 +2750,9 @@ public class StandardContext extends Con
 
     /** Get the absolute path to the work dir.
      *  To avoid duplication.
-     * 
+     *
      * @return The work path
-     */ 
+     */
     public String getWorkPath() {
         if (getWorkDir() == null) {
             return null;
@@ -2772,7 +2772,7 @@ public class StandardContext extends Con
         }
         return workDir.getAbsolutePath();
     }
-    
+
     /**
      * Return the work directory for this Context.
      */
@@ -3192,7 +3192,7 @@ public class StandardContext extends Con
         fireContainerEvent("addFilterMap", filterMap);
     }
 
-    
+
     /**
      * Add a filter mapping to this Context before the mappings defined in the
      * deployment descriptor but after any other mappings added via this method.
@@ -3224,8 +3224,8 @@ public class StandardContext extends Con
             throw new IllegalArgumentException
                 (sm.getString("standardContext.filterMap.name", filterName));
 
-        if (!filterMap.getMatchAllServletNames() && 
-            !filterMap.getMatchAllUrlPatterns() && 
+        if (!filterMap.getMatchAllServletNames() &&
+            !filterMap.getMatchAllUrlPatterns() &&
             (servletNames.length == 0) && (urlPatterns.length == 0))
             throw new IllegalArgumentException
                 (sm.getString("standardContext.filterMap.either"));
@@ -3625,7 +3625,7 @@ public class StandardContext extends Con
         for (ApplicationListener applicationListener: applicationListeners) {
             list.add(applicationListener.getClassName());
         }
-        
+
         return list.toArray(new String[list.size()]);
 
     }
@@ -3775,8 +3775,8 @@ public class StandardContext extends Con
     public Context findMappingObject() {
         return (Context) getMappingObject();
     }
-    
-    
+
+
     /**
      * Return the message destination with the specified name, if any;
      * otherwise, return <code>null</code>.
@@ -4044,7 +4044,7 @@ public class StandardContext extends Con
 
 
     /**
-     * Return the set of watched resources for this Context. If none are 
+     * Return the set of watched resources for this Context. If none are
      * defined, a zero length array will be returned.
      */
     @Override
@@ -4053,8 +4053,8 @@ public class StandardContext extends Con
             return watchedResources;
         }
     }
-    
-    
+
+
     /**
      * Return the set of welcome files defined for this Context.  If none are
      * defined, a zero-length array is returned.
@@ -4531,12 +4531,12 @@ public class StandardContext extends Con
     /**
      * Remove the specified watched resource name from the list associated
      * with this Context.
-     * 
+     *
      * @param name Name of the watched resource to be removed
      */
     @Override
     public void removeWatchedResource(String name) {
-        
+
         synchronized (watchedResourcesLock) {
 
             // Make sure this watched resource is currently present
@@ -4564,8 +4564,8 @@ public class StandardContext extends Con
         fireContainerEvent("removeWatchedResource", name);
 
     }
-    
-    
+
+
     /**
      * Remove the specified welcome file name from the list recognized
      * by this Context.
@@ -4694,7 +4694,7 @@ public class StandardContext extends Con
      * StandardContext
      */
     public long getProcessingTime() {
-        
+
         long result = 0;
 
         Container[] children = findChildren();
@@ -4871,7 +4871,7 @@ public class StandardContext extends Con
         /**
          * Add a filter mapping at the end of the current set of filter
          * mappings.
-         * 
+         *
          * @param filterMap
          *            The filter mapping to be added
          */
@@ -4886,7 +4886,7 @@ public class StandardContext extends Con
         /**
          * Add a filter mapping before the mappings defined in the deployment
          * descriptor but after any other mappings added via this method.
-         * 
+         *
          * @param filterMap
          *            The filter mapping to be added
          */
@@ -5091,7 +5091,7 @@ public class StandardContext extends Con
         // Ensure context is not null
         getServletContext();
         context.setNewServletContextListenerAllowed(false);
-        
+
         Object instances[] = getApplicationLifecycleListeners();
         if (instances == null || instances.length == 0) {
             return ok;
@@ -5210,7 +5210,7 @@ public class StandardContext extends Con
                 }
             }
         }
-        
+
         setApplicationEventListeners(null);
         setApplicationLifecycleListeners(null);
 
@@ -5253,7 +5253,7 @@ public class StandardContext extends Con
                 ((BaseDirContext) webappResources).allocate();
                 // Alias support
                 ((BaseDirContext) webappResources).setAliases(getAliases());
-                
+
                 if (effectiveMajorVersion >=3 && addWebinfClassesResources) {
                     try {
                         DirContext webInfCtx =
@@ -5274,8 +5274,8 @@ public class StandardContext extends Con
                 if (!contextName.startsWith("/")) {
                     contextName = "/" + contextName;
                 }
-                ObjectName resourcesName = 
-                    new ObjectName(this.getDomain() + ":type=Cache,host=" 
+                ObjectName resourcesName =
+                    new ObjectName(this.getDomain() + ":type=Cache,host="
                                    + getHostname() + ",context=" + contextName);
                 Registry.getRegistry(null, null).registerComponent
                     (proxyDirContext.getCache(), resourcesName, null);
@@ -5313,10 +5313,10 @@ public class StandardContext extends Con
                     if (!contextName.startsWith("/")) {
                         contextName = "/" + contextName;
                     }
-                    ObjectName resourcesName = 
+                    ObjectName resourcesName =
                         new ObjectName(this.getDomain()
-                                       + ":type=Cache,host=" 
-                                       + getHostname() + ",context=" 
+                                       + ":type=Cache,host="
+                                       + getHostname() + ",context="
                                        + contextName);
                     Registry.getRegistry(null, null)
                         .unregisterComponent(resourcesName);
@@ -5397,7 +5397,7 @@ public class StandardContext extends Con
         if(log.isDebugEnabled())
             log.debug("Starting " + getBaseName());
 
-        // Send j2ee.state.starting notification 
+        // Send j2ee.state.starting notification
         if (this.getObjectName() != null) {
             Notification notification = new Notification("j2ee.state.starting",
                     this.getObjectName(), sequenceNumber.getAndIncrement());
@@ -5412,7 +5412,7 @@ public class StandardContext extends Con
         if (namingResources != null) {
             namingResources.start();
         }
-        
+
         // Add missing components as necessary
         if (webappResources == null) {   // (1) Required by Loader
             if (log.isDebugEnabled())
@@ -5481,19 +5481,19 @@ public class StandardContext extends Con
                 setNamingContextListener(ncl);
             }
         }
-        
+
         // Standard container startup
         if (log.isDebugEnabled())
             log.debug("Processing standard container startup");
 
-        
+
         // Binding thread
         ClassLoader oldCCL = bindThread();
 
         try {
 
             if (ok) {
-                
+
                 // Start our subordinate components, if any
                 if ((loader != null) && (loader instanceof Lifecycle))
                     ((Lifecycle) loader).start();
@@ -5509,7 +5509,7 @@ public class StandardContext extends Con
                 // too early, so it should be reset.
                 logger = null;
                 getLogger();
-                
+
                 if ((cluster != null) && (cluster instanceof Lifecycle))
                     ((Lifecycle) cluster).start();
                 Realm realm = getRealmInternal();
@@ -5520,7 +5520,7 @@ public class StandardContext extends Con
 
                 // Notify our interested LifecycleListeners
                 fireLifecycleEvent(Lifecycle.CONFIGURE_START_EVENT, null);
-                
+
                 // Start our child containers, if not already started
                 for (Container child : findChildren()) {
                     if (!child.getState().isAvailable()) {
@@ -5533,7 +5533,7 @@ public class StandardContext extends Con
                 if (pipeline instanceof Lifecycle) {
                     ((Lifecycle) pipeline).start();
                 }
-                
+
                 // Acquire clustered manager
                 Manager contextManager = null;
                 if (manager == null) {
@@ -5552,8 +5552,8 @@ public class StandardContext extends Con
                     } else {
                         contextManager = new StandardManager();
                     }
-                } 
-                
+                }
+
                 // Configure default manager if none was specified
                 if (contextManager != null) {
                     if (log.isDebugEnabled()) {
@@ -5636,7 +5636,7 @@ public class StandardContext extends Con
                     ok = false;
                 }
             }
-            
+
             try {
                 // Start manager
                 if ((manager != null) && (manager instanceof Lifecycle)) {
@@ -5654,7 +5654,7 @@ public class StandardContext extends Con
                     ok = false;
                 }
             }
-            
+
             // Load and initialize all "load on startup" servlets
             if (ok) {
                 if (!loadOnStartup(findChildren())){
@@ -5662,7 +5662,7 @@ public class StandardContext extends Con
                     ok = false;
                 }
             }
-            
+
             // Start ContainerBackgroundProcessor thread
             super.threadStart();
         } finally {
@@ -5679,16 +5679,16 @@ public class StandardContext extends Con
         }
 
         startTime=System.currentTimeMillis();
-        
-        // Send j2ee.state.running notification 
+
+        // Send j2ee.state.running notification
         if (ok && (this.getObjectName() != null)) {
-            Notification notification = 
+            Notification notification =
                 new Notification("j2ee.state.running", this.getObjectName(),
                                  sequenceNumber.getAndIncrement());
             broadcaster.sendNotification(notification);
         }
 
-        // Close all JARs right away to avoid always opening a peak number 
+        // Close all JARs right away to avoid always opening a peak number
         // of files on startup
         if (getLoader() instanceof WebappLoader) {
             ((WebappLoader) getLoader()).closeJARs(true);
@@ -5744,7 +5744,7 @@ public class StandardContext extends Con
         }
     }
 
-    
+
 
     /**
      * Merge the context initialization parameters specified in the application
@@ -5754,7 +5754,7 @@ public class StandardContext extends Con
      */
     private void mergeParameters() {
         Map<String,String> mergedParams = new HashMap<String,String>();
-        
+
         String names[] = findParameters();
         for (int i = 0; i < names.length; i++) {
             mergedParams.put(names[i], findParameter(names[i]));
@@ -5771,7 +5771,7 @@ public class StandardContext extends Con
                 mergedParams.put(params[i].getName(), params[i].getValue());
             }
         }
-        
+
         ServletContext sc = getServletContext();
         for (Map.Entry<String,String> entry : mergedParams.entrySet()) {
             sc.setInitParameter(entry.getKey(), entry.getValue());
@@ -5790,14 +5790,14 @@ public class StandardContext extends Con
     @Override
     protected synchronized void stopInternal() throws LifecycleException {
 
-        // Send j2ee.state.stopping notification 
+        // Send j2ee.state.stopping notification
         if (this.getObjectName() != null) {
-            Notification notification = 
-                new Notification("j2ee.state.stopping", this.getObjectName(), 
+            Notification notification =
+                new Notification("j2ee.state.stopping", this.getObjectName(),
                                  sequenceNumber.getAndIncrement());
             broadcaster.sendNotification(notification);
         }
-        
+
         setState(LifecycleState.STOPPING);
 
         // Binding thread
@@ -5807,7 +5807,7 @@ public class StandardContext extends Con
 
             // Stop our child containers, if any
             final Container[] children = findChildren();
-            
+
             ClassLoader old = bindThread();
             try {
                 // Stop ContainerBackgroundProcessor thread
@@ -5816,15 +5816,15 @@ public class StandardContext extends Con
                 for (int i = 0; i < children.length; i++) {
                     children[i].stop();
                 }
-            
+
                 // Stop our filters
                 filterStop();
-            
+
                 if (manager != null && manager instanceof Lifecycle &&
                         ((Lifecycle) manager).getState().isAvailable()) {
                     ((Lifecycle) manager).stop();
                 }
-            
+
                 // Stop our application listeners
                 listenerStop();
             } finally{
@@ -5841,11 +5841,11 @@ public class StandardContext extends Con
             // JNDI resources are unbound in CONFIGURE_STOP_EVENT so stop
             // naming resources before they are unbound since NamingResources
             // does a JNDI lookup to retrieve the resource. This needs to be
-            // after the application has finished with the resource 
+            // after the application has finished with the resource
             if (namingResources != null) {
                 namingResources.stop();
             }
-            
+
             fireLifecycleEvent(Lifecycle.CONFIGURE_STOP_EVENT, null);
 
             // Stop the Valves in our pipeline (including the basic), if any
@@ -5879,24 +5879,24 @@ public class StandardContext extends Con
 
         }
 
-        // Send j2ee.state.stopped notification 
+        // Send j2ee.state.stopped notification
         if (this.getObjectName() != null) {
-            Notification notification = 
-                new Notification("j2ee.state.stopped", this.getObjectName(), 
+            Notification notification =
+                new Notification("j2ee.state.stopped", this.getObjectName(),
                                 sequenceNumber.getAndIncrement());
             broadcaster.sendNotification(notification);
         }
-        
+
         // Reset application context
         context = null;
 
-        // This object will no longer be visible or used. 
+        // This object will no longer be visible or used.
         try {
             resetContext();
         } catch( Exception ex ) {
             log.error( "Error resetting context " + this + " " + ex, ex );
         }
-        
+
         //reset the instance manager
         setInstanceManager(null);
 
@@ -5906,26 +5906,26 @@ public class StandardContext extends Con
     }
 
     /** Destroy needs to clean up the context completely.
-     * 
-     * The problem is that undoing all the config in start() and restoring 
+     *
+     * The problem is that undoing all the config in start() and restoring
      * a 'fresh' state is impossible. After stop()/destroy()/init()/start()
      * we should have the same state as if a fresh start was done - i.e
-     * read modified web.xml, etc. This can only be done by completely 
+     * read modified web.xml, etc. This can only be done by completely
      * removing the context object and remapping a new one, or by cleaning
      * up everything.
-     * 
+     *
      * XXX Should this be done in stop() ?
-     * 
-     */ 
+     *
+     */
     @Override
     protected void destroyInternal() throws LifecycleException {
-        
+
         // If in state NEW when destroy is called, the object name will never
         // have been set so the notification can't be created
-        if (getObjectName() != null) { 
-            // Send j2ee.object.deleted notification 
-            Notification notification = 
-                new Notification("j2ee.object.deleted", this.getObjectName(), 
+        if (getObjectName() != null) {
+            // Send j2ee.object.deleted notification
+            Notification notification =
+                new Notification("j2ee.object.deleted", this.getObjectName(),
                                  sequenceNumber.getAndIncrement());
             broadcaster.sendNotification(notification);
         }
@@ -5940,11 +5940,29 @@ public class StandardContext extends Con
 
         super.destroyInternal();
     }
-    
+
+
+    @Override
+    public void backgroundProcess() {
+
+        InstanceManager instanceManager = getInstanceManager();
+        if (instanceManager instanceof DefaultInstanceManager) {
+            try {
+                ((DefaultInstanceManager)instanceManager).backgroundProcess();
+            } catch (Exception e) {
+                log.warn(sm.getString(
+                        "standardContext.backgroundProcess.instanceManager",
+                        resources), e);
+            }
+        }
+        super.backgroundProcess();
+    }
+
+
     private void resetContext() throws Exception {
         // Restore the original state ( pre reading web.xml in start )
         // If you extend this - override this method and make sure to clean up
-        
+
         // Don't reset anything that is read from a <Context.../> element since
         // <Context .../> elements are read at initialisation will not be read
         // again for this object
@@ -5962,9 +5980,9 @@ public class StandardContext extends Con
         applicationEventListenersObjects = new Object[0];
         applicationLifecycleListenersObjects = new Object[0];
         jspConfigDescriptor = new ApplicationJspConfigDescriptor();
-        
+
         initializers.clear();
-        
+
         createdServlets.clear();
 
         postConstructMethods.clear();
@@ -6234,14 +6252,14 @@ public class StandardContext extends Con
     return namingContextName;
     }
 
-    
+
     /**
      * Naming context listener accessor.
      */
     public NamingContextListener getNamingContextListener() {
         return namingContextListener;
     }
-    
+
 
     /**
      * Naming context listener setter.
@@ -6249,7 +6267,7 @@ public class StandardContext extends Con
     public void setNamingContextListener(NamingContextListener namingContextListener) {
         this.namingContextListener = namingContextListener;
     }
-    
+
 
     /**
      * Return the request processing paused flag for this Context.
@@ -6284,7 +6302,7 @@ public class StandardContext extends Con
 
         if ((instances != null) && (instances.length > 0)) {
 
-            ServletRequestEvent event = 
+            ServletRequestEvent event =
                     new ServletRequestEvent(getServletContext(), request);
 
             for (int i = 0; i < instances.length; i++) {
@@ -6294,7 +6312,7 @@ public class StandardContext extends Con
                     continue;
                 ServletRequestListener listener =
                     (ServletRequestListener) instances[i];
-                
+
                 try {
                     listener.requestInitialized(event);
                 } catch (Throwable t) {
@@ -6317,7 +6335,7 @@ public class StandardContext extends Con
 
         if ((instances != null) && (instances.length > 0)) {
 
-            ServletRequestEvent event = 
+            ServletRequestEvent event =
                 new ServletRequestEvent(getServletContext(), request);
 
             for (int i = 0; i < instances.length; i++) {
@@ -6328,7 +6346,7 @@ public class StandardContext extends Con
                     continue;
                 ServletRequestListener listener =
                     (ServletRequestListener) instances[j];
-                
+
                 try {
                     listener.requestDestroyed(event);
                 } catch (Throwable t) {
@@ -6554,10 +6572,10 @@ public class StandardContext extends Con
     /**
      * JSR77 deploymentDescriptor attribute
      *
-     * @return string deployment descriptor 
+     * @return string deployment descriptor
      */
     public String getDeploymentDescriptor() {
-    
+
         InputStream stream = null;
         ServletContext servletContext = getServletContext();
         if (servletContext != null) {
@@ -6586,17 +6604,17 @@ public class StandardContext extends Con
             }
         }
 
-        return sb.toString(); 
+        return sb.toString();
     }
-    
-    
+
+
     /**
      * JSR77 servlets attribute
      *
      * @return list of all servlets ( we know about )
      */
     public String[] getServlets() {
-        
+
         String[] result = null;
 
         Container[] children = findChildren();
@@ -6609,7 +6627,7 @@ public class StandardContext extends Con
 
         return result;
     }
-    
+
 
     @Override
     protected String getObjectNameKeyProperties() {
@@ -6624,7 +6642,7 @@ public class StandardContext extends Con
 
         return keyProperties.toString();
     }
-    
+
     private String getObjectKeyPropertiesNameOnly() {
         StringBuilder result = new StringBuilder("name=//");
         String hostname = getParent().getName();
@@ -6633,7 +6651,7 @@ public class StandardContext extends Con
         } else {
             result.append(hostname);
         }
-        
+
         String contextName = getName();
         if (!contextName.startsWith("/")) {
             result.append('/');
@@ -6646,7 +6664,7 @@ public class StandardContext extends Con
     @Override
     protected void initInternal() throws LifecycleException {
         super.initInternal();
-        
+
         if (processTlds) {
             this.addLifecycleListener(new TldConfig());
         }
@@ -6656,7 +6674,7 @@ public class StandardContext extends Con
             namingResources.init();
         }
 
-        // Send j2ee.object.created notification 
+        // Send j2ee.object.created notification
         if (this.getObjectName() != null) {
             Notification notification = new Notification("j2ee.object.created",
                     this.getObjectName(), sequenceNumber.getAndIncrement());
@@ -6665,17 +6683,17 @@ public class StandardContext extends Con
     }
 
 
-    /* Remove a JMX notificationListener 
+    /* Remove a JMX notificationListener
      * @see javax.management.NotificationEmitter#removeNotificationListener(javax.management.NotificationListener, javax.management.NotificationFilter, java.lang.Object)
      */
     @Override
-    public void removeNotificationListener(NotificationListener listener, 
+    public void removeNotificationListener(NotificationListener listener,
             NotificationFilter filter, Object object) throws ListenerNotFoundException {
         broadcaster.removeNotificationListener(listener,filter,object);
     }
-    
+
     private MBeanNotificationInfo[] notificationInfo;
-    
+
     /* Get JMX Broadcaster Info
      * @TODO use StringManager for international support!
      * @TODO This two events we not send j2ee.state.failed and j2ee.attribute.changed!
@@ -6690,7 +6708,7 @@ public class StandardContext extends Con
                     "j2ee.object.created"},
                     Notification.class.getName(),
                     "web application is created"
-                    ), 
+                    ),
                     new MBeanNotificationInfo(new String[] {
                     "j2ee.state.starting"},
                     Notification.class.getName(),
@@ -6717,34 +6735,34 @@ public class StandardContext extends Con
                     "web application is deleted"
                     )
             };
-            
+
         }
-        
+
         return notificationInfo;
     }
-    
-    
+
+
     /* Add a JMX-NotificationListener
      * @see javax.management.NotificationBroadcaster#addNotificationListener(javax.management.NotificationListener, javax.management.NotificationFilter, java.lang.Object)
      */
     @Override
-    public void addNotificationListener(NotificationListener listener, 
+    public void addNotificationListener(NotificationListener listener,
             NotificationFilter filter, Object object) throws IllegalArgumentException {
         broadcaster.addNotificationListener(listener,filter,object);
     }
-    
-    
+
+
     /**
-     * Remove a JMX-NotificationListener 
+     * Remove a JMX-NotificationListener
      * @see javax.management.NotificationBroadcaster#removeNotificationListener(javax.management.NotificationListener)
      */
     @Override
-    public void removeNotificationListener(NotificationListener listener) 
+    public void removeNotificationListener(NotificationListener listener)
     throws ListenerNotFoundException {
         broadcaster.removeNotificationListener(listener);
     }
-    
-    
+
+
     // ------------------------------------------------------------- Attributes
 
 
@@ -6761,7 +6779,7 @@ public class StandardContext extends Con
 
     /**
      * Return the naming resources associated with this web application.
-     * FIXME: Fooling introspection ... 
+     * FIXME: Fooling introspection ...
      */
     @Deprecated
     public javax.naming.directory.DirContext findStaticResources() {
@@ -6780,7 +6798,7 @@ public class StandardContext extends Con
 
     }
 
-    
+
     @Override
     public boolean getXmlNamespaceAware(){
         return webXmlNamespaceAware;
@@ -6790,7 +6808,7 @@ public class StandardContext extends Con
     @Override
     public void setXmlNamespaceAware(boolean webXmlNamespaceAware){
         this.webXmlNamespaceAware = webXmlNamespaceAware;
-    }    
+    }
 
 
     @Override
@@ -6814,7 +6832,7 @@ public class StandardContext extends Con
     @Override
     public void setTldNamespaceAware(boolean tldNamespaceAware){
         // NO-OP;
-    }    
+    }
 
 
     @Override
@@ -6859,60 +6877,60 @@ public class StandardContext extends Con
     }
 
 
-    /** 
-     * Support for "stateManageable" JSR77 
+    /**
+     * Support for "stateManageable" JSR77
      */
     public boolean isStateManageable() {
         return true;
     }
-    
+
     @Deprecated
     public void startRecursive() throws LifecycleException {
         // nothing to start recursive, the servlets will be started by load-on-startup
         start();
     }
-    
+
     /**
      * The J2EE Server ObjectName this module is deployed on.
-     */     
+     */
     private String server = null;
-    
+
     /**
      * The Java virtual machines on which this module is running.
-     */       
+     */
     private String[] javaVMs = null;
-    
+
     public String getServer() {
         return server;
     }
-        
+
     public String setServer(String server) {
         return this.server=server;
     }
-        
+
     public String[] getJavaVMs() {
         return javaVMs;
     }
-        
+
     public String[] setJavaVMs(String[] javaVMs) {
         return this.javaVMs = javaVMs;
     }
-    
+
     /**
      * Gets the time this context was started.
      *
      * @return Time (in milliseconds since January 1, 1970, 00:00:00) when this
-     * context was started 
+     * context was started
      */
     public long getStartTime() {
         return startTime;
     }
-    
+
     @Deprecated
     public boolean isEventProvider() {
         return false;
     }
-    
+
     @Deprecated
     public boolean isStatisticsProvider() {
         return false;

Copied: tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/collections/ManagedConcurrentWeakHashMap.java (from r1780264, tomcat/tc8.0.x/trunk/java/org/apache/tomcat/util/collections/ManagedConcurrentWeakHashMap.java)
URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/collections/ManagedConcurrentWeakHashMap.java?p2=tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/collections/ManagedConcurrentWeakHashMap.java&p1=tomcat/tc8.0.x/trunk/java/org/apache/tomcat/util/collections/ManagedConcurrentWeakHashMap.java&r1=1780264&r2=1780267&rev=1780267&view=diff
==============================================================================
--- tomcat/tc8.0.x/trunk/java/org/apache/tomcat/util/collections/ManagedConcurrentWeakHashMap.java (original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/collections/ManagedConcurrentWeakHashMap.java Wed Jan 25 20:23:21 2017
@@ -37,8 +37,8 @@ import java.util.concurrent.ConcurrentMa
 public class ManagedConcurrentWeakHashMap<K, V> extends AbstractMap<K, V> implements
         ConcurrentMap<K, V> {
 
-    private final ConcurrentMap<Key, V> map = new ConcurrentHashMap<>();
-    private final ReferenceQueue<Object> queue = new ReferenceQueue<>();
+    private final ConcurrentMap<Key, V> map = new ConcurrentHashMap<Key, V>();
+    private final ReferenceQueue<Object> queue = new ReferenceQueue<Object>();
 
     /**
      * Method, that has to be invoked periodically to clean dead keys from the

Modified: tomcat/tc7.0.x/trunk/test/org/apache/catalina/core/TestDefaultInstanceManager.java
URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/test/org/apache/catalina/core/TestDefaultInstanceManager.java?rev=1780267&r1=1780266&r2=1780267&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/test/org/apache/catalina/core/TestDefaultInstanceManager.java (original)
+++ tomcat/tc7.0.x/trunk/test/org/apache/catalina/core/TestDefaultInstanceManager.java Wed Jan 25 20:23:21 2017
@@ -19,11 +19,16 @@ package org.apache.catalina.core;
 import java.io.File;
 
 import static org.junit.Assert.assertEquals;
+
+import org.junit.Ignore;
 import org.junit.Test;
 
+import org.apache.catalina.Context;
 import org.apache.catalina.Wrapper;
+import org.apache.catalina.servlets.DefaultServlet;
 import org.apache.catalina.startup.Tomcat;
 import org.apache.catalina.startup.TomcatBaseTest;
+import org.apache.tomcat.InstanceManager;
 
 
 public class TestDefaultInstanceManager extends TomcatBaseTest {
@@ -52,6 +57,7 @@ public class TestDefaultInstanceManager
         // Spin a while until GC happens or we wait too long
         int loop = 0;
         while (loop < 10) {
+            instanceManager.backgroundProcess();
             if (instanceManager.getAnnotationCacheSize() == count) {
                 break;
             }
@@ -83,4 +89,70 @@ public class TestDefaultInstanceManager
 
         return (DefaultInstanceManager) ctxt.getInstanceManager();
     }
+
+
+    /*
+     * Performance test. Comment out @Ignore to run the test.
+     */
+    @Ignore
+    @Test
+    public void testConcurrency() throws Exception {
+        // Create a populated InstanceManager
+        Tomcat tomcat = getTomcatInstance();
+        Context ctx = tomcat.addContext(null, "", null);
+
+        tomcat.start();
+
+        InstanceManager im = ctx.getInstanceManager();
+
+        for (int i = 1; i < 9; i++) {
+            doTestConcurrency(im, i);
+        }
+    }
+
+
+    private void doTestConcurrency(InstanceManager im, int threadCount) throws Exception {
+        long start = System.nanoTime();
+
+        Thread[] threads = new Thread[threadCount];
+
+        for (int i = 0; i < threadCount; i++) {
+            threads[i] = new Thread(new InstanceManagerRunnable(im));
+        }
+
+        for (int i = 0; i < threadCount; i++) {
+            threads[i].start();
+        }
+
+        for (int i = 0; i < threadCount; i++) {
+            threads[i].join();
+        }
+
+        long duration = System.nanoTime() - start;
+
+        System.out.println(threadCount + " threads completed in " + duration + "ns");
+    }
+
+
+    private class InstanceManagerRunnable implements Runnable {
+
+        private final InstanceManager im;
+
+        private InstanceManagerRunnable(InstanceManager im) {
+            this.im = im;
+        }
+
+        @Override
+        public void run() {
+            try {
+                Object test = new DefaultServlet();
+                for (int i = 0; i < 200000; i++) {
+                    im.newInstance(test);
+                    im.destroyInstance(test);
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+    }
 }

Modified: tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml
URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml?rev=1780267&r1=1780266&r2=1780267&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml Wed Jan 25 20:23:21 2017
@@ -66,6 +66,11 @@
         <code>getDefaultWebXmlListener()</code>. Patch provided by Aaron
         Anderson. (markt)
       </scode>
+      <fix>
+        Reduce the contention in the default <code>InstanceManager</code>
+        implementation when multiple threads are managing objects and need to
+        reference the annotation cache. (markt)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="WebSocket">



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