klsince commented on code in PR #9167:
URL: https://github.com/apache/pinot/pull/9167#discussion_r938337422


##########
pinot-spi/src/main/java/org/apache/pinot/spi/utils/PinotReflectionUtils.java:
##########
@@ -19,36 +19,95 @@
 package org.apache.pinot.spi.utils;
 
 import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Set;
 import org.reflections.Reflections;
+import org.reflections.scanners.MethodAnnotationsScanner;
 import org.reflections.scanners.TypeAnnotationsScanner;
 import org.reflections.util.ClasspathHelper;
 import org.reflections.util.ConfigurationBuilder;
 import org.reflections.util.FilterBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 
 public class PinotReflectionUtils {
   private PinotReflectionUtils() {
   }
 
-  private static final String PINOT_PACKAGE_PREFIX = "org.apache.pinot";
+  private static final Logger LOGGER = 
LoggerFactory.getLogger(PinotReflectionUtils.class);
+  private static final String PINOT_PACKAGE_NAME = "org.apache.pinot";
   private static final Object REFLECTION_LOCK = new Object();
 
-  public static Set<Class<?>> getClassesThroughReflection(final String 
regexPattern,
-      final Class<? extends Annotation> annotation) {
-    synchronized (getReflectionLock()) {
-      Reflections reflections = new Reflections(
-          new 
ConfigurationBuilder().setUrls(ClasspathHelper.forPackage(PINOT_PACKAGE_PREFIX))
-              .filterInputsBy(new 
FilterBuilder.Include(regexPattern)).setScanners(new TypeAnnotationsScanner()));
-      return reflections.getTypesAnnotatedWith(annotation, true);
+  public static Set<Class<?>> getClassesThroughReflection(String regexPattern, 
Class<? extends Annotation> annotation) {
+    return getClassesThroughReflection(PINOT_PACKAGE_NAME, regexPattern, 
annotation);
+  }
+
+  public static Set<Class<?>> getClassesThroughReflection(String packageName, 
String regexPattern,
+      Class<? extends Annotation> annotation) {
+    try {
+      synchronized (REFLECTION_LOCK) {
+        return new Reflections(new 
ConfigurationBuilder().setUrls(ClasspathHelper.forPackage(packageName))
+            .filterInputsBy(new FilterBuilder.Include(regexPattern))
+            .setScanners(new 
TypeAnnotationsScanner())).getTypesAnnotatedWith(annotation);
+      }
+    } catch (Throwable t) {
+      // Log an error then re-throw it because this method is usually called 
in a static block, where exception might
+      // not be properly handled
+      LOGGER.error("Error scanning classes within package: {} with regex 
pattern: {}, annotation: {}", packageName,
+          regexPattern, annotation, t);
+      throw t;
+    }
+  }
+
+  public static Set<Class<?>> getClassesThroughReflection(List<String> 
packages, String regexPattern,
+      Class<? extends Annotation> annotation) {
+    try {
+      synchronized (REFLECTION_LOCK) {
+        List<URL> urls = new ArrayList<>();
+        for (String packageName : packages) {
+          urls.addAll(ClasspathHelper.forPackage(packageName));
+        }
+        return new Reflections(
+            new ConfigurationBuilder().setUrls(urls).filterInputsBy(new 
FilterBuilder.Include(regexPattern))
+                .setScanners(new 
TypeAnnotationsScanner())).getTypesAnnotatedWith(annotation);
+      }
+    } catch (Throwable t) {
+      // Log an error then re-throw it because this method is usually called 
in a static block, where exception might
+      // not be properly handled
+      LOGGER.error("Error scanning classes within packages: {} with regex 
pattern: {}, annotation: {}", packages,
+          regexPattern, annotation, t);
+      throw t;
+    }
+  }
+
+  public static Set<Method> getMethodsThroughReflection(String regexPattern, 
Class<? extends Annotation> annotation) {
+    return getMethodsThroughReflection(PINOT_PACKAGE_NAME, regexPattern, 
annotation);
+  }
+
+  public static Set<Method> getMethodsThroughReflection(String packageName, 
String regexPattern,
+      Class<? extends Annotation> annotation) {
+    try {
+      synchronized (REFLECTION_LOCK) {
+        return new Reflections(new 
ConfigurationBuilder().setUrls(ClasspathHelper.forPackage(packageName))
+            .filterInputsBy(new FilterBuilder.Include(regexPattern))
+            .setScanners(new 
MethodAnnotationsScanner())).getMethodsAnnotatedWith(annotation);
+      }
+    } catch (Throwable t) {
+      // Log an error then re-throw it because this method is usually called 
in a static block, where exception might
+      // not be properly handled
+      LOGGER.error("Error scanning methods within package: {} with regex 
pattern: {}, annotation: {}", packageName,
+          regexPattern, annotation, t);
+      throw t;
     }
   }
 
   /**
    * Due to the multi-threading issue in org.reflections.vfs.ZipDir, we need 
to put a lock before calling the
    * reflection related methods.
-   *
-   * @return
    */
   public static Object getReflectionLock() {

Review Comment:
   nit: instead of return lock, may do 
   ```
   runWithLock(Runnable r) {
    sync(lock) {
     r.run()
    }
   }
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscr...@pinot.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@pinot.apache.org
For additional commands, e-mail: commits-h...@pinot.apache.org

Reply via email to