Skip to content

Commit c419fd5

Browse files
authored
adjustments in getting access to org.jboss.vfs.VFS (#843)
1 parent 23f02de commit c419fd5

File tree

1 file changed

+35
-23
lines changed

1 file changed

+35
-23
lines changed

src/main/java/nonapi/io/github/classgraph/classloaderhandler/JBossClassLoaderHandler.java

Lines changed: 35 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@
3939
import java.util.Map;
4040
import java.util.Map.Entry;
4141
import java.util.Set;
42-
4342
import nonapi.io.github.classgraph.classpath.ClassLoaderOrder;
4443
import nonapi.io.github.classgraph.classpath.ClasspathOrder;
4544
import 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

Comments
 (0)