Reflection
Java's reflection APIs can also get in the way of figuring out where classes come from. You may search around for quite a while and discover that there's no call anywhere that actually constructs an instance of a class.
The Java Swing APIs work this way. Although the source is public, much of the code that does the actual work is hidden away in implementation classes in the sun package, which is not public. Consider this code extract from the JDK 1.4 JEditorPane.createEditorKitForContentType:
String classname = (String) getKitTypeRegistry().get(type); ClassLoader loader = (ClassLoader) getKitLoaderRegistry().get(type); Class c = loader.loadClass(classname); EditorKit k = (EditorKit) c.newInstance();
The class never instantiates an EditorKit with a constructor or a factory. It creates a new instance from the class itself. The class is not determined until runtime, and even tracking down where the name comes from can be a challenge. getKitTypeRegistry is:
return (Hashtable)SwingUtilities.appContextGet(kitTypeRegistryKey);
which sends us to the SwingUtlities.appContextGet class, which reads:
return AppContext.getAppContext().get(key);
I can't find any file AppContext.java, nor is it an inner class of SwingUtilities. It turns up in the imports:
import sun.awt.AppContext;
I know I don't have the implementation available because it's a sun.awt class. At least they mentioned the name explicitly; they could have imported sun.awt.* and I'd still be wondering where my classname comes from.
If you're using JDK 1.3 or later, there may be no actual implementation at all. If the developers have been really tricky, they may use the java.lang.reflect.Proxy class to create an implementation class on the fly. This can be really a pain, I'm afraid, and finding the actual implementation is going to be quite the chore.