简体   繁体   中英

Obtaining all the methods in a class — error prone

I am new to reflection and to practice, I downloaded a random Java project from a website. I decided to find out which class has the main method so I wrote the following code:

package reflection;
import java.io.IOException;
import java.lang.reflect.*;
import java.nio.file.*;

public class FindMethods {
    public static void main(String[] args) throws IOException{
        if(args.length==0){
            System.out.println("Exiting");
            System.exit(1);
        }else{
            Path p = Paths.get(args[0]);
            DirectoryStream<Path> allClassFiles = Files.newDirectoryStream(p, "*.class");
            for(Path each : allClassFiles){
//              System.out.println(each.getFileName());
                try {
                    findMethods(each.getFileName().toString());
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void findMethods(String file) throws ClassNotFoundException{
        System.out.println(file);
        Class c = Class.forName(file);
        Method[] m = c.getDeclaredMethods();
        for(Method each : m){
            System.out.println(each.toString());
        }
    }
}  

System.out.println(each.getFileName()); properly returns the .class files in the folder however, it is interspersed with stack trace of ClassNotFoundException

The classes are as follows:

Addwindow$1.class
Addwindow$2.class
Addwindow.class
Authorwindow.class
clsConnection.class
clsSettings$1.class
clsSettings.class
Deletewindow$1.class
Deletewindow$2.class
Deletewindow.class
Editwindow$1.class
Editwindow$2.class
Editwindow.class
Emprptwindow$PrintCommand.class
Emprptwindow.class
Helpwindow.class
LoginFrame$1.class
LoginFrame.class
MainMenu$1.class
MainMenu$2.class
MainMenu.class
Payrptwindow.class
printwindow$1.class
printwindow.class
Settingswindow$1.class
Settingswindow.class  

What changes do I need to make to the code to get the methods from each class ?

Stack trace:

java.lang.ClassNotFoundException: Settingswindow
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Unknown Source)
    at reflection.FindMethods.findMethods(FindMethods.java:33)
    at reflection.FindMethods.main(FindMethods.java:22)  

Random project being talked about:

http://projectseminar.org/java-projects/payroll-accounting-system/98/

.class is part of the filename, but it isn't part of the class name. You need to strip it before passing it to Class.forName .

Another issue is that forName expects packages to be separated using periods, rather than than slashes or whatever directory separator your filesystem uses. If everything is in the default package, this shouldn't be an issue though.

If it's still not working, you should double check the classpath.

Class names that contain a $ are anonymous classes within the outer class (determined by the name to the left of the $ ). You can safely ignore those in your search for main . Just test for the presence of a $ in the class names in your main loop and skip the processing.

Without knowing more about what app you are looking at, I can't say why your code can't find some of the other classes (like clsConnection ).

There is a problem in this approach - you load all project's classes. It is better to analize classes without loading them. There are tools for that. Here's what we can do with http://www.jboss.org/javassist

public static void findMethods(String file) throws Exception {
    ClassPool cp = ClassPool.getDefault();
    try (InputStream is = new FileInputStream(file)) {
        CtClass cc = cp.makeClass(is);
        for (CtMethod m : cc.getMethods()) {
            System.out.println(m);
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM