Author: markt
Date: Fri Jun 22 08:44:24 2012
New Revision: 1352802
URL: http://svn.apache.org/viewvc?rev=1352802&view=rev
Log:
As per clarification from Servlet EG, version declared in web.xml does not
control annotation scanning. I don't like it but the EG was very clear this was
the intended behaviour.
Modified:
tomcat/tc7.0.x/trunk/ (props changed)
tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/ContextConfig.java
tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml
Propchange: tomcat/tc7.0.x/trunk/
------------------------------------------------------------------------------
Merged /tomcat/trunk:r1352788
Modified:
tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/ContextConfig.java
URL:
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/ContextConfig.java?rev=1352802&r1=1352801&r2=1352802&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/ContextConfig.java
(original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/ContextConfig.java
Fri Jun 22 08:44:24 2012
@@ -1195,13 +1195,24 @@ public class ContextConfig implements Li
* web.xml file.
*/
protected void webConfig() {
- /* Anything and everything can override the global and host defaults.
+ /*
+ * 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
*/
+
+ /*
+ * The rules for annotation scanning are not as clear-cut as one might
+ * think. Tomcat implements the following process:
+ * - As per SRV.1.6.2, Tomcat will scan for annotations regardless of
+ * which Servlet spec version is declared in web.xml. The EG has
+ * confirmed this is the expected behaviour.
+ * - This is not yet complete. Further clarifications (and possible
code
+ * changes to follow).
+ */
Set<WebXml> defaults = new HashSet<WebXml>();
defaults.add(getDefaultWebXmlFragment());
@@ -1211,161 +1222,154 @@ public class ContextConfig implements Li
InputSource contextWebXml = getContextWebXmlSource();
parseWebXml(contextWebXml, webXml, false);
- if (webXml.getMajorVersion() >= 3) {
- ServletContext sContext = context.getServletContext();
+ ServletContext sContext = context.getServletContext();
- // Ordering is important here
+ // Ordering is important here
- // Step 1. Identify all the JARs packaged with the application
- // If the JARs have a web-fragment.xml it will be parsed at this
- // point.
- Map<String,WebXml> fragments = processJarsForWebFragments();
-
- // Only need to process fragments and annotations if metadata is
- // not complete
- Set<WebXml> orderedFragments = null;
- if (!webXml.isMetadataComplete()) {
- // Step 2. Order the fragments.
- orderedFragments = WebXml.orderWebFragments(webXml, fragments);
+ // Step 1. Identify all the JARs packaged with the application
+ // If the JARs have a web-fragment.xml it will be parsed at this
+ // point.
+ Map<String,WebXml> fragments = processJarsForWebFragments();
+
+ // Only need to process fragments and annotations if metadata is
+ // not complete
+ Set<WebXml> orderedFragments = null;
+ if (!webXml.isMetadataComplete()) {
+ // Step 2. Order the fragments.
+ orderedFragments = WebXml.orderWebFragments(webXml, fragments);
- // Step 3. Look for ServletContainerInitializer implementations
- if (ok) {
- processServletContainerInitializers(orderedFragments);
- }
+ // Step 3. Look for ServletContainerInitializer implementations
+ if (ok) {
+ processServletContainerInitializers(orderedFragments);
+ }
- // Step 4. Process /WEB-INF/classes for annotations
- // This will add any matching classes to the typeInitializerMap
- if (ok) {
- // Hack required by Eclipse's "serve modules without
- // publishing" feature since this backs WEB-INF/classes by
- // multiple locations rather than one.
- NamingEnumeration<Binding> listBindings = null;
+ // Step 4. Process /WEB-INF/classes for annotations
+ // This will add any matching classes to the typeInitializerMap
+ if (ok) {
+ // Hack required by Eclipse's "serve modules without
+ // publishing" feature since this backs WEB-INF/classes by
+ // multiple locations rather than one.
+ NamingEnumeration<Binding> listBindings = null;
+ try {
try {
- try {
- listBindings = context.getResources().listBindings(
- "/WEB-INF/classes");
- } catch (NameNotFoundException ignore) {
- // Safe to ignore
- }
- while (listBindings != null &&
- listBindings.hasMoreElements()) {
- Binding binding = listBindings.nextElement();
- if (binding.getObject() instanceof FileDirContext)
{
- File webInfClassDir = new File(
- ((FileDirContext)
binding.getObject()).getDocBase());
- processAnnotationsFile(webInfClassDir, webXml);
- } else {
- String resource =
- "/WEB-INF/classes/" +
binding.getName();
- try {
- URL url = sContext.getResource(resource);
- processAnnotationsUrl(url, webXml);
- } catch (MalformedURLException e) {
- log.error(sm.getString(
- "contextConfig.webinfClassesUrl",
- resource), e);
- }
+ listBindings = context.getResources().listBindings(
+ "/WEB-INF/classes");
+ } catch (NameNotFoundException ignore) {
+ // Safe to ignore
+ }
+ while (listBindings != null &&
+ listBindings.hasMoreElements()) {
+ Binding binding = listBindings.nextElement();
+ if (binding.getObject() instanceof FileDirContext) {
+ File webInfClassDir = new File(
+ ((FileDirContext)
binding.getObject()).getDocBase());
+ processAnnotationsFile(webInfClassDir, webXml);
+ } else {
+ String resource =
+ "/WEB-INF/classes/" + binding.getName();
+ try {
+ URL url = sContext.getResource(resource);
+ processAnnotationsUrl(url, webXml);
+ } catch (MalformedURLException e) {
+ log.error(sm.getString(
+ "contextConfig.webinfClassesUrl",
+ resource), e);
}
}
- } catch (NamingException e) {
- log.error(sm.getString(
- "contextConfig.webinfClassesUrl",
- "/WEB-INF/classes"), e);
}
+ } catch (NamingException e) {
+ log.error(sm.getString(
+ "contextConfig.webinfClassesUrl",
+ "/WEB-INF/classes"), e);
}
+ }
+
+ // Step 5. Process JARs for annotations - only need to process
+ // those fragments we are going to use
+ // This will add any matching classes to the typeInitializerMap
+ if (ok) {
+ processAnnotations(orderedFragments);
+ }
- // Step 5. Process JARs for annotations - only need to process
- // those fragments we are going to use
- // This will add any matching classes to the typeInitializerMap
- if (ok) {
- processAnnotations(orderedFragments);
- }
-
- // Cache, if used, is no longer required so clear it
- javaClassCache.clear();
+ // Cache, if used, is no longer required so clear it
+ javaClassCache.clear();
- // Step 6. Merge web-fragment.xml files into the main web.xml
- // file.
- if (ok) {
- ok = webXml.merge(orderedFragments);
- }
+ // Step 6. Merge web-fragment.xml files into the main web.xml
+ // file.
+ if (ok) {
+ ok = webXml.merge(orderedFragments);
+ }
- // Step 7. Apply global defaults
- // Have to merge defaults before JSP conversion since defaults
- // provide JSP servlet definition.
- webXml.merge(defaults);
-
- // Step 8. Convert explicitly mentioned jsps to servlets
- if (ok) {
- convertJsps(webXml);
- }
+ // Step 7. Apply global defaults
+ // Have to merge defaults before JSP conversion since defaults
+ // provide JSP servlet definition.
+ webXml.merge(defaults);
+
+ // Step 8. Convert explicitly mentioned jsps to servlets
+ if (ok) {
+ convertJsps(webXml);
+ }
- // Step 9. Apply merged web.xml to Context
- if (ok) {
- webXml.configureContext(context);
+ // Step 9. Apply merged web.xml to Context
+ if (ok) {
+ webXml.configureContext(context);
- // 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
- String mergedWebXml = webXml.toXml();
- sContext.setAttribute(
-
org.apache.tomcat.util.scan.Constants.MERGED_WEB_XML,
- mergedWebXml);
- if (context.getLogEffectiveWebXml()) {
- log.info("web.xml:\n" + mergedWebXml);
- }
+ // 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
+ String mergedWebXml = webXml.toXml();
+ sContext.setAttribute(
+ org.apache.tomcat.util.scan.Constants.MERGED_WEB_XML,
+ mergedWebXml);
+ if (context.getLogEffectiveWebXml()) {
+ log.info("web.xml:\n" + mergedWebXml);
}
- } else {
- webXml.merge(defaults);
- webXml.configureContext(context);
}
-
- // Always need to look for static resources
- // Step 10. Look for static resources packaged in JARs
+ } else {
+ webXml.merge(defaults);
+ webXml.configureContext(context);
+ }
+
+ // Always need to look for static resources
+ // Step 10. Look for static resources packaged in JARs
+ if (ok) {
+ // Spec does not define an order.
+ // Use ordered JARs followed by remaining JARs
+ Set<WebXml> resourceJars = new LinkedHashSet<WebXml>();
+ if (orderedFragments != null) {
+ for (WebXml fragment : orderedFragments) {
+ resourceJars.add(fragment);
+ }
+ }
+ for (WebXml fragment : fragments.values()) {
+ if (!resourceJars.contains(fragment)) {
+ resourceJars.add(fragment);
+ }
+ }
+ processResourceJARs(resourceJars);
+ // See also StandardContext.resourcesStart() for
+ // WEB-INF/classes/META-INF/resources configuration
+ }
+
+ // Only look for ServletContainerInitializer if metadata is not
+ // complete
+ if (!webXml.isMetadataComplete()) {
+ // Step 11. Apply the ServletContainerInitializer config to the
+ // context
if (ok) {
- // Spec does not define an order.
- // Use ordered JARs followed by remaining JARs
- Set<WebXml> resourceJars = new LinkedHashSet<WebXml>();
- if (orderedFragments != null) {
- for (WebXml fragment : orderedFragments) {
- resourceJars.add(fragment);
- }
- }
- for (WebXml fragment : fragments.values()) {
- if (!resourceJars.contains(fragment)) {
- resourceJars.add(fragment);
- }
- }
- processResourceJARs(resourceJars);
- // See also StandardContext.resourcesStart() for
- // WEB-INF/classes/META-INF/resources configuration
- }
-
- // Only look for ServletContainerInitializer if metadata is not
- // complete
- if (!webXml.isMetadataComplete()) {
- // Step 11. Apply the ServletContainerInitializer config to the
- // context
- if (ok) {
- for (Map.Entry<ServletContainerInitializer,
- Set<Class<?>>> entry :
- initializerClassMap.entrySet()) {
- if (entry.getValue().isEmpty()) {
- context.addServletContainerInitializer(
- entry.getKey(), null);
- } else {
- context.addServletContainerInitializer(
- entry.getKey(), entry.getValue());
- }
+ for (Map.Entry<ServletContainerInitializer,
+ Set<Class<?>>> entry :
+ initializerClassMap.entrySet()) {
+ if (entry.getValue().isEmpty()) {
+ context.addServletContainerInitializer(
+ entry.getKey(), null);
+ } else {
+ context.addServletContainerInitializer(
+ entry.getKey(), entry.getValue());
}
}
}
- } else {
- // Apply unmerged web.xml to Context
- webXml.merge(defaults);
- convertJsps(webXml);
- webXml.configureContext(context);
}
}
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=1352802&r1=1352801&r2=1352802&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml Fri Jun 22 08:44:24 2012
@@ -70,6 +70,13 @@
could easily trigger a deadlock when deploying a ROOT web application.
(markt)
</fix>
+ <fix>
+ As per section 1.6.2 of the Servlet 3.0 specification and clarification
+ from the Servlet Expert Group, the servlet specification version
+ declared in web.xml no longer controls if Tomcat scans for annotations.
+ Annotation scanning is now always performed - regardless of the version
+ declared in web.xml - unless metadata complete is set to true. (markt)
+ </fix>
</changelog>
</subsection>
<subsection name="Web applications">
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]