3939import java .util .Map ;
4040import java .util .Map .Entry ;
4141import java .util .Set ;
42-
4342import nonapi .io .github .classgraph .classpath .ClassLoaderOrder ;
4443import nonapi .io .github .classgraph .classpath .ClasspathOrder ;
4544import nonapi .io .github .classgraph .scanspec .ScanSpec ;
@@ -110,7 +109,7 @@ private static void handleResourceLoader(final Object resourceLoader, final Clas
110109
111110 String path = loadJarPathFromClassicVFS (root , classpathOrderOut );
112111 if (!isPathExisting (path )) {
113- path = loadJarPathFromNewVFS (root , classpathOrderOut , classLoader );
112+ path = loadJarPathFromNewVFS (root , classpathOrderOut );
114113 }
115114
116115 if (path == null ) {
@@ -151,13 +150,14 @@ private static boolean isPathExisting(String path) {
151150 * <a href="https://issues.redhat.com/browse/JBEAP-25677">JBEAP-25677</a>
152151 * @param root The root object to get the JAR path from.
153152 * @param classpathOrderOut The ClasspathOrder object for updating the classpath order.
154- * @param classLoader The ClassLoader to use for loading the VFS class. Used as fallback if the current threads classloader
155- * does not have any dependency on jboss.vfs
156153 * @return The absolute path of the JAR file, or null if the path couldn't be found.
157154 */
158- private static String loadJarPathFromNewVFS (final Object root , final ClasspathOrder classpathOrderOut , final ClassLoader classLoader ) {
159- Class <?> jbossVFS = getJBossVFSAccess (classLoader );
160- if (root == null || jbossVFS == null ) return null ;
155+ private static String loadJarPathFromNewVFS (final Object root , final ClasspathOrder classpathOrderOut ) {
156+
157+ if (root == null ) return null ;
158+
159+ Class <?> jbossVFS = getJBossVFSAccess (root );
160+ if (jbossVFS == null ) return null ;
161161
162162 // try to find the mount of the root. Type is org.jboss.vfs.VFS.Mount
163163 Object mount = classpathOrderOut .reflectionUtils .invokeStaticMethod (false , jbossVFS , "getMount" ,
@@ -178,33 +178,45 @@ private static String loadJarPathFromNewVFS(final Object root, final ClasspathOr
178178 }
179179
180180 /**
181- * Get the access to the JBoss VFS class. Tries to load VFS first from the current threads classloader.
182- * If VFS can not be found in there, the provided classloader will be used to load VFS from.
181+ * Get the access to the JBoss VFS class. Tries to load VFS first from the classloader of the provided root object
182+ * if it's an object from org.jboss.vfs.
183+ * If the root object is not from org.jboss.vfs, VFS will be tried to be loaded from the current thread class loader.
184+ * It might be unnecessary to load VFS from the current thread context, because this means that the root object
185+ * is not from org.jboss.vfs and VFS will not help here... but as a defensive approach we really try to get VFS
186+ * access here.
183187 *
184- * @param classLoader The ClassLoader to use for loading the JBoss VFS class .
188+ * @param root The root VirtualFile of JBoss VFS. Used to load the VFS via the classloader of the root. Can not be null .
185189 * @return The Class object representing the JBoss VFS class, or null if it couldn't be found.
186190 */
187- private static Class <?> getJBossVFSAccess (ClassLoader classLoader ) {
191+ private static Class <?> getJBossVFSAccess ( final Object root ) {
188192 Class <?> jbossVFS = null ;
189193 // we need access to the class 'VFS' of org.jboss.vfs
190194 try {
191- // try to load JBoss VFS access from the current threads classloader
192- ClassLoader currentThreadClassLoarder = Thread .currentThread ().getContextClassLoader ();
193- jbossVFS = Class .forName ("org.jboss.vfs.VFS" , true , currentThreadClassLoarder );
194- } catch (ClassNotFoundException ex ) {
195- // if the classloader before could not provide the VFS, try it in the provided class loader
196- // NOTE: maybe we can skip this, org.jboss.vfs is less likely to be in every class loader present.
197- // It's easier to ensure that it is in the current threads classloader where classgraph is called from?
195+ if (root .getClass ().getName ().contains ("org.jboss.vfs" )) {
196+ // first, try the classloader of the root object. Since the root object comes from org.jboss.vfs,
197+ // it is likely that we can get access to org.jboss.vfs.VFS from this classloader
198+ ClassLoader vfsRootClassloader = root .getClass ().getClassLoader ();
199+ jbossVFS = loadJBossVFS (vfsRootClassloader );
200+ }else {
201+ // for non org.jboss.vfs objects, use the currentThread
202+ jbossVFS = loadJBossVFS (Thread .currentThread ().getContextClassLoader ());
203+ }
204+ } catch (ClassNotFoundException e ) {
198205 try {
199- jbossVFS = Class .forName ("org.jboss.vfs.VFS" , true , classLoader );
200- } catch (ClassNotFoundException e ) {
206+ // try to load JBoss VFS access from the current threads classloader since the previous method failed
207+ // if the previous method was already the currentThreads classloader, it will fail again...
208+ jbossVFS = loadJBossVFS (Thread .currentThread ().getContextClassLoader ());
209+ } catch (ClassNotFoundException e1 ) {
201210 // swallow the exception. If there is no VFS present, we can't do anything...
202- e .printStackTrace ();
203211 }
204212 }
205213 return jbossVFS ;
206214 }
207215
216+ private static Class <?> loadJBossVFS (ClassLoader classLoader ) throws ClassNotFoundException {
217+ return Class .forName ("org.jboss.vfs.VFS" , true , classLoader );
218+ }
219+
208220 /**
209221 * Returns the absolute path of a JAR file from a given root object using the 'classic' VFS read mechanism.
210222 * This works for Versions of JBoss/Wildfly prior to this change:
@@ -216,11 +228,10 @@ private static Class<?> getJBossVFSAccess(ClassLoader classLoader) {
216228 * @return The absolute path of the JAR file, or null if the path couldn't be found.
217229 */
218230 private static String loadJarPathFromClassicVFS (final Object root , final ClasspathOrder classpathOrderOut ) {
219-
231+ String path = null ;
220232 // type VirtualFile
221233 final File physicalFile = (File ) classpathOrderOut .reflectionUtils .invokeMethod (false , root ,
222234 "getPhysicalFile" );
223- String path = null ;
224235 if (physicalFile != null ) {
225236 final String name = (String ) classpathOrderOut .reflectionUtils .invokeMethod (false , root , "getName" );
226237 if (name != null ) {
@@ -246,6 +257,7 @@ private static String loadJarPathFromClassicVFS(final Object root, final Classpa
246257 }
247258 }
248259 }
260+
249261 return path ;
250262 }
251263
0 commit comments