From b8a4bf37e6b77a19498e9068222c9ccc8c3bd899 Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Thu, 5 Sep 2013 18:24:12 +1000 Subject: [PATCH] 416597 Allow classes and jars on the webappcontext extraclasspath to be scanned for annotations --- .../annotations/AnnotationConfiguration.java | 162 ++++++++++-------- .../jetty/annotations/AnnotationParser.java | 28 ++- .../org/eclipse/jetty/webapp/MetaData.java | 12 ++ .../jetty/webapp/WebInfConfiguration.java | 136 ++++++++++++++- 4 files changed, 257 insertions(+), 81 deletions(-) diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationConfiguration.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationConfiguration.java index 3672db4c0f2..eaa7c009cbc 100644 --- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationConfiguration.java +++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationConfiguration.java @@ -24,6 +24,7 @@ import java.util.EventListener; import java.util.Iterator; import java.util.List; import java.util.ServiceLoader; +import java.util.StringTokenizer; import javax.servlet.ServletContainerInitializer; import javax.servlet.annotation.HandlesTypes; @@ -59,6 +60,81 @@ public class AnnotationConfiguration extends AbstractConfiguration protected List _containerInitializerAnnotationHandlers = new ArrayList(); + /** + * WebAppClassNameResolver + * + * Checks to see if a classname belongs to hidden or visible packages when scanning, + * and whether a classname that is a duplicate should override a previously + * scanned classname. + * + * This is analogous to the management of classes that the WebAppClassLoader is doing, + * however we don't want to load the classes at this point so we are doing it on + * the name only. + * + */ + public class WebAppClassNameResolver implements ClassNameResolver + { + private WebAppContext _context; + + public WebAppClassNameResolver (WebAppContext context) + { + _context = context; + } + + public boolean isExcluded (String name) + { + if (_context.isSystemClass(name)) return true; + if (_context.isServerClass(name)) return false; + return false; + } + + public boolean shouldOverride (String name) + { + //looking at webapp classpath, found already-parsed class + //of same name - did it come from system or duplicate in webapp? + if (_context.isParentLoaderPriority()) + return false; + return true; + } + } + + + /** + * ContainerClassNameResolver + * + * Checks to see if a classname belongs to a hidden or visible package + * when scanning for annotations and thus whether it should be excluded from + * consideration or not. + * + * This is analogous to the management of classes that the WebAppClassLoader is doing, + * however we don't want to load the classes at this point so we are doing it on + * the name only. + * + */ + public class ContainerClassNameResolver implements ClassNameResolver + { + private WebAppContext _context; + + public ContainerClassNameResolver (WebAppContext context) + { + _context = context; + } + public boolean isExcluded (String name) + { + if (_context.isSystemClass(name)) return false; + if (_context.isServerClass(name)) return true; + return false; + } + + public boolean shouldOverride (String name) + { + //visiting the container classpath, + if (_context.isParentLoaderPriority()) + return true; + return false; + } + } + @Override public void preConfigure(final WebAppContext context) throws Exception { @@ -351,25 +427,7 @@ public class AnnotationConfiguration extends AbstractConfiguration } parser.parse (containerUris.toArray(new URI[containerUris.size()]), - new ClassNameResolver () - { - public boolean isExcluded (String name) - { - if (context.isSystemClass(name)) return false; - if (context.isServerClass(name)) return true; - return false; - } - - public boolean shouldOverride (String name) - { - //looking at system classpath - if (context.isParentLoaderPriority()) - return true; - return false; - } - }); - - + new ContainerClassNameResolver (context)); } @@ -427,24 +485,7 @@ public class AnnotationConfiguration extends AbstractConfiguration parser.registerHandlers(_discoverableAnnotationHandlers); } - parser.parse(uri, - new ClassNameResolver() - { - public boolean isExcluded (String name) - { - if (context.isSystemClass(name)) return true; - if (context.isServerClass(name)) return false; - return false; - } - - public boolean shouldOverride (String name) - { - //looking at webapp classpath, found already-parsed class of same name - did it come from system or duplicate in webapp? - if (context.isParentLoaderPriority()) - return false; - return true; - } - }); + parser.parse(uri, new WebAppClassNameResolver(context)); } } } @@ -460,45 +501,26 @@ public class AnnotationConfiguration extends AbstractConfiguration throws Exception { LOG.debug("Scanning classes in WEB-INF/classes"); - if (context.getWebInf() != null) - { - Resource classesDir = context.getWebInf().addPath("classes/"); - if (classesDir.exists()) - { - parser.clearHandlers(); - for (DiscoverableAnnotationHandler h:_discoverableAnnotationHandlers) - { - if (h instanceof AbstractDiscoverableAnnotationHandler) - ((AbstractDiscoverableAnnotationHandler)h).setResource(null); // - } - parser.registerHandlers(_discoverableAnnotationHandlers); - parser.registerHandler(_classInheritanceHandler); - parser.registerHandlers(_containerInitializerAnnotationHandlers); - - parser.parseDir(classesDir, - new ClassNameResolver() - { - public boolean isExcluded (String name) - { - if (context.isSystemClass(name)) return true; - if (context.isServerClass(name)) return false; - return false; - } - public boolean shouldOverride (String name) - { - //looking at webapp classpath, found already-parsed class of same name - did it come from system or duplicate in webapp? - if (context.isParentLoaderPriority()) return false; - return true; - } - }); - } + parser.clearHandlers(); + for (DiscoverableAnnotationHandler h:_discoverableAnnotationHandlers) + { + if (h instanceof AbstractDiscoverableAnnotationHandler) + ((AbstractDiscoverableAnnotationHandler)h).setResource(null); // + } + parser.registerHandlers(_discoverableAnnotationHandlers); + parser.registerHandler(_classInheritanceHandler); + parser.registerHandlers(_containerInitializerAnnotationHandlers); + + for (Resource dir : context.getMetaData().getWebInfClassesDirs()) + { + parser.parseDir(dir, new WebAppClassNameResolver(context)); } } - /** + /** * Get the web-fragment.xml from a jar * * @param jar diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationParser.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationParser.java index c8048f462ee..4607f139fc7 100644 --- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationParser.java +++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationParser.java @@ -758,7 +758,7 @@ public class AnnotationParser return; if (LOG.isDebugEnabled()) {LOG.debug("Scanning dir {}", dir);}; - + String[] files=dir.list(); for (int f=0;files!=null && f