Switch to ClassGraph
authorStephen Kitt <skitt@redhat.com>
Wed, 10 Oct 2018 11:38:46 +0000 (13:38 +0200)
committerMichael Vorburger <mike@vorburger.ch>
Wed, 1 Jul 2020 23:37:08 +0000 (01:37 +0200)
Closes: #38
Signed-off-by: Stephen Kitt <skitt@redhat.com>
TODO.md
pom.xml
src/main/java/org/opendaylight/infrautils/inject/ClassPathScanner.java

diff --git a/TODO.md b/TODO.md
index 723521722c48a4a840926fb3266e25c4e76cd0b4..4a055a2e72a26f0612f3796b51504e7e0762de21 100644 (file)
--- a/TODO.md
+++ b/TODO.md
@@ -33,7 +33,7 @@
 - [ ] MINOR: why does "java -jar lib/ch.vorburger.opendaylight.simple.poc-1.5.0-SNAPSHOT.jar" not work?  (MANIFEST.MF has all lib/*)
 
 - [ ] create a Binding Generator? (reflecting upon annotated classes)
-- [ ] [re-implement ClassPathScanner](https://github.com/vorburger/opendaylight-simple/pull/18#issuecomment-426859615) using [ClassGraph](https://github.com/classgraph/classgraph) used in [INFRAUTILS-52](https://jira.opendaylight.org/browse/INFRAUTILS-52) (and rename it to something more appropriate)
+- [X] [re-implement ClassPathScanner](https://github.com/vorburger/opendaylight-simple/pull/18#issuecomment-426859615) using [ClassGraph](https://github.com/classgraph/classgraph) used in [INFRAUTILS-52](https://jira.opendaylight.org/browse/INFRAUTILS-52) (and rename it to something more appropriate)
 
 - [ ] read YANG XML configuration files using [DataStoreAppConfigDefaultXMLReader](https://git.opendaylight.org/gerrit/#/c/76416/3/opendaylight/blueprint/src/test/java/org/opendaylight/controller/blueprint/tests/DataStoreAppConfigDefaultXMLReaderTest.java)
 
diff --git a/pom.xml b/pom.xml
index 8f9e75d9203f442846ba38a20202fbd434ca0d18..f005a4170de690c3a45d6053e3d52a8a3d37c179 100644 (file)
--- a/pom.xml
+++ b/pom.xml
     </dependency>
 
     <dependency>
-      <groupId>org.reflections</groupId>
-      <artifactId>reflections</artifactId>
-      <version>0.9.11</version>
+      <groupId>io.github.classgraph</groupId>
+      <artifactId>classgraph</artifactId>
+      <version>4.2.7</version>
     </dependency>
   </dependencies>
 
index 5ef5cf7591f7ac7c330bcafc31f1200d821df5b1..66e0d7079381b0642c6d2c87bb99db033d4e99cc 100644 (file)
@@ -8,6 +8,9 @@
 package org.opendaylight.infrautils.inject;
 
 import com.google.inject.Binder;
+import io.github.classgraph.ClassGraph;
+import io.github.classgraph.ClassInfo;
+import io.github.classgraph.ScanResult;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Constructor;
 import java.util.HashMap;
@@ -16,7 +19,6 @@ import java.util.Map;
 import java.util.Set;
 import javax.inject.Inject;
 import javax.inject.Singleton;
-import org.reflections.Reflections;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -33,7 +35,7 @@ import org.slf4j.LoggerFactory;
 public class ClassPathScanner {
     private static final Logger LOG = LoggerFactory.getLogger(ClassPathScanner.class);
 
-    private final Map<Class, Class> implementations = new HashMap<>();
+    private final Map<String, Class> implementations = new HashMap<>();
 
     /**
      * Create a class path scanner, scanning packages with the given prefix.
@@ -41,15 +43,22 @@ public class ClassPathScanner {
      * @param prefix The package prefix.
      */
     public ClassPathScanner(String prefix) {
-        Reflections reflections = new Reflections(prefix);
-        Set<Class<?>> duplicateInterfaces = new HashSet<>();
-        for (Class<?> singleton : reflections.getTypesAnnotatedWith(Singleton.class)) {
-            for (Class<?> declaredInterface : singleton.getInterfaces()) {
-                if (!duplicateInterfaces.contains(declaredInterface)) {
-                    if (implementations.put(declaredInterface, singleton) != null) {
-                        LOG.debug("{} is declared multiple times, ignoring it", declaredInterface);
-                        implementations.remove(declaredInterface);
-                        duplicateInterfaces.add(declaredInterface);
+        try (ScanResult scanResult =
+                 new ClassGraph()
+                     .enableClassInfo()
+                     .enableAnnotationInfo()
+                     .whitelistPackages(prefix)
+                     .scan()) {
+            Set<String> duplicateInterfaces = new HashSet<>();
+            for (ClassInfo singletonInfo : scanResult.getClassesWithAnnotation(Singleton.class.getName())) {
+                for (ClassInfo interfaceInfo : singletonInfo.getInterfaces()) {
+                    String interfaceName = interfaceInfo.getName();
+                    if (!duplicateInterfaces.contains(interfaceName)) {
+                        if (implementations.put(interfaceName, singletonInfo.loadClass()) != null) {
+                            LOG.debug("{} is declared multiple times, ignoring it", interfaceName);
+                            implementations.remove(interfaceName);
+                            duplicateInterfaces.add(interfaceName);
+                        }
                     }
                 }
             }
@@ -71,7 +80,7 @@ public class ClassPathScanner {
 
     @SuppressWarnings("unchecked")
     private void bindImplementationFor(Binder binder, Class requestedInterface) {
-        Class implementation = implementations.get(requestedInterface);
+        Class implementation = implementations.get(requestedInterface.getName());
         if (implementation != null) {
             binder.bind(requestedInterface).to(implementation);
             for (Constructor constructor : implementation.getDeclaredConstructors()) {