question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

What is the correct way to scan classes in other jars?

See original GitHub issue

I have a project into which i shaded classgraph-4.8.150, JDK version 16.

The project comes with this method to find certain classes:

public static @NotNull List<Class<? extends CustomItem>> findCustomItemClasses(final @NotNull ClassLoader classLoader, final @NotNull String rootPackagePath) {

    final List<Class<? extends CustomItem>> customItemClasses = new ArrayList<>();

    try (final ScanResult scanResult = new ClassGraph()
            .acceptPackages(rootPackagePath)
            .scan()
    ) {
        for (final ClassInfo classInfo : scanResult.getAllClasses()) {

            final Class<?> clazz;
            try {
                clazz = classLoader.loadClass(classInfo.getName());
            } catch (ClassNotFoundException ignore) {
                continue;
            }

            if (CustomItem.class.equals(clazz)
                    || !CustomItem.class.isAssignableFrom(clazz)
                    || !clazz.isAnnotationPresent(CustomItemIdentifier.class)) {
                continue;
            }

            //noinspection unchecked
            customItemClasses.add((Class<? extends CustomItem>) clazz);
        }
    }

    return customItemClasses;
}

(Note: of course i used debug souts to check if any classes were found at all, even before the filter conditions)

The problem is that this method will only find results within in its native project (in that instance “de.jaylawl.commonljb”). If i am calling this method with any other package path, there are no results.

I have tried many different configurations for ClassGraph instantiation, but it never works.

But it used to work before, when i was using a prior version of classgraph. I think it was somewhere around 4.8.~50, when #whitelistPackages was not deprecated yet.

What am i doing wrong? I’ve been reading through the documentation but i can’t find any examples for what i’m supposed to do for my use case (iterate classes in external jars).

Issue Analytics

  • State:closed
  • Created 10 months ago
  • Comments:15 (8 by maintainers)

github_iconTop GitHub Comments

1reaction
lukehutchcommented, Nov 15, 2022

ClassGraph obtains classpath elements from classloaders, and then scans them manually. Here you can see that org.bukkit.plugin.java.PluginClassLoader reported only one jar, CommonLjb.jar. Since PluginClassLoader extends URLClassLoader, ClassGraph just uses the standard URLClassLoader API to get the classpath, which contains just that one element.

However, it’s possible that this classloader has a different field or method for getting the full set of plugin paths. You will have to find a reference to this classloader in your runtime environment, and then use a debugger to see where inside this classloader the other plugins are stored.

I don’t know how to set up bukkit etc., so I can’t really help you debug this, but a debugger should help you figure it out. You may need to look at other classloaders too.

Once you figure out where the plugin paths are stored, then we can figure out why ClassPath doesn’t detect them.

0reactions
lukehutchcommented, Nov 18, 2022

OK, thanks. Well the output of toString() doesn’t contain an address for the object instance for these two PluginClassLoader instances, so actually I can’t tell from the output if these are the same instance, but they probably are, since url points to the same jar.

Your original log showed that ClassGraph did in fact find one PluginClassLoader. I just can’t understand why it only found one jar, whereas if you manually add the PluginClassLoader, it finds many more jars.

I’m not really sure what else I can suggest unless you want to produce a small reproducer project. Otherwise, at least you have a solution for your purposes. Thanks!

Read more comments on GitHub >

github_iconTop Results From Across the Web

JarScan, scan all JAR files in all subfolders for specific class
It pops open a GUI window with two panels. You can pick a directory, the tool will scan all the JAR files in...
Read more >
Scanning jar and classes for annotations - JBoss.org
Hi, I've made some annotations I use for configuration, to find the annotation I used the project Scannotation, the only problem I had...
Read more >
Spring Component Scanning - Baeldung
In this tutorial, we'll cover component scanning in Spring. When working with Spring, we can annotate our classes in order to make them...
Read more >
The jdeprscan Command - Oracle Help Center
To scan a JAR file or a set of class files, you must first ensure that all of the classes that the scanned...
Read more >
Component Scanning with Spring Boot - Reflectoring
The process of searching the classpath for classes that should contribute to the application context is called component scanning. Stereotype ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found