aspose file tools*
The moose likes Beginning Java and the fly likes Unexpected behavior with Throwable.Error Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "Unexpected behavior with Throwable.Error" Watch "Unexpected behavior with Throwable.Error" New topic
Author

Unexpected behavior with Throwable.Error

Jason Gullickson
Greenhorn

Joined: Jul 01, 2011
Posts: 3

Earlier today I had a problem with some Java code. After a bit of debugging we figured out that it was just a simple ClassNotFoundException because a jar file was missing from the execution class path. The part I'm still struggling with is the way that the Exception exhibited itself -- there was no error output and it didn't stop execution the way I would have expected it to.

The stack trace output looks like this:

java.lang.NoClassDefFoundError: org/apache/log4j/PropertyConfigurator
at ait.directory.DirectoryServiceClient.initializeLogger(DirectoryServiceClient.java:621)
at ait.directory.DirectoryServiceClient.findMembers(DirectoryServiceClient.java:73)
at Test_Socket_Client.main(Test_Socket_Client.java:28)
Caused by: java.lang.ClassNotFoundException: org.apache.log4j.PropertyConfigurator


Each of those three functions/methods are wrapped in try/catch(Exception) blocks. The method initLogger() attempted to use org.apache.log4j.PropertyConfigurator which was missing from the class path and a ClassNotFoundException was thrown. This all makes good sense to me, but then something "mysterious" happens -- nothing. Execution continues at the next line in main(). No catch blocks hit, no stackTraces or output of any kind, nothing at all. Note: Eventually I got the above trace by adding a catch(Error) block.

I'm fuzzy on how the ClassNotFoundException is being transmuted into a java.lang.NoClassDefFoundError, but that explains why it is avoiding my catch(Exception) blocks. The really puzzling thing to me is that the Error stops short of causing my program to bomb-out completely. Again, I have no code to translate an Exception to an Error, nor any code to catch an Error anywhere -- what's going on here?

Thanks,
Jason

PS. I'm looking at trying to write this as a simplified test case that will make more sense to post here, as I expect the very first piece of feedback will request.
Winston Gutkowski
Bartender

Joined: Mar 17, 2011
Posts: 8009
    
  22

Jason Gullickson wrote:I'm fuzzy on how the ClassNotFoundException is being transmuted into a java.lang.NoClassDefFoundError, but that explains why it is avoiding my catch(Exception) blocks.

There's nothing to stop a catch block from throwing another Exception (or Error), in this case by probably doing something like:
The really puzzling thing to me is that the Error stops short of causing my program to bomb-out completely. Again, I have no code to translate an Exception to an Error, nor any code to catch an Error anywhere -- what's going on here?

It's probably dealt with by the software itself. The code that issues the error is more than likely executed from another try...catch block which determines if it can recover from the error. If it can, it does.

BTW, if you really want a catch block that can catch anything, try
catch (Throwable t) {...
but I'd use with discretion.

Winston


Isn't it funny how there's always time and money enough to do it WRONG?
Articles by Winston can be found here
Jason Gullickson
Greenhorn

Joined: Jul 01, 2011
Posts: 3

Winston,

Thanks for your reply.

Winston Gutkowski wrote:
It's probably dealt with by the software itself. The code that issues the error is more than likely executed from another try...catch block which determines if it can recover from the error. If it can, it does.

I see what you are saying -- the part of the stackTrace I didn't include above indicates that the Exception was thrown inside java.lang.ClassLoader, and that is probably where the Exception was translated into an Error.

Winston Gutkowski wrote:
BTW, if you really want a catch block that can catch anything, try
catch (Throwable t) {...
but I'd use with discretion.

Agreed -- this is how we figured it out the class path problem in the first place.


I guess the only remaining question is why the uncaught java.lang.NoClassDefFoundError doesn't stop the execution like I would have expected.

Regards,
Jason
Winston Gutkowski
Bartender

Joined: Mar 17, 2011
Posts: 8009
    
  22

Jason Gullickson wrote:I guess the only remaining question is why the uncaught java.lang.NoClassDefFoundError doesn't stop the execution like I would have expected.

Are you sure it's uncaught? There's nothing to stop code in log4j doing something like:and then carry on quite happily. Perhaps there's some sort of default class it can use.

Winston

Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18669
    
    8

This seems perfectly normal to me. The API docs for NoClassDefFoundError say

Thrown if the Java Virtual Machine or a ClassLoader instance tries to load in the definition of a class (as part of a normal method call or as part of creating a new instance using the new expression) and no definition of the class could be found.

The searched-for class definition existed when the currently executing class was compiled, but the definition can no longer be found.


Which means that the ait.directory.DirectoryServiceClient class was compiled successfully and the PropertyConfigurator class was identified at that time, but at runtime it can't be found.

Whereas the API docs for ClassNotFoundException say

Thrown when an application tries to load in a class through its string name using:

The forName method in class Class.
The findSystemClass method in class ClassLoader .
The loadClass method in class ClassLoader.

but no definition for the class with the specified name could be found.


Which means that the ait.directory.DirectoryServiceClient class isn't using any of those techniques to load the class.
Jason Gullickson
Greenhorn

Joined: Jul 01, 2011
Posts: 3

Winston, I think you're on the right track, though the catch/re-throw block definitely wasn't in log4j since it wasn't in the class path and that was the very reason for the problem in the first place. I think Paul nailed it, the Exception is caught by either the JVM or ClassLoader and re-thrown as an Error instead.

Paul, your second point makes sense. I'm not using any of those techniques directly, though I suspect that the JVM probably is.


Finally, I have figured out what was causing the behavior I was so puzzled about. I built a simplified test case and it worked exactly as I expected it to. So I went back to the original code and eventually realized that I had a misplaced closing bracket that included the return statement inside the finally block. I don't know exactly how the JVM dealt with that, but I can certainly imagine why it would cause mysterious problems like mine.


Thanks for the help guys!

Regards,
Jason
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Unexpected behavior with Throwable.Error