简体   繁体   中英

Get all classes referenced by a class

Let's say I have a java.lang.Class instance, c at runtime.

At runtime, is there anyway to see what classes are used by c? eg if c.foo instantiates a B, B is being 'used'. if c.foo calls static method G.bar(), G is being used.

Note: Only trying to get what classes could be known statically - I'm fine missing ones loaded by reflection.

In python, equivalent functionality is found in modulefinder: http://docs.python.org/library/modulefinder.html

Everything that happens outside of method bodies, constructors and static initilizers can be queried with reflection. You can look at field and method signatures and reflect the fields to get the actual classes of field values.

Classes used inside methods are quite a challenge. You could use BCEL or a similiar tool to analyse the class file and extract all classnames that are hardcoded in the class file. But this will fail as soon as you program against interfaces:

public List someMethod() {
  return SomeClass.getList();
}

The type of the class returned by someMethod is not known by the class file. And there ist no lookup table or central registry. The JVM will know the type, look if the class is already loaded and - if not - try to load it. It doesn't have to care about which class asked for that other class and it will not record this information. Just because it is not needed for exectution and not needed for garbage collection.

IMHO, it is impossible because other referenced classes may be instantiated using reflection. Or they can be injected using dependency injection mechanism.

您可以尝试这个Java Dependency Resolver 项目,它不仅可以找到项目中特定类的引用类和 jar。

某些类可以动态加载,使用getLoadedClasses()

看看Maven Dependency Analyzer和它的类ASMDependencyAnalyzer

Set<String> referencedClasses = new ASMDependencyAnalyzer().analyze(new File("ClassName.class").toURI().toURL())

You might want to take a look at the Heap functions available in the JVM Tool Interface which allow you to iterate through the heap and recursively follow object references. It will require a lot of work to use this though.

One could use javap -v ClassFile.class and inspect the outcome. The constant pool contains the VM names of all used classes and interface references either as eg Class or Methodref etc. It is a file system op (creating eg temp files, reading the class and or jar file) and will not perform very well, but can be used to investigate a reference class for non-functionals aspect using relatively simple regex. You could for instance check if unallowed classes etc are indeed not used.

Constant pool:
#1 = InterfaceMethodref #263.#264     // appointmentplanner/api/Time.asMinutes:()I
#2 = Methodref          #105.#265     // appointmentplanner/APDayPlan."<init>":(Ljava/time/LocalDate;II)V
#3 = Methodref          #115.#266     // java/lang/Object."<init>":()V
#4 = Fieldref           #105.#267     // appointmentplanner/APDayPlan.date:Ljava/time/LocalDate;
#5 = Class              #268          // appointmentplanner/LinearAllocator
#6 = Methodref          #5.#269       // appointmentplanner/LinearAllocator."<init>":(II)V
#7 = Fieldref           #105.#270     // appointmentplanner/APDayPlan.allocator:Lappointmentplanner/LinearAllocator;

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