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-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org