![]() |
| Because my Eclipse project didn't print the exception, I set a breakpoint and stepped into the problem to find something resembling a stack trace. |
This post, however, will cover the longer story of my debugging. The intent is to show that debugging can often be a tricky process, and that it's very important to rule out all of the basics first. I knew the projects own files were not somehow improperly imported into the project, and my classpath files all seemed right, which led me (to my downfall) to assume that the problem must be very complex.
I decided also to build upon the previous Coding Zen lesson with a new one, which we will find is tantamount to finding the solution in the more exceptional debugging cases:
The amateur studies advanced techniques; the master practices the fundamentals.
Understanding the problem—the "advanced techniques"
Starting at the bottom of the stack, we can see that the problem appears to be of theClassLoader.loadClass variety. This prompted me to read the ClassLoader documentation on its loadClass(String) method, which searches for classes using the same steps noted in the loadClass(String, boolean) method. They are as follows:- Invoke
findLoadedClass(String)to check if the class has already been loaded. - Invoke the
loadClassmethod on the parent class loader. If the parent isnullthe class loader built-in to the virtual machine is used, instead. - Invoke the
findClass(String)method to find the class.
I felt comfortable skipping step one, because our stack specifically cites the
Sort of. That parent was called
That's where the "CSI moment" happened. You know that part in an episode of CSI, about three quarters of the way through, when they've got all the evidence and it's not leading anywhere, but then one new twist happens that makes the whole case come together? That's what happened.
Feeling like this research was taking me back to the same conclusion I had before—Eclipse can't find the class because it doesn't know where to look—I decided to try reproducing the problem in a different environment.
Short interlude. Any seasoned troubleshooter will say this is the first thing you should do. In many ways, this was the first thing I 'did.' When this problem began, I immediately viewed this as a learning opportunity (since this was the first time I ran into the infamous
Interestingly: when I ran the code, in Eclipse, on my PC (usually reserved as an entertainment center), I got the following output.
Running the code on my PC throws no exception and produces the (at the time) expected output. And like the missing hair from the crime scene, everything fell into place: the problem was specific to my laptop.loadClass method. So I checked to see if there was a parent class loader. Indeed there was (right).Sort of. That parent was called
sun.misc.Launcher$ExtClassLoader@360b0c5a, which according to my assigned reading indicates that the JVM is searching in the <JAVA_HOME>/jre/lib/ext directory. Which seems to be the class loader built-in to the JVM.Getting to the cause—practicing the fundamentals
If we go back to our stack (top of this post) we can see that further up thefindClass method is being invoked—so then, my case appeared to actually be the least common cause: an exception thrown by the findClass method. Naturally, that means I went straight to the documentation, where I found that "this method should be overridden by class loader implementations that follow the delegation model for loading classes, and will be invoked by the loadClass method after checking the parent class loader for the requested class."That's where the "CSI moment" happened. You know that part in an episode of CSI, about three quarters of the way through, when they've got all the evidence and it's not leading anywhere, but then one new twist happens that makes the whole case come together? That's what happened.
Feeling like this research was taking me back to the same conclusion I had before—Eclipse can't find the class because it doesn't know where to look—I decided to try reproducing the problem in a different environment.
Short interlude. Any seasoned troubleshooter will say this is the first thing you should do. In many ways, this was the first thing I 'did.' When this problem began, I immediately viewed this as a learning opportunity (since this was the first time I ran into the infamous
ClassNotFoundException), and therefore decided to take the time to actually learn about it, and write about it.The "CSI moment"
![]() |
| It can be as convoluted as finding a key inside an alligator's body, or it can be as simple as finding that your code works on your other computer. |
Directories for cab
Contents in cab
Notice that when one writes about CSI, it has certain effects on one's writing: specifically, that you use colons too much.
Laying out the evidence
![]() |
| Eclipse settings are common between computers; this can't be the problem. |
Being the only thing I could think of, I concluded that the difference must be local to my laptop... meaning:
My Java versions differ. And they do. Java 7u25 is installed on my PC, and 7u40 on my laptop. How could this be causing my problem?
The Twist!
This time I was curious about what would happen when I tried to run the code by command line—since Eclipse wasn't throwing an exception by suspending the thread with a
ClassNotFoundException.
And when I ran Java from command line, I found that I got a different error. Check out my stack trace:
NoClassDefFoundError
These two problems are very closely related, according to every article I've read explaining either one. Of course, I was incorrectly running my file (I should have been in the Academia root folder, and entered
I decided to do some additional research, and found this blog post from Javarevisited to be very useful. After some reading, I found a huge twist. And just like CSI, the answer is always much simpler than the problem makes it out to be.
java cabinet.CabinetTest; but I continued to get this error even after I moved CabinetTest to the Acamedia root folder and ran from there).I decided to do some additional research, and found this blog post from Javarevisited to be very useful. After some reading, I found a huge twist. And just like CSI, the answer is always much simpler than the problem makes it out to be.
My Cabinet constructor was throwing an error into a static block (main).
Next time
In the next post, I'll complete my narrative by reflecting on the results and seeking to better understand all the complexities of my issue: the above was indeed the cause (I've since moved on in my coding, finally) but that does not answer why, for example, I got two different exceptions—or why it worked on my PC.





No comments:
Post a Comment