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 1c16dd17117..f35c5811074 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 @@ -71,7 +71,10 @@ public class AnnotationParser private static final Logger LOG = Log.getLogger(AnnotationParser.class); protected static int ASM_OPCODE_VERSION = Opcodes.ASM6; //compatibility of api - protected Map> _parsedClassNames = new ConcurrentHashMap<>(); + /** + * Map of classnames scanned and the first location from which scan occurred + */ + protected Map _parsedClassNames = new ConcurrentHashMap<>(); private final int _javaPlatform; private int _asmVersion; @@ -561,17 +564,11 @@ public class AnnotationParser */ public void addParsedClass (String classname, Resource location) { - List list = new ArrayList<>(1); - if (location != null) - list.add(location.toString()); - - List existing = _parsedClassNames.putIfAbsent(classname, list); + Resource existing = _parsedClassNames.putIfAbsent(classname, location); if (existing != null) - { - existing.addAll(list); - LOG.warn("{} scanned from multiple locations: {}", classname, existing); - } + LOG.warn("{} scanned from multiple locations: {}, {}", classname, existing, location); } + /** * Get the locations of the given classname. There may be more than one @@ -579,13 +576,13 @@ public class AnnotationParser * * @param classname the name of the class * @return an immutable list of locations + * + * @deprecated List of duplicate locations no longer stored */ + @Deprecated public List getParsedLocations (String classname) { - List list = _parsedClassNames.get(classname); - if (list == null) - return Collections.emptyList(); - return Collections.unmodifiableList(list); + return Collections.emptyList(); } /** diff --git a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestAnnotationParser.java b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestAnnotationParser.java index 590947d3883..23725cff2d6 100644 --- a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestAnnotationParser.java +++ b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestAnnotationParser.java @@ -35,7 +35,10 @@ import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArrayList; import org.eclipse.jetty.annotations.AnnotationParser.ClassInfo; import org.eclipse.jetty.annotations.AnnotationParser.FieldInfo; @@ -71,6 +74,33 @@ public class TestAnnotationParser foundClasses.add(info.getClassName()); } } + + + public static class DuplicateClassScanHandler extends AnnotationParser.AbstractHandler + { + private Map> _classMap = new ConcurrentHashMap(); + + @Override + public void handle(ClassInfo info) + { + List list = new CopyOnWriteArrayList<>(); + Resource r = info.getContainingResource(); + list.add((r==null?"":r.toString())); + + List existing = _classMap.putIfAbsent(info.getClassName(), list); + if (existing != null) + { + existing.addAll(list); + } + } + + + public List getParsedList(String classname) + { + return _classMap.get(classname); + } + + } @Rule public TestingDir testdir = new TestingDir(); @@ -219,10 +249,11 @@ public class TestAnnotationParser Resource testJar = Resource.newResource(MavenTestingUtils.getTestResourceFile("tinytest.jar")); Resource testJar2 = Resource.newResource(MavenTestingUtils.getTestResourceFile("tinytest_copy.jar")); AnnotationParser parser = new AnnotationParser(); - Set emptySet = Collections.emptySet(); - parser.parse(emptySet, testJar); - parser.parse(emptySet, testJar2); - List locations = parser.getParsedLocations("org.acme.ClassOne"); + DuplicateClassScanHandler handler = new DuplicateClassScanHandler(); + Set handlers = Collections.singleton(handler); + parser.parse(handlers, testJar); + parser.parse(handlers, testJar2); + List locations = handler.getParsedList("org.acme.ClassOne"); Assert.assertNotNull(locations); Assert.assertEquals(2, locations.size()); Assert.assertTrue(!(locations.get(0).equals(locations.get(1)))); @@ -235,10 +266,11 @@ public class TestAnnotationParser Resource testJar = Resource.newResource(MavenTestingUtils.getTestResourceFile("tinytest.jar")); File testClasses = new File(MavenTestingUtils.getTargetDir(), "test-classes"); AnnotationParser parser = new AnnotationParser(); - Set emptySet = Collections.emptySet(); - parser.parse(emptySet, testJar); - parser.parse(emptySet, Resource.newResource(testClasses)); - List locations = parser.getParsedLocations("org.acme.ClassOne"); + DuplicateClassScanHandler handler = new DuplicateClassScanHandler(); + Set handlers = Collections.singleton(handler); + parser.parse(handlers, testJar); + parser.parse(handlers, Resource.newResource(testClasses)); + Listlocations = handler.getParsedList("org.acme.ClassOne"); Assert.assertNotNull(locations); Assert.assertEquals(2, locations.size()); Assert.assertTrue(!(locations.get(0).equals(locations.get(1))));