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

Reply via email to