Troubleshooting ClassNotFoundException with Filemon (on Windows)

Have you ever run into classpath issues where you could have sworn the class was in a jar, the jar was on a classpath, yet you still got NoClassDefFoundError or ClassNotFoundException. Or perhaps you define several Classloaders in your application each with its own classpath and are not quite sure which one gets the priority in a specific situation.

On Windows, FileMon from SysInternals (FileMon from Microsoft now) is a great free tool to resolve exactly those kind of questions.

Imagine you have a very simple java class:

public class Test
public static void main(String[] args) throws Exception
Class c = Class.forName("somepackage.SomeClass");

Basically, we are trying to load somepackage.SomeClass into the system. For our test purposes that class does not exist.

Compile this class and run. It comes back with java.lang.ClassNotFoundException: somepackage.SomeClass. As it should.

The question however is what Classpath the JVM was looking for the class on. If your application is a J2EE deployment or anything with custom classloaders, this question may become a hard one to answer.

This is where the FileMon shines. FileMon will show you every file operation on the machine performed by any – or all – of the processes.

Start it up and set the filter to java.exe . If that causes problems you can reset filter to * and check what name your JVM is generating the log entries under.

With FileMon capture enabled, rerun your test or scenario. After you see the ClassNotFoundException, stop the capture. Now search from the capture start for the classname you got in the exception, in this case SomeClass. You should see a sequence of the lines similar to the following (some columns had been cut):

C:\temp\filemontest SUCCESS
C:\somepackage\SomeClass.class PATH NOT FOUND
C:\temp\filemontest SUCCESS
C:\Utils\somepackage\SomeClass.class PATH NOT FOUND
C:\temp\filemontest SUCCESS
C:\temp\somepackage\SomeClass.class PATH NOT FOUND
C:\temp\filemontest SUCCESS
C:\temp\filemontest\somepackage\SomeClass.class PATH NOT FOUND

From here, we can figure out that the classpath checked was: C:\;C:\Utils;C:\temp;C:\temp\filemontest.
Now, you can check that against your expectations and figure out how to fix the discrepancy.

If you are on Solaris/Linux machine instead, look into truss/strace for a way to achieve very similar results.

BlogicBlogger Over and Out