I saw a question posted a couple of months ago on stackoverflow, or a forum. I can't remember where I saw it actually. The question was how do I determine what classes are currently loaded by the
ClassLoader
when an application is loaded and running. A number of folks posted various solutions like using
java -verbose
which are of limited help. Another solution was to get using something like
ClassLoader.getSystemClassLoader();
. The latter looks very promising, but is wrong. I knew that there are a number of classes that are loaded that this would not display.
Ssssh... I will show you how I know.
The problem and solution is surprisingly non-trivial. I thought I would come up with a solution like the one above in 5 minutes. I did come up with one above in about that much time. It turns out to be incorrect.
The solution is to use a Java agent to instrument the JVM and see what it is loading. I am sure a number of you have seen the
-javaagent:[=]
flag for the VM and wondered what is that for. I am going to show you.
First some results:
all length -> 815
system length -> 163
appLoader length -> 163
classes size -> 61
The first value
all indicates all of the classes loaded by the JVM. That is a lot of classes. This is via an Instrumentation agent.
The second value
system indicates all of the classes loaded by the System
ClassLoader
. This is significantly less than loaded by the JVM. This is via an Instrumentation agent.
The third value is the
appLoader which is the application classloader. It matches the System, but this may not always be the case. This is via an Instrumentation agent.
Finally, the last value
classes is what you get from the
ClassLoader
without instrumentation. It is a paltry amount of the total classes loaded.
So which one is right? Good question... Here is an answer only a parent, or teacher can give.
"It depends."
If I am looking at everything being loaded to check for something forensically I would use the 815 and look at what these classes are and where they came from. If I am checking which classes are loaded to help with reflection, I would look at the 61.
If you have read this far, then you want the code to look at. I have split it into a couple of
NetBeans Maven projects hosted on
BitBucket using
Mercurial.
Code
InstrumentationAgent.java
AgentLoader.java
App.java
Note: I had to put the tools.jar in my Maven repository to make it easy to add as a library.
References
We can not achieve success alone. It is on the shoulders of giants that we see further. I used an example from Dhruba Bandopadhyay to figure out some of the instrumentation process.