Author: markt
Date: Fri Jun 22 08:46:55 2012
New Revision: 1352803
URL: http://svn.apache.org/viewvc?rev=1352803&view=rev
Log:
metadata-complete does not control the processing of
ServletContainerInitializers
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/test/org/apache/catalina/startup/TestContextConfigAnnotation.java
tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml
Propchange: tomcat/tc7.0.x/trunk/
------------------------------------------------------------------------------
Merged /tomcat/trunk:r1352799
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=1352803&r1=1352802&r2=1352803&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:46:55 2012
@@ -1210,8 +1210,15 @@ public class ContextConfig implements Li
* - 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).
+ * - As per http://java.net/jira/browse/SERVLET_SPEC-36, if the main
+ * web.xml is marked as metadata-complete, JARs are still processed
+ * for SCIs.
+ * - TBD. If metadata-complete=true and an absolute ordering is
+ * specified, are JARs excluded from the ordering also excluded from
+ * the SCI processing? Current assumption is that they are.
+ * - If an SCI has a @HandlesType annotation then all classes (except
+ * those in JARs excluded from an absolute ordering) need to be
+ * scanned to check if they match.
*/
Set<WebXml> defaults = new HashSet<WebXml>();
defaults.add(getDefaultWebXmlFragment());
@@ -1231,20 +1238,17 @@ public class ContextConfig implements Li
// point.
Map<String,WebXml> fragments = processJarsForWebFragments();
- // Only need to process fragments and annotations if metadata is
- // not complete
+ // Step 2. Order the fragments.
Set<WebXml> orderedFragments = null;
- if (!webXml.isMetadataComplete()) {
- // Step 2. Order the fragments.
- orderedFragments = WebXml.orderWebFragments(webXml, 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);
+ }
+ if (!webXml.isMetadataComplete() || typeInitializerMap.size() > 0) {
// 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
@@ -1263,13 +1267,15 @@ public class ContextConfig implements Li
if (binding.getObject() instanceof FileDirContext) {
File webInfClassDir = new File(
((FileDirContext)
binding.getObject()).getDocBase());
- processAnnotationsFile(webInfClassDir, webXml);
+ processAnnotationsFile(webInfClassDir, webXml,
+ webXml.isMetadataComplete());
} else {
String resource =
"/WEB-INF/classes/" + binding.getName();
try {
URL url = sContext.getResource(resource);
- processAnnotationsUrl(url, webXml);
+ processAnnotationsUrl(url, webXml,
+ webXml.isMetadataComplete());
} catch (MalformedURLException e) {
log.error(sm.getString(
"contextConfig.webinfClassesUrl",
@@ -1286,14 +1292,16 @@ public class ContextConfig implements Li
// 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);
+ processAnnotations(
+ orderedFragments, webXml.isMetadataComplete());
}
// Cache, if used, is no longer required so clear it
javaClassCache.clear();
+ }
+ if (!webXml.isMetadataComplete()) {
// Step 6. Merge web-fragment.xml files into the main web.xml
// file.
if (ok) {
@@ -1352,22 +1360,18 @@ public class ContextConfig implements Li
// 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());
- }
+ // 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());
}
}
}
@@ -1879,33 +1883,35 @@ public class ContextConfig implements Li
return callback.getFragments();
}
- protected void processAnnotations(Set<WebXml> fragments) {
+ protected void processAnnotations(Set<WebXml> fragments,
+ boolean handlesTypesOnly) {
for(WebXml fragment : fragments) {
- if (!fragment.isMetadataComplete()) {
- WebXml annotations = new WebXml();
- // no impact on distributable
- annotations.setDistributable(true);
- URL url = fragment.getURL();
- processAnnotationsUrl(url, annotations);
- Set<WebXml> set = new HashSet<WebXml>();
- set.add(annotations);
- // Merge annotations into fragment - fragment takes priority
- fragment.merge(set);
- }
+ WebXml annotations = new WebXml();
+ // no impact on distributable
+ annotations.setDistributable(true);
+ URL url = fragment.getURL();
+ processAnnotationsUrl(url, annotations,
+ (handlesTypesOnly || fragment.isMetadataComplete()));
+ Set<WebXml> set = new HashSet<WebXml>();
+ set.add(annotations);
+ // Merge annotations into fragment - fragment takes priority
+ fragment.merge(set);
}
}
- protected void processAnnotationsUrl(URL url, WebXml fragment) {
+ protected void processAnnotationsUrl(URL url, WebXml fragment,
+ boolean handlesTypesOnly) {
if (url == null) {
// Nothing to do.
return;
} else if ("jar".equals(url.getProtocol())) {
- processAnnotationsJar(url, fragment);
+ processAnnotationsJar(url, fragment, handlesTypesOnly);
} else if ("jndi".equals(url.getProtocol())) {
- processAnnotationsJndi(url, fragment);
+ processAnnotationsJndi(url, fragment, handlesTypesOnly);
} else if ("file".equals(url.getProtocol())) {
try {
- processAnnotationsFile(new File(url.toURI()), fragment);
+ processAnnotationsFile(
+ new File(url.toURI()), fragment, handlesTypesOnly);
} catch (URISyntaxException e) {
log.error(sm.getString("contextConfig.fileUrl", url), e);
}
@@ -1917,7 +1923,8 @@ public class ContextConfig implements Li
}
- protected void processAnnotationsJar(URL url, WebXml fragment) {
+ protected void processAnnotationsJar(URL url, WebXml fragment,
+ boolean handlesTypesOnly) {
Jar jar = null;
InputStream is;
@@ -1932,7 +1939,8 @@ public class ContextConfig implements Li
is = null;
try {
is = jar.getEntryInputStream();
- processAnnotationsStream(is, fragment);
+ processAnnotationsStream(
+ is, fragment, handlesTypesOnly);
} catch (IOException e) {
log.error(sm.getString("contextConfig.inputStreamJar",
entryName, url),e);
@@ -1962,7 +1970,8 @@ public class ContextConfig implements Li
}
- protected void processAnnotationsJndi(URL url, WebXml fragment) {
+ protected void processAnnotationsJndi(URL url, WebXml fragment,
+ boolean handlesTypesOnly) {
try {
URLConnection urlConn = url.openConnection();
DirContextURLConnection dcUrlConn;
@@ -1982,7 +1991,7 @@ public class ContextConfig implements Li
while (dirs.hasMoreElements()) {
String dir = dirs.nextElement();
URL dirUrl = new URL(url.toString() + '/' + dir);
- processAnnotationsJndi(dirUrl, fragment);
+ processAnnotationsJndi(dirUrl, fragment, handlesTypesOnly);
}
} else {
@@ -1991,7 +2000,8 @@ public class ContextConfig implements Li
InputStream is = null;
try {
is = dcUrlConn.getInputStream();
- processAnnotationsStream(is, fragment);
+ processAnnotationsStream(
+ is, fragment, handlesTypesOnly);
} catch (IOException e) {
log.error(sm.getString("contextConfig.inputStreamJndi",
url),e);
@@ -2015,18 +2025,20 @@ public class ContextConfig implements Li
}
- protected void processAnnotationsFile(File file, WebXml fragment) {
+ protected void processAnnotationsFile(File file, WebXml fragment,
+ boolean handlesTypesOnly) {
if (file.isDirectory()) {
String[] dirs = file.list();
for (String dir : dirs) {
- processAnnotationsFile(new File(file,dir), fragment);
+ processAnnotationsFile(
+ new File(file,dir), fragment, handlesTypesOnly);
}
} else if (file.canRead() && file.getName().endsWith(".class")) {
FileInputStream fis = null;
try {
fis = new FileInputStream(file);
- processAnnotationsStream(fis, fragment);
+ processAnnotationsStream(fis, fragment, handlesTypesOnly);
} catch (IOException e) {
log.error(sm.getString("contextConfig.inputStreamFile",
file.getAbsolutePath()),e);
@@ -2046,7 +2058,8 @@ public class ContextConfig implements Li
}
- protected void processAnnotationsStream(InputStream is, WebXml fragment)
+ protected void processAnnotationsStream(InputStream is, WebXml fragment,
+ boolean handlesTypesOnly)
throws ClassFormatException, IOException {
ClassParser parser = new ClassParser(is, null);
@@ -2054,6 +2067,10 @@ public class ContextConfig implements Li
checkHandlesTypes(clazz);
+ if (handlesTypesOnly) {
+ return;
+ }
+
String className = clazz.getClassName();
AnnotationEntry[] annotationsEntries = clazz.getAnnotationEntries();
Modified:
tomcat/tc7.0.x/trunk/test/org/apache/catalina/startup/TestContextConfigAnnotation.java
URL:
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/test/org/apache/catalina/startup/TestContextConfigAnnotation.java?rev=1352803&r1=1352802&r2=1352803&view=diff
==============================================================================
---
tomcat/tc7.0.x/trunk/test/org/apache/catalina/startup/TestContextConfigAnnotation.java
(original)
+++
tomcat/tc7.0.x/trunk/test/org/apache/catalina/startup/TestContextConfigAnnotation.java
Fri Jun 22 08:46:55 2012
@@ -60,7 +60,7 @@ public class TestContextConfigAnnotation
File pFile = paramClassResource(
"org/apache/catalina/startup/ParamServlet");
assertTrue(pFile.exists());
- config.processAnnotationsFile(pFile, webxml);
+ config.processAnnotationsFile(pFile, webxml, false);
ServletDef servletDef = webxml.getServlets().get("param");
assertNotNull(servletDef);
assertEquals("Hello", servletDef.getParameterMap().get("foo"));
@@ -99,7 +99,7 @@ public class TestContextConfigAnnotation
File pFile = paramClassResource(
"org/apache/catalina/startup/ParamServlet");
assertTrue(pFile.exists());
- config.processAnnotationsFile(pFile, webxml);
+ config.processAnnotationsFile(pFile, webxml, false);
assertEquals(servletDef, webxml.getServlets().get("param"));
@@ -126,12 +126,12 @@ public class TestContextConfigAnnotation
File pFile = paramClassResource(
"org/apache/catalina/startup/NoMappingParamServlet");
assertTrue(pFile.exists());
- config.processAnnotationsFile(pFile, webxml);
+ config.processAnnotationsFile(pFile, webxml, false);
ServletDef servletDef = webxml.getServlets().get("param1");
assertNull(servletDef);
webxml.addServletMapping("/param", "param1");
- config.processAnnotationsFile(pFile, webxml);
+ config.processAnnotationsFile(pFile, webxml, false);
servletDef = webxml.getServlets().get("param1");
assertNull(servletDef);
@@ -152,7 +152,7 @@ public class TestContextConfigAnnotation
File pFile = paramClassResource(
"org/apache/catalina/startup/NoMappingParamServlet");
assertTrue(pFile.exists());
- config.processAnnotationsFile(pFile, webxml);
+ config.processAnnotationsFile(pFile, webxml, false);
assertEquals("tomcat", servletDef.getParameterMap().get("foo"));
assertEquals("World!", servletDef.getParameterMap().get("bar"));
ServletDef servletDef1 = webxml.getServlets().get("param1");
@@ -168,7 +168,7 @@ public class TestContextConfigAnnotation
"org/apache/catalina/startup/DuplicateMappingParamServlet");
assertTrue(pFile.exists());
try {
- config.processAnnotationsFile(pFile, webxml);
+ config.processAnnotationsFile(pFile, webxml, false);
fail();
} catch (IllegalArgumentException ex) {
// ignore
@@ -183,10 +183,10 @@ public class TestContextConfigAnnotation
ContextConfig config = new ContextConfig();
File sFile = paramClassResource(
"org/apache/catalina/startup/ParamServlet");
- config.processAnnotationsFile(sFile, webxml);
+ config.processAnnotationsFile(sFile, webxml, false);
File fFile = paramClassResource(
"org/apache/catalina/startup/ParamFilter");
- config.processAnnotationsFile(fFile, webxml);
+ config.processAnnotationsFile(fFile, webxml, false);
FilterDef fdef = webxml.getFilters().get("paramFilter");
assertNotNull(fdef);
assertEquals("Servlet says: ",fdef.getParameterMap().get("message"));
@@ -215,10 +215,10 @@ public class TestContextConfigAnnotation
ContextConfig config = new ContextConfig();
File sFile = paramClassResource(
"org/apache/catalina/startup/ParamServlet");
- config.processAnnotationsFile(sFile, webxml);
+ config.processAnnotationsFile(sFile, webxml, false);
File fFile = paramClassResource(
"org/apache/catalina/startup/ParamFilter");
- config.processAnnotationsFile(fFile, webxml);
+ config.processAnnotationsFile(fFile, webxml, false);
FilterDef fdef = webxml.getFilters().get("paramFilter");
assertNotNull(fdef);
assertEquals(filterDef,fdef);
@@ -255,7 +255,7 @@ public class TestContextConfigAnnotation
"org/apache/catalina/startup/DuplicateMappingParamFilter");
assertTrue(pFile.exists());
try {
- config.processAnnotationsFile(pFile, webxml);
+ config.processAnnotationsFile(pFile, webxml, false);
fail();
} catch (IllegalArgumentException ex) {
// ignore
@@ -297,13 +297,13 @@ public class TestContextConfigAnnotation
WebXml ignore = new WebXml();
File file = paramClassResource(
"org/apache/catalina/startup/ParamServlet");
- config.processAnnotationsFile(file, ignore);
+ config.processAnnotationsFile(file, ignore, false);
file = paramClassResource("org/apache/catalina/startup/ParamFilter");
- config.processAnnotationsFile(file, ignore);
+ config.processAnnotationsFile(file, ignore, false);
file = paramClassResource("org/apache/catalina/startup/TesterServlet");
- config.processAnnotationsFile(file, ignore);
+ config.processAnnotationsFile(file, ignore, false);
file = paramClassResource("org/apache/catalina/startup/TestListener");
- config.processAnnotationsFile(file, ignore);
+ config.processAnnotationsFile(file, ignore, false);
// Check right number of classes were noted to be handled
assertEquals(0, config.initializerClassMap.get(sciNone).size());
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=1352803&r1=1352802&r2=1352803&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:46:55 2012
@@ -77,6 +77,11 @@
Annotation scanning is now always performed - regardless of the version
declared in web.xml - unless metadata complete is set to true. (markt)
</fix>
+ <fix>
+ As per clarification from the Servlet Expert Group, JARs are always
+ checked for ServletContainerInitializers regardless of the setting of
+ metadata complete. (markt)
+ </fix>
</changelog>
</subsection>
<subsection name="Web applications">
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]