I need to programmatically find out which JRE classes can be referenced in a compilation unit without being imported (for static code analysis). We can disregard package-local classes. According to the JLS, classes from the package java.lang
are implicitly imported. The output should be a list of binary class names. The solution should work with plain Java 5 and up (no Guava, Reflections, etc.), and be vendor agnostic.
Any reliable Java-based solution is welcome.
Here are some notes on what I've tried so far:
At first glance, it seems that the question boils down to "How to load all classes from a package?", which is of course practically impossible, although several workarounds exist (e.g. this and this, plus the blog posts linked there). But my case is much simpler, because the multiple classloaders issue does not exist. java.lang
stuff can always be loaded by the system/bootstrap classloader, and you cannot create your own classes in that package. Problem is, the system classloader does not divulge its class path, which the linked appoaches rely on.
So far, I haven't managed to get access to the system classloader's class path, because on the HotSpot VM I'm using, Object.class.getClassLoader()
returns null
, and Thread.currentThread().getContextClassLoader()
can load java.lang.Object
by delegation, but does not itself include the classpath. So solutions like this one don't work for me. Also, the list of guaranteed system properties does not include properties with this kind of classpath info (such as sun.boot.class.path
).
It would be nice if I didn't have to assume that there is an rt.jar at all, and rather scan the list of resources used by the system classloader. Such an approach would be safer with respect to vendor specific JRE implementations.