问题
Suppose I have two packages(package1,package2) with one class in each package(package1.A, package2.B). I need to identify references from package1.A to package2.B and vice versa using a java program, and also references to any methods in each class as well.
The code would be something like this:
package package1;
public class A{
public A(){
Class<?> clazz = Class.forName("package2.B");
Method mthd = clazz.getMethod("someMethod", Integer.TYPE);
}
public static void main(String[] args) {
new A();
}
Class B goes like this:
package package2;
public class B {
public B someMethod(int someParam) {
return null;
}
}
I just need a few pointers on how I should get started in using parsers for this problem. What kind of rules must I keep in mind? The goal of my problem is to identify dependency.
回答1:
I was not going to post this because it's not great, but since it has been a couple days and you have not had a lot of response, here is a different sort of answer based on your comment:
I'm trying to find dependencies between the two classes and their various methods.
If you only need to find dependencies and calls within your own application (Not external libraries) then read on.
Consider injecting a line or two of code into every method (Easily done by a script at compile time?), and have this information logged. For example, you can use variations of object.getClass().???
to find info about the current method including its package, class, and method name.
For example this one just outputs info directly to console:
StackTraceElement[] ste = Thread.currentThread().getStackTrace();
System.out.println("Called by: "+ste[ste.length - 2].getMethodName());
Object object = new Object(){};
System.out.println("Method details: "+ object.getClass().getPackage().getName() +" - "+ object.getClass().getName() +" - "+ object.getClass().getEnclosingMethod().getName());
For every method that these lines are inserted into it will spit out something like this on the console every time it is called:
Called by: source
Method details: myPackage - myClass$1 - myMethod
Some real results from a quick test on one of my applications by throwing the above into several classes:
Called by: getStackTrace
Method details: testdump - testdump.TestDump$1 - main
Called by: pumpEvents
Method details: testdump - testdump.Rect$1 - paintComponent
Called by: checkFileSize
Method details: update - update.FTP$2 - checkFileSize
Called by: checkFileSize
Method details: update - update.FTP$1 - download
Called by: pumpEvents
Method details: testdump - testdump.Rect$1 - paintComponent
...
We can very easily see exactly the two different packages that were called, and we can generally see where it was called from, although you will need to play around with ste[ste.length - 2].getMethodName()
to return different lines depending on how far back on the stack trace that you want to see. Obviously, this should be used in debug mode only, and it will generate a lot of junk, but depending on the size of your application it should be a simple matter of inspecting the output results, either manually or by making a short program that builds a tree of dependencies for you to inspect.
Alternatively, you may be able to use the Java 9 stack walking API in a similar way: https://stackoverflow.com/a/45812871/1270000
来源:https://stackoverflow.com/questions/51830669/how-can-i-identify-declarations-and-references-to-external-classes-and-methods-w