A Note About ClassLoaders
It used to be that the correct method of implementing a custom Classloader was to override loadClass()
. But these days, the correct way is to implement findClass()
, which uses the newer 'delegation' model of Classloader customization. JMClassLoader uses the older, loadClass()
method, because JarMaker has special needs. In particular, we don't want to use the default implementation of loadClass()
, because this would make it impossible for us to track which classes were loaded. To understand this, we need to look at how loadClass()
In the base class, loadClass() does a number of things. It checks a cache to see if it has already loaded the class, and if it hasn't, then it checks the so-called 'parent' Classloader. If it still hasn't found the class, it calls the findClass() method. Finally, it calls resolveClass(), which links the class with other classes that it requires.
If you don't want to implement all these steps, you can choose to override the findClass() method rather than the loadClass() method. This way, the default implementation of loadClass() will take care of these details for you.
In fact, using findClass() is the preferred method of implementing a custom Classloader, since it's more likely that your Classloader will behave as expected. However, you must overload loadClass(), because The default implementation does something which we dont want it to doit loads classes from the filesystem.
The default implementation of loadClass() would call the system Classloader, which would find the class and return it. It would never call the findClass(), and therefore you wouldn't get to record it. Thus, loadClass() is bad for my purposes, since I want to make sure that JMClassLoader loads the class.
Furthermore, if my implementation of loadClass() were to simply call the system Classloader itself, the system Classloader would find the class. I would record this class, which is good, but the class would be marked as having been loaded by the system Classloader, and further classes would be loaded by the system Classloader as well. As a result, only a single class would be loaded and I would not be able to build the JAR file.
So you have to load the class yourself, directly from the filesystem. For the sake of simplicity, the implementation provided in the source code (see link in left column) only looks in the current directory (and subdirectories thereof), but it could easily be extended to look in the classpath for other places to find classes.