spotter
spotter

Reputation: 1216

Figure out all possible exceptions that can be thrown?

Is it possible to figure out all possible exceptions that can be thrown that are not necessarily listed by the method's signature.

There are 2 cases

1) runtime exceptions that don't have to be declared (obviously some are obvious, such as null pointer, but there are other runtime exceptions that I'd want to catch that can be due to bad data, which while in development I don't know is bad data yet).

2) exceptions that are subclasses of the exception listed in the signature.

a motivation example

imagine I call getInputStream() on an HttpURLConnection object, it throws java.io.Exception, but in reality, it throws other exceptions that are sublcasses of java.io.Exception (ala java.io.FileNotFoundException), which I'd want to handle in a unique manner (i.e. don't want to lump all java.io.Exceptions together).

so while I can learn in practice by catching java.io.Exception and printing out the actual exception, and then modifying code to handle that case, was wondering if there was a better method :)

thanks

edit: I think people are missing my 2nd problem. Methods that throw checked exceptions that are fully consistent with the method's signature, but aren't listed in it due to the method's signature only having some sort of base class.

Upvotes: 4

Views: 3471

Answers (4)

user207421
user207421

Reputation: 311052

No. You can't know in principle ahead of time what exception classes will be present on the CLASSPATH at runtime, for a start, nor can you know ahead of time the possible set of classes that implement the interface you are looking at, or extend the class you are looking at and override the method, unless the class or method is final. Your own example is a perfect case in point: you are looking at HttpURLConnection, but it is an abstract class, and the actual implementation class that appears at runtime can vary depending on your configuration: the HTTP URLStreamHandler class used can be redefined so as to use one that returns a different implementation of HttpURLConnection.

Upvotes: 3

Stephen C
Stephen C

Reputation: 719739

This is an intractable problem.

There is a relatively simple "non-solution". A static analyser should be able to enumerate all of the unchecked exceptions that are available in an application's class libraries; and all subclasses of any checked exception. Of course, that will give lots of false positives; i.e. exceptions that are allowed by the method signature, and yet cannot possibly be thrown in the call.

To find out the exceptions that could really be thrown, you would need to analyse the code using some kind of bytecode or sourcecode manipulation framework. It should be possible to determine the set of exception classes of the classes that are mentioned in the closure of the Java methods that are possibly used in a given method call. However some exceptions are not mentioned in the Java code. This includes runtime exceptions and errors thrown by the JVM itself, and others that might be thrown by native code libraries. And there there is the possibility that exception throwing code could be injected at runtime; e.g. using dynamic proxies. Finally, you have the issue that some exceptions will only be thrown in circumstances that are provably impossible ... in a given application.


So while I can learn in practice by catching java.io.Exception and printing out the actual exception, and then modifying code to handle that case, was wondering if there was a better method.

Yea. A better method is to read the javadoc, use your common sense to figure out which exceptions are likely, and read the source code if you are in doubt.

The other point is that you generally speaking don't need to know all of the possible exceptions in order to handle them effectively.

Finally, since the actual exceptions thrown may vary from one JVM to another (these are implementation details!) it is a bad idea to make assumptions in your code about exactly what exceptions might be thrown.

Upvotes: 1

Antimony
Antimony

Reputation: 39511

At the bytecode level, checked exceptions don't exist, so if you're calling bytecode methods, you can throw anything, regardless of the method signature. This also means that you can do the same from pure Java using reflection or custom classloaders.

You can also force code to throw any exception using Thread.stop

Upvotes: 0

Sujay
Sujay

Reputation: 6783

Is it possible to figure out all possible exceptions that can be thrown that are not necessarily listed by the method's signature.

Simple answer: Not really.

My answer is heavily based on this document, so I would suggest that you read this document to get an understanding of why Java designers didn't make it a necessity for you to handle all possible exception. The reasoning behind having unchecked exception as the document puts it:

Runtime exceptions represent problems that are the result of a programming problem, and as such, the API client code cannot reasonably be expected to recover from them or to handle them in any way. Such problems include arithmetic exceptions, such as dividing by zero; pointer exceptions, such as trying to access an object through a null reference; and indexing exceptions, such as attempting to access an array element through an index that is too large or too small.

Runtime exceptions can occur anywhere in a program, and in a typical one they can be very numerous. Having to add runtime exceptions in every method declaration would reduce a program's clarity. Thus, the compiler does not require that you catch or specify runtime exceptions (although you can).

So, in my opinion, looking out for all possible exception wouldn't be a good idea. For example, it doesn't make sense to OutOfMemoryError. In fact, it is also considered a bad practice to catch such an exception.

Upvotes: 2

Related Questions