0

My Question:

Is it possible to get a Uri from an import of a third party dependency?

Question Context:

I am trying to get a list of classes accessed with the following.
import com.name.*

In the context in which I want to use it, I will not be able to use third party dependencies. I do however need to find all classes associated with a third party dependency import.

I have found one such answer to my issue in the following code, provided by the user tirz.

public static List<Class<?>> getClassesForPackage(final String pkgName) throws IOException, URISyntaxException {
    final String pkgPath = pkgName.replace('.', '/');
    final URI pkg = Objects.requireNonNull(ClassLoader.getSystemClassLoader().getResource(pkgPath)).toURI();
    final ArrayList<Class<?>> allClasses = new ArrayList<Class<?>>();

    Path root;
    if (pkg.toString().startsWith("jar:")) {
        try {
            root = FileSystems.getFileSystem(pkg).getPath(pkgPath);
        } catch (final FileSystemNotFoundException e) {
            root = FileSystems.newFileSystem(pkg, Collections.emptyMap()).getPath(pkgPath);
        }
    } else {
        root = Paths.get(pkg);
    }

    final String extension = ".class";
    try (final Stream<Path> allPaths = Files.walk(root)) {
        allPaths.filter(Files::isRegularFile).forEach(file -> {
            try {
                final String path = file.toString().replace('/', '.');
                final String name = path.substring(path.indexOf(pkgName), path.length() - extension.length());
                allClasses.add(Class.forName(name));
            } catch (final ClassNotFoundException | StringIndexOutOfBoundsException ignored) {
            }
        });
    }
    return allClasses;
}

The problem I have with the code above is that where final URI pkg is assigned. This works with a package that exists within the project, but if an import for a third party dependency is used this throws a NullPointerException. Is it possible to make this code work for third party dependencies? Might this require some reference to an .m2 folder or other library resource?

Jack J
  • 1,514
  • 3
  • 20
  • 28
  • What are you actually trying to achieve? – tgdavies Feb 22 '22 at 00:17
  • Perhaps if I get a Uri for a dependency, I can loop through the package indicated by the import statement. That would allow me to find all classes in a particular package. – Jack J Feb 22 '22 at 00:21
  • 2
    Two possibilities 1) these third party classes are not loaded by the system class loader or 2) these classes are shipped with a file format (like jar) without directory entries, so `getResource` does not find a matching entry. It’s always safer to use a class for the lookup, preferably a `Class` object which allows to identify the right class loader as well. By the way, not every resource is a class file, so you should filter the entries to only process resources ending with `.class`. Then, you don’t need to catch `StringIndexOutOfBoundsException`. – Holger Feb 22 '22 at 09:25

0 Answers0