It took me a little while to figure out that Java doesn't provide a
way to reflect an entire package. In other words, there is no built-in
way for me to dynamically retrieve a list of all the classes in a given
package in Java through reflection. So I wrote my own method to do it.
Since it took a bit of googling and effort, I thought it would be nice to share the convenience method I wrote with the world. Enjoy:
Since it took a bit of googling and effort, I thought it would be nice to share the convenience method I wrote with the world. Enjoy:
Main.java under code.com.pritom package
package code.com.pritom; import java.io.File; import java.net.URL; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashMap; import java.util.List; public class Main { java.lang.reflect.Method method; public static void main(String[] args) throws Exception{ Main main = new Main(); } public Main() throws Exception{ Class loadClass = getClassObjectByName("Load"); System.out.println("Product Type Class: " + loadClass); System.out.println("Product Type Simple Name: " + loadClass.getSimpleName()); System.out.println("Product Type Package Name: " + loadClass.getPackage().getName()); System.out.println("Product Type Is Enum: " + loadClass.isEnum()); try { method = loadClass.getMethod("println", String.class); System.out.println("Method Exists: println(String.class)"); method.invoke(loadClass.newInstance(), "Pritom"); } catch (NoSuchMethodException e) { e.printStackTrace(); } try { Class[] classes = new Class[2]; classes[0] = String.class; classes[1] = Integer.class; method = loadClass.getMethod("println", classes); System.out.println("Method Exists: println(String.class, Integer.class)"); method.invoke(loadClass.newInstance(), "Pritom", 26); } catch (NoSuchMethodException e) { e.printStackTrace(); } } private static HashMap allClassList = new HashMap(); private static HashMap classObjectList = new HashMap(); private static HashMap allClassObjectList = new HashMap(); public static Class getClassObjectByName(String name) throws Exception { if(allClassObjectList.containsKey(name)) { return (Class) allClassObjectList.get(name); } String packageName = "code.com.pritom"; ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); String path = packageName.replace('.', '/'); Enumeration<URL> resources = classLoader.getResources(path); List<File> dirs = new ArrayList<File>(); while (resources.hasMoreElements()) { URL resource = resources.nextElement(); dirs.add(new File(resource.getFile())); } ArrayList<String> classes = new ArrayList<String>(); for (File directory : dirs) { findClasses(directory, packageName); } if(allClassList.containsKey(name)) { Object object = getClassObjectByFullName(allClassList.get(name).toString()); /* Get the object */ allClassObjectList.put(name, object); /* Storing for further use by class name only */ return (Class) object; /* Return object */ } throw new Exception("Invalid entity '" + name + "'"); } private static void findClasses(File directory, String packageName) throws ClassNotFoundException { if (!directory.exists()) { return; } File[] files = directory.listFiles(); for (File file : files) { if (file.isDirectory()) { findClasses(file, packageName + "." + file.getName()); } else if (file.getName().endsWith(".class")) { allClassList.put(file.getName().substring(0, file.getName().length() - 6), packageName + "." + file.getName().substring(0, file.getName().length() - 6)); } } } private static Object getClassObjectByFullName(String fullName) throws Exception { if (classObjectList.containsKey(fullName)) { return classObjectList.get(fullName); } try { ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); Object object = Class.forName(fullName, true, classLoader); classObjectList.put(fullName, object); /* Storing by (package + class) name */ return object; } catch (Exception ex) { throw new Exception(fullName + " does not appear to be a valid class."); } } }
And Load.java under code.com.pritom package
package code.com.pritom; public class Load { public void println(String text) { System.out.println("\tName: " + text); } public void println(String text, Integer age) { System.out.println("\tName: " + text +", Age: " + age); } }
And output will be as follows:
Product Type Class: class code.com.pritom.Load Product Type Simple Name: Load Product Type Package Name: code.com.pritom Product Type Is Enum: false Method Exists: println(String.class) Name: Pritom Method Exists: println(String.class, Integer.class) Name: Pritom, Age: 26