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 2011/06/02 17:54:27 UTC
svn commit: r1130618 - in /tomcat/trunk: java/org/apache/catalina/
java/org/apache/catalina/core/ java/org/apache/catalina/deploy/
java/org/apache/catalina/startup/ test/org/apache/catalina/startup/
test/webapp-3.0/ webapps/docs/
Author: markt
Date: Thu Jun 2 15:54:26 2011
New Revision: 1130618
URL: http://svn.apache.org/viewvc?rev=1130618&view=rev
Log:
Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=51278
Allow ServletContainerInitializers to override settings in the global default web.xml and the host web.xml.
Added:
tomcat/trunk/test/org/apache/catalina/startup/TestContextConfig.java (with props)
tomcat/trunk/test/webapp-3.0/index.html (with props)
Modified:
tomcat/trunk/java/org/apache/catalina/Wrapper.java
tomcat/trunk/java/org/apache/catalina/core/ApplicationContext.java
tomcat/trunk/java/org/apache/catalina/core/ApplicationServletRegistration.java
tomcat/trunk/java/org/apache/catalina/core/StandardWrapper.java
tomcat/trunk/java/org/apache/catalina/deploy/ServletDef.java
tomcat/trunk/java/org/apache/catalina/deploy/WebXml.java
tomcat/trunk/java/org/apache/catalina/startup/ContextConfig.java
tomcat/trunk/webapps/docs/changelog.xml
Modified: tomcat/trunk/java/org/apache/catalina/Wrapper.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/Wrapper.java?rev=1130618&r1=1130617&r2=1130618&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/Wrapper.java (original)
+++ tomcat/trunk/java/org/apache/catalina/Wrapper.java Thu Jun 2 15:54:26 2011
@@ -386,4 +386,14 @@ public interface Wrapper extends Contain
* Servlet associated with this wrapper.
*/
public void servletSecurityAnnotationScan() throws ServletException;
+
+ /**
+ * Is the Servlet overridable by a ServletContainerInitializer?
+ */
+ public boolean isOverridable();
+
+ /**
+ * Sets the overridable attribute for this Servlet.
+ */
+ public void setOverridable(boolean overridable);
}
Modified: tomcat/trunk/java/org/apache/catalina/core/ApplicationContext.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/ApplicationContext.java?rev=1130618&r1=1130617&r2=1130618&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/core/ApplicationContext.java (original)
+++ tomcat/trunk/java/org/apache/catalina/core/ApplicationContext.java Thu Jun 2 15:54:26 2011
@@ -1102,7 +1102,7 @@ public class ApplicationContext
Wrapper wrapper = (Wrapper) context.findChild(servletName);
- // Assume a 'complete' FilterRegistration is one that has a class and
+ // Assume a 'complete' ServletRegistration is one that has a class and
// a name
if (wrapper == null) {
wrapper = context.createWrapper();
@@ -1111,7 +1111,11 @@ public class ApplicationContext
} else {
if (wrapper.getName() != null &&
wrapper.getServletClass() != null) {
- return null;
+ if (wrapper.isOverridable()) {
+ wrapper.setOverridable(false);
+ } else {
+ return null;
+ }
}
}
Modified: tomcat/trunk/java/org/apache/catalina/core/ApplicationServletRegistration.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/ApplicationServletRegistration.java?rev=1130618&r1=1130617&r2=1130618&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/core/ApplicationServletRegistration.java (original)
+++ tomcat/trunk/java/org/apache/catalina/core/ApplicationServletRegistration.java Thu Jun 2 15:54:26 2011
@@ -171,8 +171,16 @@ public class ApplicationServletRegistrat
Set<String> conflicts = new HashSet<String>();
for (String urlPattern : urlPatterns) {
- if (context.findServletMapping(urlPattern) != null) {
- conflicts.add(urlPattern);
+ String wrapperName = context.findServletMapping(urlPattern);
+ if (wrapperName != null) {
+ Wrapper wrapper = (Wrapper) context.findChild(wrapperName);
+ if (wrapper.isOverridable()) {
+ // Some Wrappers (from global and host web.xml) may be
+ // overridden rather than generating a conflict
+ context.removeServletMapping(urlPattern);
+ } else {
+ conflicts.add(urlPattern);
+ }
}
}
Modified: tomcat/trunk/java/org/apache/catalina/core/StandardWrapper.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/StandardWrapper.java?rev=1130618&r1=1130617&r2=1130618&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/core/StandardWrapper.java (original)
+++ tomcat/trunk/java/org/apache/catalina/core/StandardWrapper.java Thu Jun 2 15:54:26 2011
@@ -276,6 +276,8 @@ public class StandardWrapper extends Con
protected volatile boolean servletSecurityAnnotationScanRequired = false;
+ private boolean overridable = false;
+
/**
* Static class array used when the SecurityManager is turned on and
* <code>Servlet.init</code> is invoked.
@@ -294,6 +296,15 @@ public class StandardWrapper extends Con
// ------------------------------------------------------------- Properties
+ @Override
+ public boolean isOverridable() {
+ return overridable;
+ }
+
+ @Override
+ public void setOverridable(boolean overridable) {
+ this.overridable = overridable;
+ }
/**
* Return the available date/time for this servlet, in milliseconds since
Modified: tomcat/trunk/java/org/apache/catalina/deploy/ServletDef.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/deploy/ServletDef.java?rev=1130618&r1=1130617&r2=1130618&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/deploy/ServletDef.java (original)
+++ tomcat/trunk/java/org/apache/catalina/deploy/ServletDef.java Thu Jun 2 15:54:26 2011
@@ -264,4 +264,19 @@ public class ServletDef implements Seria
public void setEnabled(String enabled) {
this.enabled = Boolean.valueOf(enabled);
}
+
+
+ /**
+ * Can this ServletDef be overridden by an SCI?
+ */
+ private boolean overridable = false;
+
+ public boolean isOverridable() {
+ return overridable;
+ }
+
+ public void setOverridable(boolean overridable) {
+ this.overridable = overridable;
+ }
+
}
Modified: tomcat/trunk/java/org/apache/catalina/deploy/WebXml.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/deploy/WebXml.java?rev=1130618&r1=1130617&r2=1130618&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/deploy/WebXml.java (original)
+++ tomcat/trunk/java/org/apache/catalina/deploy/WebXml.java Thu Jun 2 15:54:26 2011
@@ -61,7 +61,18 @@ public class WebXml {
private static final org.apache.juli.logging.Log log=
org.apache.juli.logging.LogFactory.getLog(WebXml.class);
-
+
+ // Global defaults are overridable but Servlets and Servlet mappings need to
+ // be unique. Duplicates normally trigger an error. This flag indicates if
+ // newly added Servlet elements are marked as overridable.
+ private boolean overridable = false;
+ public boolean isOverridable() {
+ return overridable;
+ }
+ public void setOverridable(boolean overridable) {
+ this.overridable = overridable;
+ }
+
// web.xml only elements
// Absolute Ordering
private Set<String> absoluteOrdering = null;
@@ -305,6 +316,9 @@ public class WebXml {
private Map<String,ServletDef> servlets = new HashMap<String,ServletDef>();
public void addServlet(ServletDef servletDef) {
servlets.put(servletDef.getServletName(), servletDef);
+ if (overridable) {
+ servletDef.setOverridable(overridable);
+ }
}
public Map<String,ServletDef> getServlets() { return servlets; }
@@ -1268,6 +1282,7 @@ public class WebXml {
wrapper.setAsyncSupported(
servlet.getAsyncSupported().booleanValue());
}
+ wrapper.setOverridable(servlet.isOverridable());
context.addChild(wrapper);
}
for (Entry<String, String> entry : servletMappings.entrySet()) {
Modified: tomcat/trunk/java/org/apache/catalina/startup/ContextConfig.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/startup/ContextConfig.java?rev=1130618&r1=1130617&r2=1130618&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/startup/ContextConfig.java (original)
+++ tomcat/trunk/java/org/apache/catalina/startup/ContextConfig.java Thu Jun 2 15:54:26 2011
@@ -1186,6 +1186,15 @@ public class ContextConfig
*/
protected void webConfig() {
WebXml webXml = createWebXml();
+ /* Anything and everything can override the global and host defaults.
+ * This is implemented in two parts
+ * - Handle as a web fragment that gets added after everything else so
+ * everything else takes priority
+ * - Mark Servlets as overridable so SCI configuration can replace
+ * configuration from the defaults
+ */
+ WebXml webXmlDefaultFragment = createWebXml();
+ webXmlDefaultFragment.setOverridable(true);
// Parse global web.xml if present
InputSource globalWebXml = getGlobalWebXmlSource();
@@ -1193,17 +1202,19 @@ public class ContextConfig
// This is unusual enough to log
log.info(sm.getString("contextConfig.defaultMissing"));
} else {
- parseWebXml(globalWebXml, webXml, false);
+ parseWebXml(globalWebXml, webXmlDefaultFragment, false);
}
// Parse host level web.xml if present
// Additive apart from welcome pages
webXml.setReplaceWelcomeFiles(true);
InputSource hostWebXml = getHostWebXmlSource();
- parseWebXml(hostWebXml, webXml, false);
+ parseWebXml(hostWebXml, webXmlDefaultFragment, false);
+
+ Set<WebXml> defaults = new HashSet<WebXml>();
+ defaults.add(webXmlDefaultFragment);
// Parse context level web.xml
- webXml.setReplaceWelcomeFiles(true);
InputSource contextWebXml = getContextWebXmlSource();
parseWebXml(contextWebXml, webXml, false);
@@ -1260,16 +1271,19 @@ public class ContextConfig
ok = webXml.merge(orderedFragments);
}
- // Step 6.5 Convert explicitly mentioned jsps to servlets
+ // Step 7. Convert explicitly mentioned jsps to servlets
if (!false) {
convertJsps(webXml);
}
-
- // Step 7. Apply merged web.xml to Context
+
+ // Step 8. Apply global defaults
+ webXml.merge(defaults);
+
+ // Step 9. Apply merged web.xml to Context
if (ok) {
webXml.configureContext(context);
- // Step 7a. Make the merged web.xml available to other
+ // Step 9a. Make the merged web.xml available to other
// components, specifically Jasper, to save those components
// from having to re-generate it.
// TODO Use a ServletContainerInitializer for Jasper
@@ -1282,11 +1296,12 @@ public class ContextConfig
}
}
} else {
+ webXml.merge(defaults);
webXml.configureContext(context);
}
// Always need to look for static resources
- // Step 8. Look for static resources packaged in JARs
+ // Step 10. Look for static resources packaged in JARs
if (ok) {
// Spec does not define an order.
// Use ordered JARs followed by remaining JARs
@@ -1309,7 +1324,7 @@ public class ContextConfig
// Only look for ServletContainerInitializer if metadata is not
// complete
if (!webXml.isMetadataComplete()) {
- // Step 9. Apply the ServletContainerInitializer config to the
+ // Step 11. Apply the ServletContainerInitializer config to the
// context
if (ok) {
for (Map.Entry<ServletContainerInitializer,
@@ -1328,6 +1343,7 @@ public class ContextConfig
} else {
// Apply unmerged web.xml to Context
convertJsps(webXml);
+ webXml.merge(defaults);
webXml.configureContext(context);
}
}
Added: tomcat/trunk/test/org/apache/catalina/startup/TestContextConfig.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/catalina/startup/TestContextConfig.java?rev=1130618&view=auto
==============================================================================
--- tomcat/trunk/test/org/apache/catalina/startup/TestContextConfig.java (added)
+++ tomcat/trunk/test/org/apache/catalina/startup/TestContextConfig.java Thu Jun 2 15:54:26 2011
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * 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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.catalina.startup;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Set;
+
+import javax.servlet.Servlet;
+import javax.servlet.ServletContainerInitializer;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRegistration;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.catalina.core.StandardContext;
+import org.apache.tomcat.util.buf.ByteChunk;
+
+public class TestContextConfig extends TomcatBaseTest {
+
+ public void testOverrideWithSCIDefaultName() throws Exception {
+ doTestOverrideDefaultServletWithSCI("default");
+ }
+
+ public void testOverrideWithSCIDefaultMapping() throws Exception {
+ doTestOverrideDefaultServletWithSCI("anything");
+ }
+
+ private void doTestOverrideDefaultServletWithSCI(String servletName)
+ throws Exception{
+
+ Tomcat tomcat = getTomcatInstance();
+
+ File appDir = new File("test/webapp-3.0");
+ StandardContext ctxt = (StandardContext) tomcat.addContext(null,
+ "/test", appDir.getAbsolutePath());
+ ctxt.setDefaultWebXml(new File("conf/web.xml").getAbsolutePath());
+ ctxt.addLifecycleListener(new ContextConfig());
+
+ ctxt.addServletContainerInitializer(
+ new CustomDefaultServletSCI(servletName), null);
+
+ tomcat.start();
+
+ ByteChunk res = new ByteChunk();
+
+ int rc =getUrl("http://localhost:" + getPort() + "/test", res, null);
+
+ // Check return code
+ assertEquals(HttpServletResponse.SC_OK, rc);
+
+ // Check context
+ assertEquals("OK - Custom default Servlet", res.toString());
+ }
+
+ private static class CustomDefaultServletSCI
+ implements ServletContainerInitializer {
+
+ private String servletName;
+
+ public CustomDefaultServletSCI(String servletName) {
+ this.servletName = servletName;
+ }
+
+ @Override
+ public void onStartup(Set<Class<?>> c, ServletContext ctx)
+ throws ServletException {
+ Servlet s = new CustomDefaultServlet();
+ ServletRegistration.Dynamic r = ctx.addServlet(servletName, s);
+ r.addMapping("/");
+ }
+
+ }
+
+ private static class CustomDefaultServlet extends HttpServlet {
+
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
+ resp.setContentType("text/plain");
+ resp.getWriter().print("OK - Custom default Servlet");
+ }
+ }
+}
Propchange: tomcat/trunk/test/org/apache/catalina/startup/TestContextConfig.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: tomcat/trunk/test/webapp-3.0/index.html
URL: http://svn.apache.org/viewvc/tomcat/trunk/test/webapp-3.0/index.html?rev=1130618&view=auto
==============================================================================
--- tomcat/trunk/test/webapp-3.0/index.html (added)
+++ tomcat/trunk/test/webapp-3.0/index.html Thu Jun 2 15:54:26 2011
@@ -0,0 +1,8 @@
+<html>
+ <head>
+ <title>Index page</title>
+ </head>
+ <body>
+ <p>This is the index page served by the default Servlet.</p>
+ </body>
+</html>
\ No newline at end of file
Propchange: tomcat/trunk/test/webapp-3.0/index.html
------------------------------------------------------------------------------
svn:eol-style = native
Modified: tomcat/trunk/webapps/docs/changelog.xml
URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1130618&r1=1130617&r2=1130618&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/trunk/webapps/docs/changelog.xml Thu Jun 2 15:54:26 2011
@@ -78,6 +78,10 @@
with an incomplete FORM authentication configuration. (markt)
</fix>
<fix>
+ <bug>51278</bug>: Allow ServletContainerInitializers to override
+ settings in the global default web.xml and the host web.xml. (markt)
+ </fix>
+ <fix>
<bug>51310</bug>: When stopping the Server object on shutdown call
destroy() after calling stop(). (markt)
</fix>
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org