Skip to content

Java get Class names from package String in classpath

As a Java developer you probably used to know about reflexion. However, in order to keep your software architecture flexible, some functionalities are sometimes not provided out of the box by the JVM.
In my particular case, I needed to find out every Class and Sub-Classes inside a package, thus reparteed within several Jars.
Internet has lots of solution, but it remains complicated for everybody to reach this goal. After googleing, I found a link which provided a partial solution. I would like to thank the website author:

http://www.java2s.com/Code/Java/Reflection/Attemptstolistalltheclassesinthespecifiedpackageasdeterminedbythecontextclassloader.htm

Some other solution invited us to deploy external libraries as well. But I was not interested to manage another lib in my soft just for that purpose.
So, the solution was to recover all jars from the context classloader and loop on them in order to find out the classes we are looking for.
Following, you will see a complete Java class resolving this issue:

import java.io.File;

import java.io.IOException;

import java.io.UnsupportedEncodingException;

import java.net.URL;

import java.net.URLClassLoader;

import java.net.URLDecoder;

import java.util.ArrayList;

import java.util.Enumeration;

import java.util.HashMap;

import java.util.List;

import java.util.jar.JarEntry;

import java.util.jar.JarFile;

/**

 *

 *

 *

 * @author Philippe Schweitzer dbi services Switzerland

 *

 */

public class ClassFinder {

    public static void main(String[] args) throws ClassNotFoundException {

        List<Class> classes = ClassFinder.getClassesFromPackage(“YOUR PACKAGE NAME”);

        System.out.println(“START ClassList:”);

        for (Class c : classes) {

            System.out.println(c.toString());// + ” ” + c.getCanonicalName());

        }

        System.out.println(“END ClassList:”);

    }

    /**

     *

     * Attempts to list all the classes in the specified package as determined     *

     * by the context class loader…

     *

     * @param pckgname the package name to search

     * @return a list of classes that exist within that package

     * @throws ClassNotFoundException if something went wrong

     *

     */

    public static List getClassesFromPackage(String pckgname) throws ClassNotFoundException {

        ArrayList result = new ArrayList();

        ArrayList<File> directories = new ArrayList();

        HashMap packageNames = null;

        try {

            for (URL jarURL : ((URLClassLoader) Thread.currentThread().getContextClassLoader()).getURLs()) {

                System.out.println(“JAR: ” + jarURL.getPath());

                getClassesInSamePackageFromJar(result, pckgname, jarURL.getPath());

                String path = pckgname;

                Enumeration<URL> resources = cld.getResources(path);

                File directory = null;

                while (resources.hasMoreElements()) {

                    String path2 = resources.nextElement().getPath();

                    directory = new File(URLDecoder.decode(path2, “UTF-8”));

                    directories.add(directory);

                }

                if (packageNames == null) {

                    packageNames = new HashMap();

                }

                packageNames.put(directory, pckgname);

            }

        } catch (NullPointerException x) {

            throw new ClassNotFoundException(pckgname + ” does not appear to be a valid package (Null pointer exception)”);

        } catch (UnsupportedEncodingException encex) {

            throw new ClassNotFoundException(pckgname + ” does not appear to be a valid package (Unsupported encoding)”);

        } catch (IOException ioex) {

            throw new ClassNotFoundException(“IOException was thrown when trying to get all resources for ” + pckgname);

        }

        for (File directory : directories) {

            if (directory.exists()) {

                String[] files = directory.list();

                for (String file : files) {

                    if (file.endsWith(“.class”)) {

                        try {

                      //      System.out.println(packageNames.get(directory).toString() + ‘.’ + file.substring(0, file.length() – 6));

                            result.add(Class.forName(packageNames.get(directory).toString() + ‘.’ + file.substring(0, file.length() – 6)));

                        } catch (Throwable e) {

                        }

                    }

                }

            } else {

                throw new ClassNotFoundException(pckgname + ” (” + directory.getPath() + “) does not appear to be a valid package”);

            }

        }

        return result;

    }

    /**

     *

     * Returns the list of classes in the same directories as Classes in

     * classes.

     *

     * @param result

     * @param classes

     * @param jarPath

     *

     */

    private static void getClassesInSamePackageFromJar(List result, String packageName, String jarPath) {

        JarFile jarFile = null;

        try {

            jarFile = new JarFile(jarPath);

            Enumeration<JarEntry> en = jarFile.entries();

            while (en.hasMoreElements()) {

                JarEntry entry = en.nextElement();

                String entryName = entry.getName();

                packageName = packageName.replace(‘.’, ‘/’);

                if (entryName != null && entryName.endsWith(“.class”) && entryName.startsWith(packageName)) {

                    try {

                        Class entryClass = Class.forName(entryName.substring(0, entryName.length() – 6).replace(‘/’, ‘.’));

                        if (entryClass != null) {

                            result.add(entryClass);

                        }

                    } catch (Throwable e) {

// do nothing, just continue processing classes

                    }

                }

            }

        } catch (Exception e) {

        } finally {

            try {

                if (jarFile != null) {

                    jarFile.close();

                }

            } catch (Exception e) {

            }

        }

    }

}

Let’s work together

Ready to operate at
the next level?

Tell us about your challenge. We’ll bring the depth, the expertise, and the Swiss precision.

Middleware Team

Middleware Team

Posts published under the Middleware Team account are collective contributions by the dbi services middleware and enterprise content management consultants. The practice covers ECM platforms such as OpenText Documentum, Alfresco, and M-Files, as well as application servers and integration technologies including WebLogic, JBoss, Tomcat, and the Elastic Stack, from architecture and deployment to operations under service level agreements.View Author posts

322 posts since February 2013

Leave a Comment

Your email address will not be published. Required fields are marked *