The above code contains quite a few class dependencies. It implicitly extends
java.lang.Object. It implements
java.lang.Runnable. It uses an object
java.lang.System. It also uses
java.lang.Class). Lastly, it depends on
All these dependencies are included in J2SE except
somepackage.ExternalThing, so this is the one we need to catch programmatically.
One way of accomplishing this is to use the Apache Foundation Byte Code Engineering Library. The BCEL can be used to do all sorts of things with class files and makes inspecting them really easy.
BCEL javadoc: http://jakarta.apache.org/bcel/apidocs/
EmptyVisitoris a do-nothing adapter implementation of the
Visitorinterface. By overriding the
visitConstantClassmethod, we can be notified of any classes in the constant pool.
Repositoryuses the classpath to locate classes, so the target class (foo.Bar) needs to be visible to the JVM.
This is the output:
foo/Bar java/lang/Object java/lang/Runnable java/lang/System java/io/File java/lang/Class java/io/PrintStream somepackage/ExternalThing
One character substitution and we have the fully qualified class names for our dependencies. There is still some more work to do - special handling for array types, loading classes outside the JVM and so on, but the potential should be obvious.
Java 6 (jre1.6.0_03)