This is an automated email from the ASF dual-hosted git repository.

nvazquez pushed a commit to branch 4.22
in repository https://gitbox.apache.org/repos/asf/cloudstack.git


The following commit(s) were added to refs/heads/4.22 by this push:
     new d4f5dff7311 Fix overly broad classpath scanning in 
ReflectUtil.getClassesWithAnnotation() (#13427)
d4f5dff7311 is described below

commit d4f5dff7311bdb6a7fb6174b8eddb705a8e0eac5
Author: Vishesh <[email protected]>
AuthorDate: Wed Oct 7 00:41:44 2026 +0530

    Fix overly broad classpath scanning in 
ReflectUtil.getClassesWithAnnotation() (#13427)
    
    * Fix overly broad classpath scanning in 
ReflectUtil.getClassesWithAnnotation()
    
    Production logs show a recurring WARN at startup:
      "could not get type for name org.conscrypt.AllocatedBuffer"
      (org.reflections.ReflectionsException / ClassNotFoundException)
    
    Root cause: ReflectUtil.getClassesWithAnnotation() uses
    ClasspathHelper.forPackage() to collect URLs to scan, but this
    returns all classpath entries (JARs/directories), not just those
    containing the target package. The Reflections library then scans
    every .class file in every JAR — including Netty's
    ConscryptAlpnSslEngine$BufferAdapter which references the optional
    org.conscrypt.AllocatedBuffer type. During expandSuperTypes(),
    Reflections tries Class.forName() on that type and fails because
    Conscrypt is not (and need not be) on the classpath.
    
    The fix adds a FilterBuilder that restricts bytecode scanning to
    only classes whose fully-qualified names match the requested
    packages. This prevents Reflections from processing unrelated
    classes (e.g., io.netty.handler.ssl.*), eliminating the warning
    and reducing startup time by skipping thousands of irrelevant
    class files.
    
    Signed-off-by: Ganesh Maharaj Mahalingam <[email protected]>
    
    * Add missing API command packages to ApiXmlDocWriter's classpath scan list
    
    ---------
    
    Signed-off-by: Ganesh Maharaj Mahalingam <[email protected]>
    Co-authored-by: Ganesh Maharaj Mahalingam <[email protected]>
---
 server/src/main/java/com/cloud/api/doc/ApiXmlDocWriter.java | 5 ++++-
 utils/src/main/java/com/cloud/utils/ReflectUtil.java        | 4 ++++
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/server/src/main/java/com/cloud/api/doc/ApiXmlDocWriter.java 
b/server/src/main/java/com/cloud/api/doc/ApiXmlDocWriter.java
index b1bb316471b..0495a41e36a 100644
--- a/server/src/main/java/com/cloud/api/doc/ApiXmlDocWriter.java
+++ b/server/src/main/java/com/cloud/api/doc/ApiXmlDocWriter.java
@@ -92,7 +92,10 @@ public class ApiXmlDocWriter {
     public static void main(String[] args) {
         Set<Class<?>> cmdClasses = 
ReflectUtil.getClassesWithAnnotation(APICommand.class, new String[] 
{"org.apache.cloudstack.api", "com.cloud.api",
                 "com.cloud.api.commands", "com.globo.globodns.cloudstack.api", 
"org.apache.cloudstack.network.opendaylight.api",
-                "org.apache.cloudstack.api.command.admin.zone", 
"org.apache.cloudstack.network.contrail.api.command"});
+                "org.apache.cloudstack.api.command.admin.zone", 
"org.apache.cloudstack.network.contrail.api.command",
+                "org.apache.cloudstack.cloudian.api", 
"org.apache.cloudstack.framework.extensions.api",
+                "org.apache.cloudstack.mom.webhook.api.command.user", 
"org.apache.cloudstack.network.tungsten.api.command",
+                "org.apache.cloudstack.oauth2.api.command", 
"org.apache.cloudstack.storage.datastore.util"});
 
         for (Class<?> cmdClass : cmdClasses) {
             if(cmdClass.getAnnotation(APICommand.class)==null){
diff --git a/utils/src/main/java/com/cloud/utils/ReflectUtil.java 
b/utils/src/main/java/com/cloud/utils/ReflectUtil.java
index 5b40d48c20e..bf11cea22cc 100644
--- a/utils/src/main/java/com/cloud/utils/ReflectUtil.java
+++ b/utils/src/main/java/com/cloud/utils/ReflectUtil.java
@@ -42,6 +42,7 @@ import org.reflections.scanners.SubTypesScanner;
 import org.reflections.scanners.TypeAnnotationsScanner;
 import org.reflections.util.ClasspathHelper;
 import org.reflections.util.ConfigurationBuilder;
+import org.reflections.util.FilterBuilder;
 
 import com.cloud.utils.exception.CloudRuntimeException;
 import com.google.common.collect.ImmutableSet;
@@ -70,9 +71,12 @@ public class ReflectUtil {
         Reflections reflections;
         Set<Class<?>> classes = new HashSet<Class<?>>();
         ConfigurationBuilder builder=new ConfigurationBuilder();
+        FilterBuilder filterBuilder = new FilterBuilder();
         for (String packageName : packageNames) {
              builder.addUrls(ClasspathHelper.forPackage(packageName));
+             filterBuilder.includePackage(packageName);
         }
+        builder.filterInputsBy(filterBuilder);
         builder.setScanners(new SubTypesScanner(),new 
TypeAnnotationsScanner());
         reflections = new Reflections(builder);
         classes.addAll(reflections.getTypesAnnotatedWith(annotation));

Reply via email to