Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I get all Class files in a specific package in Java?

As the description says: how to get a list of all Java class files for a given package name.

like image 915
mythbu Avatar asked Feb 23 '15 16:02

mythbu


2 Answers

I've seen many questions and ways here on SO and other sites to find all classes in a specific Java package. Most of the solutions didn't work for me. Sometimes they worked on Jar files but not on "plain" Java projects in a folder (like the way an IDE does it) or the other way around. So I put all those code snippets together and formed a solution which will work (for me) out of the box regardless if the code is inside a Jar file or in a plain folder structure.

It's really simple: you give the method getClassesInPackage the name of the package to inspect and you will get a list of all classes in this package. Currently no exception is "consumed" orderly.

Have fun with it! Here is the code:

public static final List<Class<?>> getClassesInPackage(String packageName) {
    String path = packageName.replaceAll("\\.", File.separator);
    List<Class<?>> classes = new ArrayList<>();
    String[] classPathEntries = System.getProperty("java.class.path").split(
            System.getProperty("path.separator")
    );

    String name;
    for (String classpathEntry : classPathEntries) {
        if (classpathEntry.endsWith(".jar")) {
            File jar = new File(classpathEntry);
            try {
                JarInputStream is = new JarInputStream(new FileInputStream(jar));
                JarEntry entry;
                while((entry = is.getNextJarEntry()) != null) {
                    name = entry.getName();
                    if (name.endsWith(".class")) {
                        if (name.contains(path) && name.endsWith(".class")) {
                            String classPath = name.substring(0, entry.getName().length() - 6);
                            classPath = classPath.replaceAll("[\\|/]", ".");
                            classes.add(Class.forName(classPath));
                        }
                    }
                }
            } catch (Exception ex) {
                // Silence is gold
            }
        } else {
            try {
                File base = new File(classpathEntry + File.separatorChar + path);
                for (File file : base.listFiles()) {
                    name = file.getName();
                    if (name.endsWith(".class")) {
                        name = name.substring(0, name.length() - 6);
                        classes.add(Class.forName(packageName + "." + name));
                    }
                }
            } catch (Exception ex) {
                // Silence is gold
            }
        }
    }

    return classes;
}
like image 186
mythbu Avatar answered Oct 11 '22 21:10

mythbu


Here is @mythbu 's answer in Kotlin:

@Throws(Exception::class)
fun getClassesInPackage(packageName: String) = with(packageName.replace(".", File.separator)) {
    System.getProperty("java.class.path")
        .split(System.getProperty("path.separator").toRegex())
        .flatMap { classpathEntry ->
            if (classpathEntry.endsWith(".jar")) {
                JarInputStream(FileInputStream(File(classpathEntry))).use { s ->
                    generateSequence { s.nextJarEntry }
                            .map { it.name }
                            .filter { this in it && it.endsWith(".class") }
                            .map { it.substring(0, it.length - 6) }
                            .map { it.replace('|', '.').replace('/', '.') }
                            .map { Class.forName(it) }
                            .toList()
                }
            } else {
                File(classpathEntry, this).list()
                        ?.asSequence()
                        ?.filter { it.endsWith(".class") }
                        ?.map { it.substring(0, it.length - 6) }
                        ?.map { Class.forName("$packageName.$it") }
                        ?.toList() ?: emptyList()
            }
        }
}
like image 40
Alex Semeniuk Avatar answered Oct 11 '22 22:10

Alex Semeniuk