Get All of the Classes in the Classpath

Get all of the Classes in the Classpath

You can get all classpath roots by passing an empty String into ClassLoader#getResources().

Enumeration<URL> roots = classLoader.getResources("");

You can construct a File based on URL as follows:

File root = new File(url.getPath());

You can use File#listFiles() to get a list of all files in the given directory:

for (File file : root.listFiles()) {
// ...
}

You can use the standard java.io.File methods to check if it's a directory and/or to grab the filename.

if (file.isDirectory()) {
// Loop through its listFiles() recursively.
} else {
String name = file.getName();
// Check if it's a .class file or a .jar file and handle accordingly.
}

Depending on the sole functional requirement, I guess that the Reflections library is much more exactly what you want.

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

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;
}

How can i do to get all class of a given package with guava

I found tow solutions :

With guava :

public void getClassOfPackage(String packagenom) {

final ClassLoader loader = Thread.currentThread()
.getContextClassLoader();
try {

ClassPath classpath = ClassPath.from(loader); // scans the class path used by classloader
for (ClassPath.ClassInfo classInfo : classpath.getTopLevelClasses(packagenom)) {
if(!classInfo.getSimpleName().endsWith("_")){
System.out.println(classInfo.getSimpleName());
}
}
} catch (IOException e) {
e.printStackTrace();
}

}

public static void main(String[] args) {
new TestMain().getClassOfPackage("org.myproject");
}

With Java.util:

    public List<Class> getClassOfPackage(String packageName)
throws ClassNotFoundException, IOException {

ClassLoader classLoader = Thread.currentThread()
.getContextClassLoader();

assert classLoader != null;
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<Class> classes = new ArrayList<Class>();
for (File directory : dirs) {
classes.addAll(findClasses(directory, packageName));
}
return classes;
}

private static List<Class> findClasses(File directory, String packageName)
throws ClassNotFoundException {
List<Class> classes = new ArrayList<Class>();
if (!directory.exists()) {
return classes;
}
File[] files = directory.listFiles();
for (File file : files) {
if (file.isDirectory()) {
assert !file.getName().contains(".");
classes.addAll(findClasses(file,
packageName + "." + file.getName()));
} else if (file.getName().endsWith(".class")) {
classes.add(Class.forName(packageName
+ '.'
+ file.getName().substring(0,
file.getName().length() - 6)));
}
}
return classes;
}

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

for (Class className : new ClassOfPackage()
.getClassOfPackage("org.mypackage")) {
if (!className.getSimpleName().endsWith("_")) {
System.out.println(className.getSimpleName());
}

}

}

How can I find all classes on the classpath that have a specific method annotation?

You could use Reflections, which is a Java runtime metadata analysis tool. I've used it to get all subtypes of a given type, but it can handle your case as well.

Java : loop on all the classes in the classpath

The Reflections library helps deal with this problem. As others have stated, it isn't fully possible in all class loading situations, but if all you have are jars and files, this will do it reliably.

Load all classes in all JARs to classpath

The java documentation states

-jar

Executes a program encapsulated in a JAR file. The first argument is the name of a JAR file instead of a startup class name. For this option to work, the manifest of the JAR file must contain a line in the form Main-Class: classname. Here, classname identifies the class with the public static void main(String[] args) method that serves as your application's starting point.

When you use this option, the JAR file is the source of all user classes, and other user class path settings are ignored`.

One workaround is to append MyTest.jar to the classpath (-cp) and specify the main class in the MyTest.jar as argument to java

java -cp Mytest.jar;E:\libs\* me.darksidecode.KekGUI

How do I get a list of packages and/or classes on the classpath?

Its a bit tricky and there are a few libraries that can help, but basically...

  1. Look at your classpath
  2. If you are dealing with a directory, you can look for all files ending in .class
  3. If you are dealing with a jar, load the jar up and look for all files ending in .class
  4. Remove the .class from the end of the file, replace the "\" with "." and then you have the fully qualified classname.

If you have spring in your classpath, you can take advantage of them doing most of this already:

ArrayList<String> retval = new ArrayList<Class<?>>();
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
MetadataReaderFactory readerFactory = new CachingMetadataReaderFactory(resolver);
String basePath = ClassUtils.convertClassNameToResourcePath("com.mypackage.to.search");
Resource[] resources;
try {
resources = resolver.getResources("classpath*:" + basePath + "/**/*.class");
} catch (IOException e) {
throw new AssertionError(e);
}
for (Resource resource : resources) {
MetadataReader reader;
try {
reader = readerFactory.getMetadataReader(resource);
} catch (IOException e) {
throw new AssertionError(e);
}
String className = reader.getClassMetadata().getClassName();
retval.add(className)
}
return retval;


Related Topics



Leave a reply



Submit