Author: markt Date: Wed Jun 12 18:31:30 2013 New Revision: 1492331 URL: http://svn.apache.org/r1492331 Log: With clarification from the EG for Servlet 3.1 section 4.4 finally makes sense. Implement the necessary restriction and add a test case.
Added: tomcat/tc7.0.x/trunk/java/org/apache/catalina/deploy/ApplicationListener.java - copied unchanged from r1492307, tomcat/trunk/java/org/apache/catalina/deploy/ApplicationListener.java tomcat/tc7.0.x/trunk/test/org/apache/catalina/core/TesterTldListener.java - copied unchanged from r1492307, tomcat/trunk/test/org/apache/catalina/core/TesterTldListener.java tomcat/tc7.0.x/trunk/test/webapp-3.0/WEB-INF/listener.tld - copied unchanged from r1492307, tomcat/trunk/test/webapp-3.0/WEB-INF/listener.tld Modified: tomcat/tc7.0.x/trunk/ (props changed) tomcat/tc7.0.x/trunk/java/javax/servlet/ServletContext.java tomcat/tc7.0.x/trunk/java/org/apache/catalina/Context.java tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/LocalStrings.properties tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/StandardContext.java tomcat/tc7.0.x/trunk/java/org/apache/catalina/deploy/WebXml.java tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/FailedContext.java tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/TldConfig.java tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/WebAnnotationSet.java tomcat/tc7.0.x/trunk/test/org/apache/catalina/core/TestAsyncContextImpl.java tomcat/tc7.0.x/trunk/test/org/apache/catalina/core/TestNamingContextListener.java tomcat/tc7.0.x/trunk/test/org/apache/catalina/core/TestStandardContext.java tomcat/tc7.0.x/trunk/test/org/apache/catalina/core/TesterContext.java tomcat/tc7.0.x/trunk/test/org/apache/catalina/startup/TestListener.java Propchange: tomcat/tc7.0.x/trunk/ ------------------------------------------------------------------------------ Merged /tomcat/trunk:r1492307 Modified: tomcat/tc7.0.x/trunk/java/javax/servlet/ServletContext.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/javax/servlet/ServletContext.java?rev=1492331&r1=1492330&r2=1492331&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/java/javax/servlet/ServletContext.java (original) +++ tomcat/tc7.0.x/trunk/java/javax/servlet/ServletContext.java Wed Jun 12 18:31:30 2013 @@ -105,14 +105,27 @@ public interface ServletContext { /** * @return TODO - * @throws UnsupportedOperationException + * @throws UnsupportedOperationException If called from a + * {@link ServletContextListener#contextInitialized(ServletContextEvent)} + * method of a {@link ServletContextListener} that was not defined in a + * web.xml file, a web-fragment.xml file nor annotated with + * {@link javax.servlet.annotation.WebListener}. For example, a + * {@link ServletContextListener} defined in a TLD would not be able to + * use this method. + * * @since Servlet 3.0 TODO SERVLET3 - Add comments */ public int getEffectiveMajorVersion(); /** * @return TODO - * @throws UnsupportedOperationException + * @throws UnsupportedOperationException If called from a + * {@link ServletContextListener#contextInitialized(ServletContextEvent)} + * method of a {@link ServletContextListener} that was not defined in a + * web.xml file, a web-fragment.xml file nor annotated with + * {@link javax.servlet.annotation.WebListener}. For example, a + * {@link ServletContextListener} defined in a TLD would not be able to + * use this method. * @since Servlet 3.0 TODO SERVLET3 - Add comments */ public int getEffectiveMinorVersion(); @@ -429,7 +442,13 @@ public interface ServletContext { * @param value * @return TODO * @throws IllegalStateException - * @throws UnsupportedOperationException + * @throws UnsupportedOperationException If called from a + * {@link ServletContextListener#contextInitialized(ServletContextEvent)} + * method of a {@link ServletContextListener} that was not defined in a + * web.xml file, a web-fragment.xml file nor annotated with + * {@link javax.servlet.annotation.WebListener}. For example, a + * {@link ServletContextListener} defined in a TLD would not be able to + * use this method. * @since Servlet 3.0 TODO SERVLET3 - Add comments */ public boolean setInitParameter(String name, String value); @@ -518,6 +537,13 @@ public interface ServletContext { * @return TODO * @throws IllegalStateException * If the context has already been initialised + * @throws UnsupportedOperationException If called from a + * {@link ServletContextListener#contextInitialized(ServletContextEvent)} + * method of a {@link ServletContextListener} that was not defined in a + * web.xml file, a web-fragment.xml file nor annotated with + * {@link javax.servlet.annotation.WebListener}. For example, a + * {@link ServletContextListener} defined in a TLD would not be able to + * use this method. * @since Servlet 3.0 TODO SERVLET3 - Add comments */ public ServletRegistration.Dynamic addServlet(String servletName, @@ -529,6 +555,13 @@ public interface ServletContext { * @return TODO * @throws IllegalStateException * If the context has already been initialised + * @throws UnsupportedOperationException If called from a + * {@link ServletContextListener#contextInitialized(ServletContextEvent)} + * method of a {@link ServletContextListener} that was not defined in a + * web.xml file, a web-fragment.xml file nor annotated with + * {@link javax.servlet.annotation.WebListener}. For example, a + * {@link ServletContextListener} defined in a TLD would not be able to + * use this method. * @since Servlet 3.0 TODO SERVLET3 - Add comments */ public ServletRegistration.Dynamic addServlet(String servletName, @@ -540,6 +573,13 @@ public interface ServletContext { * @return TODO * @throws IllegalStateException * If the context has already been initialised + * @throws UnsupportedOperationException If called from a + * {@link ServletContextListener#contextInitialized(ServletContextEvent)} + * method of a {@link ServletContextListener} that was not defined in a + * web.xml file, a web-fragment.xml file nor annotated with + * {@link javax.servlet.annotation.WebListener}. For example, a + * {@link ServletContextListener} defined in a TLD would not be able to + * use this method. * @since Servlet 3.0 TODO SERVLET3 - Add comments */ public ServletRegistration.Dynamic addServlet(String servletName, @@ -549,6 +589,13 @@ public interface ServletContext { * @param c * @return TODO * @throws ServletException + * @throws UnsupportedOperationException If called from a + * {@link ServletContextListener#contextInitialized(ServletContextEvent)} + * method of a {@link ServletContextListener} that was not defined in a + * web.xml file, a web-fragment.xml file nor annotated with + * {@link javax.servlet.annotation.WebListener}. For example, a + * {@link ServletContextListener} defined in a TLD would not be able to + * use this method. * @since Servlet 3.0 TODO SERVLET3 - Add comments */ public <T extends Servlet> T createServlet(Class<T> c) @@ -563,7 +610,13 @@ public interface ServletContext { * <code>null</code> if no Servlet has been registered with the * given name * - * @throws UnsupportedOperationException TODO SERVLET3 - Add comments + * @throws UnsupportedOperationException If called from a + * {@link ServletContextListener#contextInitialized(ServletContextEvent)} + * method of a {@link ServletContextListener} that was not defined in a + * web.xml file, a web-fragment.xml file nor annotated with + * {@link javax.servlet.annotation.WebListener}. For example, a + * {@link ServletContextListener} defined in a TLD would not be able to + * use this method. * * @since Servlet 3.0 */ @@ -571,7 +624,13 @@ public interface ServletContext { /** * @return TODO - * @throws UnsupportedOperationException + * @throws UnsupportedOperationException If called from a + * {@link ServletContextListener#contextInitialized(ServletContextEvent)} + * method of a {@link ServletContextListener} that was not defined in a + * web.xml file, a web-fragment.xml file nor annotated with + * {@link javax.servlet.annotation.WebListener}. For example, a + * {@link ServletContextListener} defined in a TLD would not be able to + * use this method. * @since Servlet 3.0 TODO SERVLET3 - Add comments */ public Map<String, ? extends ServletRegistration> getServletRegistrations(); @@ -580,6 +639,13 @@ public interface ServletContext { * @param filterName * @param className * @return TODO + * @throws UnsupportedOperationException If called from a + * {@link ServletContextListener#contextInitialized(ServletContextEvent)} + * method of a {@link ServletContextListener} that was not defined in a + * web.xml file, a web-fragment.xml file nor annotated with + * {@link javax.servlet.annotation.WebListener}. For example, a + * {@link ServletContextListener} defined in a TLD would not be able to + * use this method. * @throws IllegalStateException * If the context has already been initialised * @since Servlet 3.0 TODO SERVLET3 - Add comments @@ -591,6 +657,13 @@ public interface ServletContext { * @param filterName * @param filter * @return TODO + * @throws UnsupportedOperationException If called from a + * {@link ServletContextListener#contextInitialized(ServletContextEvent)} + * method of a {@link ServletContextListener} that was not defined in a + * web.xml file, a web-fragment.xml file nor annotated with + * {@link javax.servlet.annotation.WebListener}. For example, a + * {@link ServletContextListener} defined in a TLD would not be able to + * use this method. * @throws IllegalStateException * If the context has already been initialised * @since Servlet 3.0 TODO SERVLET3 - Add comments @@ -601,6 +674,13 @@ public interface ServletContext { * @param filterName * @param filterClass * @return TODO + * @throws UnsupportedOperationException If called from a + * {@link ServletContextListener#contextInitialized(ServletContextEvent)} + * method of a {@link ServletContextListener} that was not defined in a + * web.xml file, a web-fragment.xml file nor annotated with + * {@link javax.servlet.annotation.WebListener}. For example, a + * {@link ServletContextListener} defined in a TLD would not be able to + * use this method. * @throws IllegalStateException * If the context has already been initialised * @since Servlet 3.0 TODO SERVLET3 - Add comments @@ -611,6 +691,13 @@ public interface ServletContext { /** * @param c * @return TODO + * @throws UnsupportedOperationException If called from a + * {@link ServletContextListener#contextInitialized(ServletContextEvent)} + * method of a {@link ServletContextListener} that was not defined in a + * web.xml file, a web-fragment.xml file nor annotated with + * {@link javax.servlet.annotation.WebListener}. For example, a + * {@link ServletContextListener} defined in a TLD would not be able to + * use this method. * @throws ServletException * @since Servlet 3.0 TODO SERVLET3 - Add comments */ @@ -620,21 +707,39 @@ public interface ServletContext { /** * @param filterName * @return TODO - * @throws UnsupportedOperationException + * @throws UnsupportedOperationException If called from a + * {@link ServletContextListener#contextInitialized(ServletContextEvent)} + * method of a {@link ServletContextListener} that was not defined in a + * web.xml file, a web-fragment.xml file nor annotated with + * {@link javax.servlet.annotation.WebListener}. For example, a + * {@link ServletContextListener} defined in a TLD would not be able to + * use this method. * @since Servlet 3.0 TODO SERVLET3 - Add comments */ public FilterRegistration getFilterRegistration(String filterName); /** * @return TODO - * @throws UnsupportedOperationException + * @throws UnsupportedOperationException If called from a + * {@link ServletContextListener#contextInitialized(ServletContextEvent)} + * method of a {@link ServletContextListener} that was not defined in a + * web.xml file, a web-fragment.xml file nor annotated with + * {@link javax.servlet.annotation.WebListener}. For example, a + * {@link ServletContextListener} defined in a TLD would not be able to + * use this method. * @since Servlet 3.0 TODO SERVLET3 - Add comments */ public Map<String, ? extends FilterRegistration> getFilterRegistrations(); /** * @return TODO - * @throws UnsupportedOperationException + * @throws UnsupportedOperationException If called from a + * {@link ServletContextListener#contextInitialized(ServletContextEvent)} + * method of a {@link ServletContextListener} that was not defined in a + * web.xml file, a web-fragment.xml file nor annotated with + * {@link javax.servlet.annotation.WebListener}. For example, a + * {@link ServletContextListener} defined in a TLD would not be able to + * use this method. * @since Servlet 3.0 TODO SERVLET3 - Add comments */ public SessionCookieConfig getSessionCookieConfig(); @@ -647,7 +752,13 @@ public interface ServletContext { * {@link SessionTrackingMode} * @throws IllegalStateException * If the context has already been initialised - * @throws UnsupportedOperationException + * @throws UnsupportedOperationException If called from a + * {@link ServletContextListener#contextInitialized(ServletContextEvent)} + * method of a {@link ServletContextListener} that was not defined in a + * web.xml file, a web-fragment.xml file nor annotated with + * {@link javax.servlet.annotation.WebListener}. For example, a + * {@link ServletContextListener} defined in a TLD would not be able to + * use this method. * @since Servlet 3.0 TODO SERVLET3 - Add comments */ public void setSessionTrackingModes( @@ -656,24 +767,39 @@ public interface ServletContext { /** * @return TODO + * @throws UnsupportedOperationException If called from a + * {@link ServletContextListener#contextInitialized(ServletContextEvent)} + * method of a {@link ServletContextListener} that was not defined in a + * web.xml file, a web-fragment.xml file nor annotated with + * {@link javax.servlet.annotation.WebListener}. For example, a + * {@link ServletContextListener} defined in a TLD would not be able to + * use this method. * @since Servlet 3.0 TODO SERVLET3 - Add comments */ public Set<SessionTrackingMode> getDefaultSessionTrackingModes(); /** * @return TODO + * @throws UnsupportedOperationException If called from a + * {@link ServletContextListener#contextInitialized(ServletContextEvent)} + * method of a {@link ServletContextListener} that was not defined in a + * web.xml file, a web-fragment.xml file nor annotated with + * {@link javax.servlet.annotation.WebListener}. For example, a + * {@link ServletContextListener} defined in a TLD would not be able to + * use this method. * @since Servlet 3.0 TODO SERVLET3 - Add comments */ public Set<SessionTrackingMode> getEffectiveSessionTrackingModes(); /** - * @param listenerClass - * @since Servlet 3.0 TODO SERVLET3 - Add comments - */ - public void addListener(Class<? extends EventListener> listenerClass); - - /** * @param className + * @throws UnsupportedOperationException If called from a + * {@link ServletContextListener#contextInitialized(ServletContextEvent)} + * method of a {@link ServletContextListener} that was not defined in a + * web.xml file, a web-fragment.xml file nor annotated with + * {@link javax.servlet.annotation.WebListener}. For example, a + * {@link ServletContextListener} defined in a TLD would not be able to + * use this method. * @since Servlet 3.0 TODO SERVLET3 - Add comments */ public void addListener(String className); @@ -681,15 +807,42 @@ public interface ServletContext { /** * @param <T> * @param t + * @throws UnsupportedOperationException If called from a + * {@link ServletContextListener#contextInitialized(ServletContextEvent)} + * method of a {@link ServletContextListener} that was not defined in a + * web.xml file, a web-fragment.xml file nor annotated with + * {@link javax.servlet.annotation.WebListener}. For example, a + * {@link ServletContextListener} defined in a TLD would not be able to + * use this method. * @since Servlet 3.0 TODO SERVLET3 - Add comments */ public <T extends EventListener> void addListener(T t); /** + * @param listenerClass + * @throws UnsupportedOperationException If called from a + * {@link ServletContextListener#contextInitialized(ServletContextEvent)} + * method of a {@link ServletContextListener} that was not defined in a + * web.xml file, a web-fragment.xml file nor annotated with + * {@link javax.servlet.annotation.WebListener}. For example, a + * {@link ServletContextListener} defined in a TLD would not be able to + * use this method. + * @since Servlet 3.0 TODO SERVLET3 - Add comments + */ + public void addListener(Class<? extends EventListener> listenerClass); + + /** * @param <T> * @param c * @return TODO * @throws ServletException + * @throws UnsupportedOperationException If called from a + * {@link ServletContextListener#contextInitialized(ServletContextEvent)} + * method of a {@link ServletContextListener} that was not defined in a + * web.xml file, a web-fragment.xml file nor annotated with + * {@link javax.servlet.annotation.WebListener}. For example, a + * {@link ServletContextListener} defined in a TLD would not be able to + * use this method. * @since Servlet 3.0 TODO SERVLET3 - Add comments */ public <T extends EventListener> T createListener(Class<T> c) @@ -697,7 +850,13 @@ public interface ServletContext { /** * @param roleNames - * @throws UnsupportedOperationException + * @throws UnsupportedOperationException If called from a + * {@link ServletContextListener#contextInitialized(ServletContextEvent)} + * method of a {@link ServletContextListener} that was not defined in a + * web.xml file, a web-fragment.xml file nor annotated with + * {@link javax.servlet.annotation.WebListener}. For example, a + * {@link ServletContextListener} defined in a TLD would not be able to + * use this method. * @throws IllegalArgumentException * @throws IllegalStateException * @since Servlet 3.0 TODO SERVLET3 - Add comments @@ -706,7 +865,13 @@ public interface ServletContext { /** * @return TODO - * @throws UnsupportedOperationException + * @throws UnsupportedOperationException If called from a + * {@link ServletContextListener#contextInitialized(ServletContextEvent)} + * method of a {@link ServletContextListener} that was not defined in a + * web.xml file, a web-fragment.xml file nor annotated with + * {@link javax.servlet.annotation.WebListener}. For example, a + * {@link ServletContextListener} defined in a TLD would not be able to + * use this method. * @throws SecurityException * @since Servlet 3.0 TODO SERVLET3 - Add comments */ @@ -714,7 +879,13 @@ public interface ServletContext { /** * @return TODO - * @throws UnsupportedOperationException + * @throws UnsupportedOperationException If called from a + * {@link ServletContextListener#contextInitialized(ServletContextEvent)} + * method of a {@link ServletContextListener} that was not defined in a + * web.xml file, a web-fragment.xml file nor annotated with + * {@link javax.servlet.annotation.WebListener}. For example, a + * {@link ServletContextListener} defined in a TLD would not be able to + * use this method. * @since Servlet 3.0 TODO SERVLET3 - Add comments */ public JspConfigDescriptor getJspConfigDescriptor(); Modified: tomcat/tc7.0.x/trunk/java/org/apache/catalina/Context.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/Context.java?rev=1492331&r1=1492330&r2=1492331&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/java/org/apache/catalina/Context.java (original) +++ tomcat/tc7.0.x/trunk/java/org/apache/catalina/Context.java Wed Jun 12 18:31:30 2013 @@ -31,6 +31,7 @@ import javax.servlet.ServletSecurityElem import javax.servlet.descriptor.JspConfigDescriptor; import org.apache.catalina.core.ApplicationServletRegistration; +import org.apache.catalina.deploy.ApplicationListener; import org.apache.catalina.deploy.ApplicationParameter; import org.apache.catalina.deploy.ErrorPage; import org.apache.catalina.deploy.FilterDef; @@ -720,7 +721,7 @@ public interface Context extends Contain * * @param listener Java class name of a listener class */ - public void addApplicationListener(String listener); + public void addApplicationListener(ApplicationListener listener); /** @@ -898,7 +899,7 @@ public interface Context extends Contain * Return the set of application listener class names configured * for this application. */ - public String[] findApplicationListeners(); + public ApplicationListener[] findApplicationListeners(); /** Modified: tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/LocalStrings.properties URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/LocalStrings.properties?rev=1492331&r1=1492330&r2=1492331&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/LocalStrings.properties (original) +++ tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/LocalStrings.properties Wed Jun 12 18:31:30 2013 @@ -267,6 +267,8 @@ standardWrapper.waiting=Waiting for {0} threadLocalLeakPreventionListener.lifecycleEvent.error=Exception processing lifecycle event {0} threadLocalLeakPreventionListener.containerEvent.error=Exception processing container event {0} +tldListenerServletContext.notAllowed=Section 4.4 of the Servlet 3.0 specification does not permit this method to be called from a ServletContextListener that is defined in a TLD + defaultInstanceManager.restrictedServletsResource=Restricted servlets property file not found defaultInstanceManager.privilegedServlet=Servlet of class {0} is privileged and cannot be loaded by this web application defaultInstanceManager.restrictedFiltersResource=Restricted filters property file not found 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=1492331&r1=1492330&r2=1492331&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 Jun 12 18:31:30 2013 @@ -23,10 +23,13 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Enumeration; +import java.util.EventListener; import java.util.HashMap; import java.util.HashSet; import java.util.Hashtable; @@ -50,7 +53,9 @@ import javax.management.NotificationList import javax.management.ObjectName; import javax.naming.NamingException; import javax.naming.directory.DirContext; +import javax.servlet.Filter; import javax.servlet.FilterConfig; +import javax.servlet.FilterRegistration; import javax.servlet.RequestDispatcher; import javax.servlet.Servlet; import javax.servlet.ServletContainerInitializer; @@ -60,11 +65,14 @@ import javax.servlet.ServletContextEvent import javax.servlet.ServletContextListener; import javax.servlet.ServletException; import javax.servlet.ServletRegistration; +import javax.servlet.ServletRegistration.Dynamic; import javax.servlet.ServletRequest; import javax.servlet.ServletRequestAttributeListener; import javax.servlet.ServletRequestEvent; import javax.servlet.ServletRequestListener; import javax.servlet.ServletSecurityElement; +import javax.servlet.SessionCookieConfig; +import javax.servlet.SessionTrackingMode; import javax.servlet.descriptor.JspConfigDescriptor; import javax.servlet.http.HttpSessionAttributeListener; import javax.servlet.http.HttpSessionListener; @@ -86,6 +94,7 @@ import org.apache.catalina.Pipeline; import org.apache.catalina.Realm; import org.apache.catalina.Valve; import org.apache.catalina.Wrapper; +import org.apache.catalina.deploy.ApplicationListener; import org.apache.catalina.deploy.ApplicationParameter; import org.apache.catalina.deploy.ErrorPage; import org.apache.catalina.deploy.FilterDef; @@ -233,10 +242,11 @@ public class StandardContext extends Con /** - * The set of application listener class names configured for this - * application, in the order they were encountered in the web.xml file. + * The set of application listeners configured for this application, in the + * order they were encountered in the web.xml file. */ - private String applicationListeners[] = new String[0]; + private ApplicationListener applicationListeners[] = + new ApplicationListener[0]; private final Object applicationListenersLock = new Object(); @@ -2777,10 +2787,11 @@ public class StandardContext extends Con * @param listener Java class name of a listener class */ @Override - public void addApplicationListener(String listener) { + public void addApplicationListener(ApplicationListener listener) { synchronized (applicationListenersLock) { - String results[] =new String[applicationListeners.length + 1]; + ApplicationListener results[] = + new ApplicationListener[applicationListeners.length + 1]; for (int i = 0; i < applicationListeners.length; i++) { if (listener.equals(applicationListeners[i])) { log.info(sm.getString( @@ -3412,7 +3423,7 @@ public class StandardContext extends Con * for this application. */ @Override - public String[] findApplicationListeners() { + public ApplicationListener[] findApplicationListeners() { return (applicationListeners); @@ -3952,7 +3963,7 @@ public class StandardContext extends Con // Make sure this welcome file is currently present int n = -1; for (int i = 0; i < applicationListeners.length; i++) { - if (applicationListeners[i].equals(listener)) { + if (applicationListeners[i].getClassName().equals(listener)) { n = i; break; } @@ -3962,7 +3973,8 @@ public class StandardContext extends Con // Remove the specified constraint int j = 0; - String results[] = new String[applicationListeners.length - 1]; + ApplicationListener results[] = + new ApplicationListener[applicationListeners.length - 1]; for (int i = 0; i < applicationListeners.length; i++) { if (i != n) results[j++] = applicationListeners[i]; @@ -4812,15 +4824,21 @@ public class StandardContext extends Con log.debug("Configuring application event listeners"); // Instantiate the required listeners - String listeners[] = findApplicationListeners(); + ApplicationListener listeners[] = findApplicationListeners(); Object results[] = new Object[listeners.length]; boolean ok = true; + Set<Object> tldListeners = new HashSet<Object>(); for (int i = 0; i < results.length; i++) { if (getLogger().isDebugEnabled()) getLogger().debug(" Configuring event listener class '" + listeners[i] + "'"); try { - results[i] = instanceManager.newInstance(listeners[i]); + ApplicationListener listener = listeners[i]; + results[i] = instanceManager.newInstance( + listener.getClassName()); + if (listener.isFromTLD()) { + tldListeners.add(results[i]); + } } catch (Throwable t) { t = ExceptionUtils.unwrapInvocationTargetException(t); ExceptionUtils.handleThrowable(t); @@ -4871,10 +4889,17 @@ public class StandardContext extends Con context.setNewServletContextListenerAllowed(false); Object instances[] = getApplicationLifecycleListeners(); - if (instances == null) - return (ok); + if (instances == null || instances.length == 0) { + return ok; + } + ServletContextEvent event = - new ServletContextEvent(getServletContext()); + new ServletContextEvent(getServletContext()); + ServletContextEvent tldEvent = null; + if (tldListeners.size() > 0) { + tldEvent = new ServletContextEvent(new TldListenerServletContext( + getServletContext())); + } for (int i = 0; i < instances.length; i++) { if (instances[i] == null) continue; @@ -4884,7 +4909,11 @@ public class StandardContext extends Con (ServletContextListener) instances[i]; try { fireContainerEvent("beforeContextInitialized", listener); - listener.contextInitialized(event); + if (tldListeners.contains(listener)) { + listener.contextInitialized(tldEvent); + } else { + listener.contextInitialized(event); + } fireContainerEvent("afterContextInitialized", listener); } catch (Throwable t) { ExceptionUtils.handleThrowable(t); @@ -5702,7 +5731,7 @@ public class StandardContext extends Con // Bugzilla 32867 distributable = false; - applicationListeners = new String[0]; + applicationListeners = new ApplicationListener[0]; applicationEventListenersObjects = new Object[0]; applicationLifecycleListenersObjects = new Object[0]; jspConfigDescriptor = new ApplicationJspConfigDescriptor(); @@ -6688,4 +6717,307 @@ public class StandardContext extends Con public boolean isStatisticsProvider() { return false; } + + + private static class TldListenerServletContext implements ServletContext { + + private final ServletContext sc; + + public TldListenerServletContext(ServletContext sc) { + this.sc = sc; + } + + @Override + public String getContextPath() { + return sc.getContextPath(); + } + + @Override + public ServletContext getContext(String uripath) { + return sc.getContext(uripath); + } + + @Override + public int getMajorVersion() { + return sc.getMajorVersion(); + } + + @Override + public int getMinorVersion() { + return sc.getMinorVersion(); + } + + @Override + public int getEffectiveMajorVersion() { + throw new UnsupportedOperationException( + sm.getString("tldListenerServletContext.notAllowed")); + } + + @Override + public int getEffectiveMinorVersion() { + throw new UnsupportedOperationException( + sm.getString("tldListenerServletContext.notAllowed")); + } + + @Override + public String getMimeType(String file) { + return sc.getMimeType(file); + } + + @Override + public Set<String> getResourcePaths(String path) { + return sc.getResourcePaths(path); + } + + @Override + public URL getResource(String path) throws MalformedURLException { + return sc.getResource(path); + } + + @Override + public InputStream getResourceAsStream(String path) { + return sc.getResourceAsStream(path); + } + + @Override + public RequestDispatcher getRequestDispatcher(String path) { + return sc.getRequestDispatcher(path); + } + + @Override + public RequestDispatcher getNamedDispatcher(String name) { + return sc.getNamedDispatcher(name); + } + + @Override + @Deprecated + public Servlet getServlet(String name) throws ServletException { + return sc.getServlet(name); + } + + @Override + @Deprecated + public Enumeration<Servlet> getServlets() { + return sc.getServlets(); + } + + @Override + @Deprecated + public Enumeration<String> getServletNames() { + return sc.getServletNames(); + } + + @Override + public void log(String msg) { + sc.log(msg); + } + + @Override + @Deprecated + public void log(Exception exception, String msg) { + sc.log(exception, msg); + } + + @Override + public void log(String message, Throwable throwable) { + sc.log(message, throwable); + } + + @Override + public String getRealPath(String path) { + return sc.getRealPath(path); + } + + @Override + public String getServerInfo() { + return sc.getServerInfo(); + } + + @Override + public String getInitParameter(String name) { + return sc.getInitParameter(name); + } + + @Override + public Enumeration<String> getInitParameterNames() { + return sc.getInitParameterNames(); + } + + @Override + public boolean setInitParameter(String name, String value) { + throw new UnsupportedOperationException( + sm.getString("tldListenerServletContext.notAllowed")); + } + + @Override + public Object getAttribute(String name) { + return sc.getAttribute(name); + } + + @Override + public Enumeration<String> getAttributeNames() { + return sc.getAttributeNames(); + } + + @Override + public void setAttribute(String name, Object object) { + sc.setAttribute(name, object); + } + + @Override + public void removeAttribute(String name) { + sc.removeAttribute(name); + } + + @Override + public String getServletContextName() { + return sc.getServletContextName(); + } + + @Override + public Dynamic addServlet(String servletName, String className) { + throw new UnsupportedOperationException( + sm.getString("tldListenerServletContext.notAllowed")); + } + + @Override + public Dynamic addServlet(String servletName, Servlet servlet) { + throw new UnsupportedOperationException( + sm.getString("tldListenerServletContext.notAllowed")); + } + + @Override + public Dynamic addServlet(String servletName, + Class<? extends Servlet> servletClass) { + throw new UnsupportedOperationException( + sm.getString("tldListenerServletContext.notAllowed")); + } + + @Override + public <T extends Servlet> T createServlet(Class<T> c) + throws ServletException { + throw new UnsupportedOperationException( + sm.getString("tldListenerServletContext.notAllowed")); + } + + @Override + public ServletRegistration getServletRegistration(String servletName) { + throw new UnsupportedOperationException( + sm.getString("tldListenerServletContext.notAllowed")); + } + + @Override + public Map<String,? extends ServletRegistration> getServletRegistrations() { + throw new UnsupportedOperationException( + sm.getString("tldListenerServletContext.notAllowed")); + } + + @Override + public javax.servlet.FilterRegistration.Dynamic addFilter( + String filterName, String className) { + throw new UnsupportedOperationException( + sm.getString("tldListenerServletContext.notAllowed")); + } + + @Override + public javax.servlet.FilterRegistration.Dynamic addFilter( + String filterName, Filter filter) { + throw new UnsupportedOperationException( + sm.getString("tldListenerServletContext.notAllowed")); + } + + @Override + public javax.servlet.FilterRegistration.Dynamic addFilter( + String filterName, Class<? extends Filter> filterClass) { + throw new UnsupportedOperationException( + sm.getString("tldListenerServletContext.notAllowed")); + } + + @Override + public <T extends Filter> T createFilter(Class<T> c) + throws ServletException { + throw new UnsupportedOperationException( + sm.getString("tldListenerServletContext.notAllowed")); + } + + @Override + public FilterRegistration getFilterRegistration(String filterName) { + throw new UnsupportedOperationException( + sm.getString("tldListenerServletContext.notAllowed")); + } + + @Override + public Map<String,? extends FilterRegistration> getFilterRegistrations() { + throw new UnsupportedOperationException( + sm.getString("tldListenerServletContext.notAllowed")); + } + + @Override + public SessionCookieConfig getSessionCookieConfig() { + throw new UnsupportedOperationException( + sm.getString("tldListenerServletContext.notAllowed")); + } + + @Override + public void setSessionTrackingModes( + Set<SessionTrackingMode> sessionTrackingModes) { + throw new UnsupportedOperationException( + sm.getString("tldListenerServletContext.notAllowed")); + } + + @Override + public Set<SessionTrackingMode> getDefaultSessionTrackingModes() { + throw new UnsupportedOperationException( + sm.getString("tldListenerServletContext.notAllowed")); + } + + @Override + public Set<SessionTrackingMode> getEffectiveSessionTrackingModes() { + throw new UnsupportedOperationException( + sm.getString("tldListenerServletContext.notAllowed")); + } + + @Override + public void addListener(String className) { + throw new UnsupportedOperationException( + sm.getString("tldListenerServletContext.notAllowed")); + } + + @Override + public <T extends EventListener> void addListener(T t) { + throw new UnsupportedOperationException( + sm.getString("tldListenerServletContext.notAllowed")); + } + + @Override + public void addListener(Class<? extends EventListener> listenerClass) { + throw new UnsupportedOperationException( + sm.getString("tldListenerServletContext.notAllowed")); + } + + @Override + public <T extends EventListener> T createListener(Class<T> c) + throws ServletException { + throw new UnsupportedOperationException( + sm.getString("tldListenerServletContext.notAllowed")); + } + + @Override + public JspConfigDescriptor getJspConfigDescriptor() { + throw new UnsupportedOperationException( + sm.getString("tldListenerServletContext.notAllowed")); + } + + @Override + public ClassLoader getClassLoader() { + throw new UnsupportedOperationException( + sm.getString("tldListenerServletContext.notAllowed")); + } + + @Override + public void declareRoles(String... roleNames) { + throw new UnsupportedOperationException( + sm.getString("tldListenerServletContext.notAllowed")); + } + } } Modified: tomcat/tc7.0.x/trunk/java/org/apache/catalina/deploy/WebXml.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/deploy/WebXml.java?rev=1492331&r1=1492330&r2=1492331&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/java/org/apache/catalina/deploy/WebXml.java (original) +++ tomcat/tc7.0.x/trunk/java/org/apache/catalina/deploy/WebXml.java Wed Jun 12 18:31:30 2013 @@ -1277,7 +1277,8 @@ public class WebXml { descriptor); } for (String listener : listeners) { - context.addApplicationListener(listener); + context.addApplicationListener( + new ApplicationListener(listener, false)); } for (Entry<String, String> entry : localeEncodingMappings.entrySet()) { context.addLocaleEncodingMappingParameter(entry.getKey(), Modified: tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/FailedContext.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/FailedContext.java?rev=1492331&r1=1492330&r2=1492331&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/FailedContext.java (original) +++ tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/FailedContext.java Wed Jun 12 18:31:30 2013 @@ -47,6 +47,7 @@ import org.apache.catalina.Wrapper; import org.apache.catalina.connector.Request; import org.apache.catalina.connector.Response; import org.apache.catalina.core.ApplicationServletRegistration; +import org.apache.catalina.deploy.ApplicationListener; import org.apache.catalina.deploy.ApplicationParameter; import org.apache.catalina.deploy.ErrorPage; import org.apache.catalina.deploy.FilterDef; @@ -122,6 +123,7 @@ public class FailedContext extends Lifec @Override + @Deprecated protected String getDomainInternal() { return MBeanUtils.getDomain(this); } @@ -446,9 +448,9 @@ public class FailedContext extends Lifec public boolean getLogEffectiveWebXml() { return false; } @Override - public void addApplicationListener(String listener) { /* NO-OP */ } + public void addApplicationListener(ApplicationListener listener) { /* NO-OP */ } @Override - public String[] findApplicationListeners() { return null; } + public ApplicationListener[] findApplicationListeners() { return null; } @Override public void removeApplicationListener(String listener) { /* NO-OP */ } Modified: tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/TldConfig.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/TldConfig.java?rev=1492331&r1=1492330&r2=1492331&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/TldConfig.java (original) +++ tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/TldConfig.java Wed Jun 12 18:31:30 2013 @@ -36,6 +36,7 @@ import org.apache.catalina.Lifecycle; import org.apache.catalina.LifecycleEvent; import org.apache.catalina.LifecycleListener; import org.apache.catalina.core.StandardContext; +import org.apache.catalina.deploy.ApplicationListener; import org.apache.tomcat.JarScanner; import org.apache.tomcat.JarScannerCallback; import org.apache.tomcat.util.ExceptionUtils; @@ -286,7 +287,8 @@ public final class TldConfig implements Integer.valueOf(list.length))); for( int i=0; list!=null && i<list.length; i++ ) { - context.addApplicationListener(list[i]); + context.addApplicationListener( + new ApplicationListener(list[i], true)); } long t2=System.currentTimeMillis(); Modified: tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/WebAnnotationSet.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/WebAnnotationSet.java?rev=1492331&r1=1492330&r2=1492331&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/WebAnnotationSet.java (original) +++ tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/WebAnnotationSet.java Wed Jun 12 18:31:30 2013 @@ -27,6 +27,7 @@ import javax.annotation.security.RunAs; import org.apache.catalina.Container; import org.apache.catalina.Context; import org.apache.catalina.Wrapper; +import org.apache.catalina.deploy.ApplicationListener; import org.apache.catalina.deploy.ContextEnvironment; import org.apache.catalina.deploy.ContextResource; import org.apache.catalina.deploy.ContextResourceEnvRef; @@ -78,10 +79,11 @@ public class WebAnnotationSet { */ protected static void loadApplicationListenerAnnotations(Context context) { Class<?> classClass = null; - String[] applicationListeners = context.findApplicationListeners(); + ApplicationListener[] applicationListeners = + context.findApplicationListeners(); for (int i = 0; i < applicationListeners.length; i++) { classClass = Introspection.loadClass(context, - applicationListeners[i]); + applicationListeners[i].getClassName()); if (classClass == null) { continue; } Modified: tomcat/tc7.0.x/trunk/test/org/apache/catalina/core/TestAsyncContextImpl.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/test/org/apache/catalina/core/TestAsyncContextImpl.java?rev=1492331&r1=1492330&r2=1492331&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/test/org/apache/catalina/core/TestAsyncContextImpl.java (original) +++ tomcat/tc7.0.x/trunk/test/org/apache/catalina/core/TestAsyncContextImpl.java Wed Jun 12 18:31:30 2013 @@ -50,6 +50,7 @@ import org.junit.Test; import org.apache.catalina.Context; import org.apache.catalina.Wrapper; import org.apache.catalina.connector.Request; +import org.apache.catalina.deploy.ApplicationListener; import org.apache.catalina.deploy.ErrorPage; import org.apache.catalina.startup.Tomcat; import org.apache.catalina.startup.TomcatBaseTest; @@ -440,7 +441,8 @@ public class TestAsyncContextImpl extend ctx.addServletMapping(dispatchUrl, "nonasync"); } - ctx.addApplicationListener(TrackingRequestListener.class.getName()); + ctx.addApplicationListener(new ApplicationListener( + TrackingRequestListener.class.getName(), false)); TesterAccessLogValve alv = new TesterAccessLogValve(); ctx.getPipeline().addValve(alv); @@ -570,7 +572,8 @@ public class TestAsyncContextImpl extend wrapper2.setAsyncSupported(true); ctx.addServletMapping("/stage2", "nonasync"); - ctx.addApplicationListener(TrackingRequestListener.class.getName()); + ctx.addApplicationListener(new ApplicationListener( + TrackingRequestListener.class.getName(), false)); TesterAccessLogValve alv = new TesterAccessLogValve(); ctx.getPipeline().addValve(alv); @@ -907,7 +910,8 @@ public class TestAsyncContextImpl extend Tomcat.addServlet(ctx, "error", error); ctx.addServletMapping("/stage2", "error"); - ctx.addApplicationListener(TrackingRequestListener.class.getName()); + ctx.addApplicationListener(new ApplicationListener( + TrackingRequestListener.class.getName(), false)); TesterAccessLogValve alv = new TesterAccessLogValve(); ctx.getPipeline().addValve(alv); @@ -1525,7 +1529,8 @@ public class TestAsyncContextImpl extend ctx.addErrorPage(ep); } - ctx.addApplicationListener(TrackingRequestListener.class.getName()); + ctx.addApplicationListener(new ApplicationListener( + TrackingRequestListener.class.getName(), false)); TesterAccessLogValve alv = new TesterAccessLogValve(); ctx.getPipeline().addValve(alv); Modified: tomcat/tc7.0.x/trunk/test/org/apache/catalina/core/TestNamingContextListener.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/test/org/apache/catalina/core/TestNamingContextListener.java?rev=1492331&r1=1492330&r2=1492331&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/test/org/apache/catalina/core/TestNamingContextListener.java (original) +++ tomcat/tc7.0.x/trunk/test/org/apache/catalina/core/TestNamingContextListener.java Wed Jun 12 18:31:30 2013 @@ -27,6 +27,7 @@ import static org.junit.Assert.assertEqu import org.junit.Test; import org.apache.catalina.LifecycleState; +import org.apache.catalina.deploy.ApplicationListener; import org.apache.catalina.deploy.ContextEnvironment; import org.apache.catalina.startup.Tomcat; import org.apache.catalina.startup.TomcatBaseTest; @@ -61,7 +62,8 @@ public class TestNamingContextListener e environment.setValue(BUG49132_VALUE); ctx.getNamingResources().addEnvironment(environment); - ctx.addApplicationListener(Bug49132Listener.class.getName()); + ctx.addApplicationListener(new ApplicationListener( + Bug49132Listener.class.getName(), false)); tomcat.start(); @@ -115,7 +117,8 @@ public class TestNamingContextListener e environmentB.setValue(BUG54096_ValueB); ctx.getNamingResources().addEnvironment(environmentB); - ctx.addApplicationListener(Bug54096Listener.class.getName()); + ctx.addApplicationListener(new ApplicationListener( + Bug54096Listener.class.getName(), false)); tomcat.start(); Modified: tomcat/tc7.0.x/trunk/test/org/apache/catalina/core/TestStandardContext.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/test/org/apache/catalina/core/TestStandardContext.java?rev=1492331&r1=1492330&r2=1492331&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/test/org/apache/catalina/core/TestStandardContext.java (original) +++ tomcat/tc7.0.x/trunk/test/org/apache/catalina/core/TestStandardContext.java Wed Jun 12 18:31:30 2013 @@ -46,6 +46,7 @@ import static org.junit.Assert.assertNot import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import org.junit.Assert; import org.junit.Test; import org.apache.catalina.Context; @@ -786,4 +787,23 @@ public class TestStandardContext extends standardContext.addPreDestroyMethod("a", "a"); standardContext.addPreDestroyMethod("a", "b"); } + + @Test + public void testTldListener() throws Exception { + // Set up a container + Tomcat tomcat = getTomcatInstance(); + + File docBase = new File("test/webapp-3.0"); + Context ctx = tomcat.addContext("", docBase.getAbsolutePath()); + + // Start the context + tomcat.start(); + + // Stop the context + ctx.stop(); + + String log = TesterTldListener.getLog(); + Assert.assertTrue(log, log.contains("PASS")); + Assert.assertFalse(log, log.contains("FAIL")); + } } Modified: tomcat/tc7.0.x/trunk/test/org/apache/catalina/core/TesterContext.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/test/org/apache/catalina/core/TesterContext.java?rev=1492331&r1=1492330&r2=1492331&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/test/org/apache/catalina/core/TesterContext.java (original) +++ tomcat/tc7.0.x/trunk/test/org/apache/catalina/core/TesterContext.java Wed Jun 12 18:31:30 2013 @@ -48,6 +48,7 @@ import org.apache.catalina.Realm; import org.apache.catalina.Wrapper; import org.apache.catalina.connector.Request; import org.apache.catalina.connector.Response; +import org.apache.catalina.deploy.ApplicationListener; import org.apache.catalina.deploy.ApplicationParameter; import org.apache.catalina.deploy.ErrorPage; import org.apache.catalina.deploy.FilterDef; @@ -624,7 +625,7 @@ public class TesterContext implements Co } @Override - public void addApplicationListener(String listener) { + public void addApplicationListener(ApplicationListener listener) { // NO-OP } @@ -725,7 +726,7 @@ public class TesterContext implements Co } @Override - public String[] findApplicationListeners() { + public ApplicationListener[] findApplicationListeners() { return null; } Modified: tomcat/tc7.0.x/trunk/test/org/apache/catalina/startup/TestListener.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/test/org/apache/catalina/startup/TestListener.java?rev=1492331&r1=1492330&r2=1492331&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/test/org/apache/catalina/startup/TestListener.java (original) +++ tomcat/tc7.0.x/trunk/test/org/apache/catalina/startup/TestListener.java Wed Jun 12 18:31:30 2013 @@ -30,6 +30,7 @@ import static org.junit.Assert.assertTru import org.junit.Test; import org.apache.catalina.Context; +import org.apache.catalina.deploy.ApplicationListener; public class TestListener extends TomcatBaseTest { @@ -52,7 +53,7 @@ public class TestListener extends Tomcat /** * Check that a {@link ServletContextListener} cannot install a - * {@link ServletContextInitializer}. + * {@link javax.servlet.ServletContainerInitializer}. * @throws Exception */ @Test @@ -63,11 +64,12 @@ public class TestListener extends Tomcat System.getProperty("java.io.tmpdir")); // SCL2 pretends to be in web.xml, and tries to install a - // ServletContextInitializer. - context.addApplicationListener(SCL2.class.getName()); + // ServletContainerInitializer. + context.addApplicationListener(new ApplicationListener( + SCL2.class.getName(), false)); tomcat.start(); - //check that the ServletContextInitializer wasn't initialized. + //check that the ServletContainerInitializer wasn't initialized. assertFalse(SCL3.initialized); } --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org