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 2010/10/27 00:09:20 UTC
svn commit: r1027760 - in /tomcat/trunk: java/org/apache/catalina/connector/
java/org/apache/catalina/core/ java/org/apache/catalina/mbeans/ webapps/docs/
Author: markt
Date: Tue Oct 26 22:09:20 2010
New Revision: 1027760
URL: http://svn.apache.org/viewvc?rev=1027760&view=rev
Log:
Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=50157
Ensure MapperListener is only added to a container object once.
Also
- Improve debug logging for MapperListener registration.
- Expose names of LifecycleListeners and ContainerListers for StandardContext via JMX.
Modified:
tomcat/trunk/java/org/apache/catalina/connector/LocalStrings.properties
tomcat/trunk/java/org/apache/catalina/connector/MapperListener.java
tomcat/trunk/java/org/apache/catalina/core/mbeans-descriptors.xml
tomcat/trunk/java/org/apache/catalina/mbeans/ContainerMBean.java
tomcat/trunk/webapps/docs/changelog.xml
Modified: tomcat/trunk/java/org/apache/catalina/connector/LocalStrings.properties
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/LocalStrings.properties?rev=1027760&r1=1027759&r2=1027760&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/connector/LocalStrings.properties (original)
+++ tomcat/trunk/java/org/apache/catalina/connector/LocalStrings.properties Tue Oct 26 22:09:20 2010
@@ -73,12 +73,13 @@ cometEvent.nullRequest=The event object
#
# MapperListener
#
-mapperListener.unknownDefaultHost=Unknown default host: {0}
-mapperListener.registerHost=Register host {0} at domain {1}
-mapperListener.unregisterHost=Unregister host {0} at domain {1}
-mapperListener.registerContext=Register Context {0}
-mapperListener.unregisterContext=Unregister Context {0}
-mapperListener.registerWrapper=Register Wrapper {0} in Context {1}
+mapperListener.unknownDefaultHost=Unknown default host [{0}] for connector [{1}]
+mapperListener.registerHost=Register host [{0}] at domain [{1}] for connector [{2}]
+mapperListener.unregisterHost=Unregister host [{0}] at domain [{1}] for connector [{2}]
+mapperListener.registerContext=Register Context [{0}] for connector [{1}]
+mapperListener.unregisterContext=Unregister Context [{0}] for connector [{1}]
+mapperListener.registerWrapper=Register Wrapper [{0}] in Context [{1}] for connector [{2}]
+mapperListener.unregisterWrapper=Unregister Wrapper [{0}] in Context [{1}] for connector [{2}]
mapperListener.addMBeanListenerFail=Failed to add MBean notification listener for connector [{0}] in domain [{1}]. Adding Hosts, Contexts and Wrappers will not be visible to the connector.
mapperListener.removeMBeanListenerFail=Failed to remove MBean notification listener for connector [{0}] in domain [{1}]. This may result in a memory leak.
mapperListener.lifecycleListenerFail=Failed to add Lifecycle listener to object [{0}]. Changes in the object state may not be correctly reflected in the mapper for connector [{1}] in domain [{2}].
Modified: tomcat/trunk/java/org/apache/catalina/connector/MapperListener.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/MapperListener.java?rev=1027760&r1=1027759&r2=1027760&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/connector/MapperListener.java (original)
+++ tomcat/trunk/java/org/apache/catalina/connector/MapperListener.java Tue Oct 26 22:09:20 2010
@@ -101,13 +101,12 @@ public class MapperListener implements C
findDefaultHost();
Engine engine = (Engine) connector.getService().getContainer();
- engine.addContainerListener(this);
+ addListeners(engine);
Container[] conHosts = engine.findChildren();
for (Container conHost : conHosts) {
Host host = (Host) conHost;
if (!LifecycleState.NEW.equals(host.getState())) {
- host.addLifecycleListener(this);
// Registering the host will register the context and wrappers
registerHost(host);
}
@@ -125,29 +124,28 @@ public class MapperListener implements C
// --------------------------------------------- Container Listener methods
+ @Override
public void containerEvent(ContainerEvent event) {
if (event.getType() == Container.ADD_CHILD_EVENT) {
Container child = (Container) event.getData();
- child.addLifecycleListener(this);
- child.addContainerListener(this);
- if (child instanceof Host) {
- registerHost((Host) child);
- } else if (child instanceof Context) {
- registerContext((Context) child);
- } else if (child instanceof Wrapper) {
- registerWrapper((Wrapper) child);
+ addListeners(child);
+ // If child is started then it is too late for life-cycle listener
+ // to register the child so register it here
+ if (child.getState().isAvailable()) {
+ if (child instanceof Host) {
+ registerHost((Host) child);
+ } else if (child instanceof Context) {
+ registerContext((Context) child);
+ } else if (child instanceof Wrapper) {
+ registerWrapper((Wrapper) child);
+ }
}
} else if (event.getType() == Container.REMOVE_CHILD_EVENT) {
Container child = (Container) event.getData();
removeListeners(child);
- if (child instanceof Host) {
- unregisterHost((Host) child);
- } else if (child instanceof Context) {
- unregisterContext((Context) child);
- } else if (child instanceof Wrapper) {
- unregisterWrapper((Wrapper) child);
- }
+ // No need to unregister - life-cycle listener will handle this when
+ // the child stops
} else if (event.getType() == Host.ADD_ALIAS_EVENT) {
// Handle dynamically adding host aliases
mapper.addHostAlias(((Host) event.getSource()).getName(),
@@ -260,7 +258,7 @@ public class MapperListener implements C
mapper.setDefaultHostName(defaultHost);
} else {
log.warn(sm.getString("mapperListener.unknownDefaultHost",
- defaultHost));
+ defaultHost, connector));
}
}
@@ -273,14 +271,12 @@ public class MapperListener implements C
String[] aliases = host.findAliases();
mapper.addHost(host.getName(), aliases, host);
- host.addContainerListener(this);
-
for (Container container : host.findChildren()) {
registerContext((Context) container);
}
if(log.isDebugEnabled()) {
- log.debug(sm.getString
- ("mapperListener.registerHost", host.getName(), domain));
+ log.debug(sm.getString("mapperListener.registerHost",
+ host.getName(), domain, connector));
}
}
@@ -296,7 +292,7 @@ public class MapperListener implements C
if(log.isDebugEnabled())
log.debug(sm.getString("mapperListener.unregisterHost", hostname,
- domain));
+ domain, connector));
}
@@ -306,6 +302,8 @@ public class MapperListener implements C
private void unregisterWrapper(Wrapper wrapper) {
String contextName = wrapper.getParent().getName();
+ String wrapperName = wrapper.getName();
+
if ("/".equals(contextName)) {
contextName = "";
}
@@ -316,6 +314,11 @@ public class MapperListener implements C
for (String mapping : mappings) {
mapper.removeWrapper(hostName, contextName, mapping);
}
+
+ if(log.isDebugEnabled()) {
+ log.debug(sm.getString("mapperListener.unregisterWrapper",
+ wrapperName, contextName, connector));
+ }
}
@@ -336,15 +339,13 @@ public class MapperListener implements C
mapper.addContext(host.getName(), host, contextName, context,
welcomeFiles, resources);
- context.addContainerListener(this);
-
for (Container container : context.findChildren()) {
registerWrapper((Wrapper) container);
}
if(log.isDebugEnabled()) {
- log.debug(sm.getString
- ("mapperListener.registerContext", contextName));
+ log.debug(sm.getString("mapperListener.registerContext",
+ contextName, connector));
}
}
@@ -366,8 +367,8 @@ public class MapperListener implements C
String hostName = context.getParent().getName();
if(log.isDebugEnabled())
- log.debug(sm.getString
- ("mapperListener.unregisterContext", contextName));
+ log.debug(sm.getString("mapperListener.unregisterContext",
+ contextName, connector));
mapper.removeContext(hostName, contextName);
}
@@ -394,11 +395,9 @@ public class MapperListener implements C
jspWildCard);
}
- wrapper.addContainerListener(this);
-
if(log.isDebugEnabled()) {
log.debug(sm.getString("mapperListener.registerWrapper",
- wrapperName, contextName));
+ wrapperName, contextName, connector));
}
}
@@ -425,6 +424,21 @@ public class MapperListener implements C
}
}
+
+ /**
+ * Add this mapper to the container and all child containers
+ *
+ * @param container
+ */
+ private void addListeners(Container container) {
+ container.addContainerListener(this);
+ container.addLifecycleListener(this);
+ for (Container child : container.findChildren()) {
+ addListeners(child);
+ }
+ }
+
+
/**
* Remove this mapper from the container and all child containers
*
Modified: tomcat/trunk/java/org/apache/catalina/core/mbeans-descriptors.xml
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/mbeans-descriptors.xml?rev=1027760&r1=1027759&r2=1027760&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/core/mbeans-descriptors.xml (original)
+++ tomcat/trunk/java/org/apache/catalina/core/mbeans-descriptors.xml Tue Oct 26 22:09:20 2010
@@ -583,6 +583,12 @@
returnType="java.lang.String">
</operation>
+ <operation name="findContainerListenerNames"
+ description="Return the set of container listener class names configured for this application."
+ impact="INFO"
+ returnType="[Ljava.lang.String;">
+ </operation>
+
<operation name="findErrorPage"
description="Return the error page entry for the specified HTTP error code, if any; otherwise return null"
impact="ACTION"
@@ -634,6 +640,12 @@
returnType="[Ljava.lang.String;">
</operation>
+ <operation name="findLifecycleListenerNames"
+ description="Return the set of lifecycle listener class names configured for this application."
+ impact="INFO"
+ returnType="[Ljava.lang.String;">
+ </operation>
+
<operation name="findMimeMapping"
description="Return the MIME type to which the specified extension is mapped, if any; otherwise return null."
impact="ACTION"
Modified: tomcat/trunk/java/org/apache/catalina/mbeans/ContainerMBean.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/mbeans/ContainerMBean.java?rev=1027760&r1=1027759&r2=1027760&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/mbeans/ContainerMBean.java (original)
+++ tomcat/trunk/java/org/apache/catalina/mbeans/ContainerMBean.java Tue Oct 26 22:09:20 2010
@@ -17,6 +17,9 @@
package org.apache.catalina.mbeans;
+import java.util.ArrayList;
+import java.util.List;
+
import javax.management.InstanceNotFoundException;
import javax.management.MBeanException;
import javax.management.MalformedObjectNameException;
@@ -25,6 +28,7 @@ import javax.management.RuntimeOperation
import javax.management.modelmbean.InvalidTargetObjectTypeException;
import org.apache.catalina.Container;
+import org.apache.catalina.ContainerListener;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.LifecycleListener;
import org.apache.catalina.Valve;
@@ -265,4 +269,57 @@ public class ContainerMBean extends Base
}
}
+
+ /**
+ * List the class name of each of the lifecycle listeners added to this
+ * container.
+ */
+ public String[] findLifecycleListenerNames() throws MBeanException {
+ ContainerBase container = null;
+ List<String> result = new ArrayList<String>();
+
+ try {
+ container = (ContainerBase) getManagedResource();
+ } catch (InstanceNotFoundException e) {
+ throw new MBeanException(e);
+ } catch (RuntimeOperationsException e) {
+ throw new MBeanException(e);
+ } catch (InvalidTargetObjectTypeException e) {
+ throw new MBeanException(e);
+ }
+
+ LifecycleListener[] listeners = container.findLifecycleListeners();
+ for(LifecycleListener listener: listeners){
+ result.add(listener.getClass().getName());
+ }
+
+ return result.toArray(new String[result.size()]);
+ }
+
+
+ /**
+ * List the class name of each of the container listeners added to this
+ * container.
+ */
+ public String[] findContainerListenerNames() throws MBeanException {
+ ContainerBase container = null;
+ List<String> result = new ArrayList<String>();
+
+ try {
+ container = (ContainerBase) getManagedResource();
+ } catch (InstanceNotFoundException e) {
+ throw new MBeanException(e);
+ } catch (RuntimeOperationsException e) {
+ throw new MBeanException(e);
+ } catch (InvalidTargetObjectTypeException e) {
+ throw new MBeanException(e);
+ }
+
+ ContainerListener[] listeners = container.findContainerListeners();
+ for(ContainerListener listener: listeners){
+ result.add(listener.getClass().getName());
+ }
+
+ return result.toArray(new String[result.size()]);
+ }
}
Modified: tomcat/trunk/webapps/docs/changelog.xml
URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1027760&r1=1027759&r2=1027760&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/trunk/webapps/docs/changelog.xml Tue Oct 26 22:09:20 2010
@@ -57,6 +57,17 @@
<bug>50138</bug>: Fix threading issues in
<code>org.apache.catalina.security.SecurityUtil</code>. (markt)
</fix>
+ <fix>
+ <bug>50157</bug>: Ensure MapperListener is only added to a container
+ object once. (markt)
+ </fix>
+ <add>
+ Improve debug logging for MapperListener registration. (markt)
+ </add>
+ <add>
+ Expose names of LifecycleListeners and ContainerListers for
+ StandardContext via JMX. (markt)
+ </add>
</changelog>
</subsection>
<subsection name="Jasper">
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org