Java 7 precise rethrow and legacy code - java

The more precise rethrow allows to write code that throws the exception really thrown :
public void foo(String bar) throws FirstException, SecondException {
try{
// Code that may throw both FirstException and SecondException
}
catch (Exception e){
throw e;
}
}
Prior to Java 7 you had to write :
public void foo(String bar) throws Exception {
try{
// Code that may throw both FirstException and SecondException
}
catch (Exception e){
throw e;
}
}
My question: is there a tool that allows to detect imprecise throw in order to replace "Exception" with "FirstException, SecondException"?
So far, I have checked that there is no compiler warning in Eclipse. There is no rule in FindBugs or CodePro.

I think this is not a situation for a compiler warning, because the "overly broad" exception is not necessarily a problem: Unless the method is final or private, it defines what kind of exception any subclass implementation can throw. In that case, the wide scope may have been intentional.
Your question would apply equally well for Java pre-7:
public void foo(String bar) throws Exception {
// Code that may throw both FirstException and SecondException
}
Here, throws Exception could also be considered bad practice (but there are no warnings about it).
Along the same line of argument, note that you will get a compile error when you try to catch a (checked) Exception that cannot possibly be thrown, but you can add to the throws clause of the method signature all kinds of exceptions that the implementation body does not use.
A tool like FindBugs would be useful though.
Update: "Unless the method is final or private" : I have to agree that for private or final methods (and maybe static ones, too) there could be a warning.
Update 2: Even for final methods, you may want to leave your options open to throw more Exceptions in the future without breaking the interface.

Try casting the exception before throw, maybe it will do the trick?
public void foo(String bar) throws FirstException, SecondException {
try{
// Code that may throw both FirstException and SecondException
}
catch (Exception e){
throw ((e instanceof FirstException) ? (FirstException)e : (SecondException)e);
}
}
BTW, rethrowing the same exception seems rather clumsy thing to me...

Related

How to wrap checked exceptions but keep the original runtime exceptions in Java

I have some code that might throw both checked and runtime exceptions.
I'd like to catch the checked exception and wrap it with a runtime exception. But if a RuntimeException is thrown, I don't have to wrap it as it's already a runtime exception.
The solution I have has a bit overhead and isn't "neat":
try {
// some code that can throw both checked and runtime exception
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
}
Any idea for a more elegant way?
I use a "blind" rethrow to pass up checked exceptions. I have used this for passing through the Streams API where I can't use lambdas which throw checked exceptions. e.g We have ThrowingXxxxx functional interfaces so the checked exception can be passed through.
This allows me to catch the checked exception in a caller naturally without needing to know a callee had to pass it through an interface which didn't allow checked exceptions.
try {
// some code that can throw both checked and runtime exception
} catch (Exception e) {
throw rethrow(e);
}
In a calling method I can declare the checked exception again.
public void loadFile(String file) throws IOException {
// call method with rethrow
}
/**
* Cast a CheckedException as an unchecked one.
*
* #param throwable to cast
* #param <T> the type of the Throwable
* #return this method will never return a Throwable instance, it will just throw it.
* #throws T the throwable as an unchecked throwable
*/
#SuppressWarnings("unchecked")
public static <T extends Throwable> RuntimeException rethrow(Throwable throwable) throws T {
throw (T) throwable; // rely on vacuous cast
}
There is a lot of different options for handling exceptions. We use a few of them.
https://vanilla-java.github.io/2016/06/21/Reviewing-Exception-Handling.html
Guava's Throwables.propagate() does exactly this:
try {
// some code that can throw both checked and runtime exception
} catch (Exception e) {
throw Throwables.propagate(e);
}
UPDATE: This method is now deprecated. See this page for a detailed explanation.
Not really.
If you do this a lot, you could tuck it away into a helper method.
static RuntimeException unchecked(Throwable t){
if (t instanceof RuntimeException){
return (RuntimeException) t;
} else if (t instanceof Error) { // if you don't want to wrap those
throw (Error) t;
} else {
return new RuntimeException(t);
}
}
try{
// ..
}
catch (Exception e){
throw unchecked(e);
}
I have a specially compiled .class file containing the following:
public class Thrower {
public static void Throw(java.lang.Throwable t) {
throw t;
}
}
It just works. The java compiler would normally refuse to compile this, but the bytecode verifier doesn't care at all.
The class is used similar to Peter Lawrey's answer:
try {
// some code that can throw both checked and runtime exception
} catch (Exception e) {
Thrower.Throw(e);
}
You can rewrite the same using instanceof operator
try {
// some code that can throw both checked and runtime exception
} catch (Exception e) {
if (e instanceof RuntimeException) {
throw e;
} else {
throw new RuntimeException(e);
}
}
However, your solution looks better.
The problem is that Exception is too broad. You should know exactly what the possible checked exceptions are.
try {
// code that throws checked and unchecked exceptions
} catch (IOException | SomeOtherException ex) {
throw new RuntimeException(ex);
}
The reasons why this wouldn't work reveal deeper problems that should be addressed instead:
If a method declares that it throws Exception then it is being too broad. Knowing that "something can go wrong" with no further information is of no use to a caller. The method should be using specific exception classes in a meaningful hierarchy, or using unchecked exceptions if appropriate.
If a method throws too many different kinds of checked exception then it is too complicated. It should either be refactored into multiple simpler methods, or the exceptions should be arranged in a sensible inheritance hierarchy, depending on the situation.
Of course there can be exceptions to the rule. Declaring a method throws Exception can be perfectly reasonable if it's consumed by some kind of cross-cutting framework (such as JUnit or AspectJ or Spring) rather than comprising an API for others to use.
I generally use the same type of code structure, but condense it down to one line in one of the few times a ternary operator actually makes code better:
try {
// code that can throw
}
catch (Exception e) {
throw (e instanceof RuntimeException) ? (RuntimeException) e : new RuntimeException(e);
}
This does not require additional methods or catch blocks which is why I like it.
lombok has this handled with a simple annotation on the method 😊
Example:
import lombok.SneakyThrows;
#SneakyThrows
void methodThatUsusallyNeedsToDeclareException() {
new FileInputStream("/doesn'tMatter");
}
In the example the method should have declared throws FileNotFoundException, but with the #SneakyThrows annotation, it doesn't.
What actually happens behind the scenes is that lombok does the same trick as the high rated answer to this same question.
Mission accomplished!

Idiom to let a specific exception bypass a broad catch block?

Often, when implementing a template method or interface method, you can only throw one specific type of exception defined by the method. But your implementation may make class to API's that throw an incompatible exception type, or many different exception types.
Naturally you need to catch them and wrap the exceptions into the type suitable for the implemented method signature. Lets assume we want to implement this interface:
public interface SomeDataGetter {
public long getSomeData() throws IOException;
}
Our implementation makes use of some other API product to implement this, and the API method we are calling may have this signature:
public long loadFromDBOrCache(Object ... params) throws SQLException, IOException, ObjectNotFoundException, RuntimeException, FridayException, NotWeekendException, NumberIs42Exception;
I made this up to demonstrate the case where you can't exactly enumerate all the possibly thrown exceptions by concrete type. Do note that IOException is a type we are allowed to throw from our implementation.
Now I can go the lazy route when implementing this and wrap anything to fit my signature:
#Override
public long getSomeData() throws IOException {
try {
return loadFromDB(...);
} catch (Exception e) {
throw new IOException(e.getMessage(), e);
}
}
This will obviously wrap any exception into an IOException (even an IOException) and it works out ok. But I'd like to not wrap IOExceptions, since I am allowed to throw those without wrapping them:
#Override
public long getSomeData() throws IOException {
try {
return loadFromDB(...);
} catch (IOException e) {
throw e;
} catch (Exception e) {
throw new IOException(e.getMessage(), e);
}
}
You can imagine this gets cumbersome quickly if there are multiple possible exception in the implementation and multiple exceptions you are allowed from the implementation. I need an extra catch for each exception I want to pass throgh.
Whats the best idiom to keep that readable (also, I'm lazy, and don't want to write all these extra catches) and still avoid unneccessary exception nesting? Or shoud I not bother and just wrap everything?
One approach would be making a method that wraps all "prohibited" exceptions in an allowed one, while returning all the allowed ones unwrapped, like this:
private static void throwIoException(Exception e)
throws IOException // <<= Add other "allowed" exceptions here
{
if (e instanceof IOException) {
throw (IOException)e;
}
... // <<= Add checks for other "allowed" exceptions here
throw new IOException(e.getMessage(), e);
}
Now you can use a single catch block, and do the wrapping as needed:
try {
return loadFromDB(...);
} catch (Exception e) {
throwIoException(e);
}
One unpleasant consequence of this is that the stack trace shows the utility method at the top of the newly created IOException, but that's not important, because the real exception is the wrapped one, not the IOException wrapper. If the exception that you caught happens to be IOException, the correct stack trace should remain in place.
I would consider the lazy route of wrapping all exceptions you get into IOExceptions (or another checked exception) to be a bad practice. Instead I would consider wrapping the exceptions in runtime exceptions, thereby bypassing the catch or specify requirement. E.g.
#Override
public long getSomeData() throws IOException {
try {
return loadFromDB(...);
} catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
}
}
The reason why this is better is that checked exceptions carry a certian meaning. If you catch for instance a ParseException in your code and rethrow that as a IOException you are lying. As a user of your code I might be able to do something about certain types of checked exceptions, but if you obfuscate the true cause of an exception it will be more difficult to debug the code when an error occurs.
In general I think you should minimize the use of checked exceptions since it litters error handling code throughout your application. Also if you are using someone else's code you have no guarantee that a RuntimeException won't be thrown anyway (unless you carefully read through it all). Therefore you have to consider that possibility anyway and handle it somewhere so your application don't crash. The virtues of unchecked exception vs checked exceptions has been discussed quite a lot elsewhere here and here for instance.

Is it possible to ignore an exception?

In Java, is it possible to make a method that has a throws statement to be not checked.
For example:
public class TestClass {
public static void throwAnException() throws Exception {
throw new Exception();
}
public static void makeNullPointer() {
Object o = null;
o.equals(0);//NullPointerException
}
public static void exceptionTest() {
makeNullPointer(); //The compiler allows me not to check this
throwAnException(); //I'm forced to handle the exception, but I don't want to
}
}
You can try and do nothing about it:
public static void exceptionTest() {
makeNullPointer(); //The compiler allows me not to check this
try {
throwAnException(); //I'm forced to handle the exception, but I don't want to
} catch (Exception e) { /* do nothing */ }
}
Bear in mind, in real life this is extemely ill-advised. That can hide an error and keep you searching for dogs a whole week while the problem was really a cat(ch). (Come on, put at least a System.err.println() there - Logging is the best practice here, as suggested by #BaileyS.)
Unchecked exceptions in Java extend the RuntimeException class. Throwing them will not demand a catch from their clients:
// notice there's no "throws RuntimeException" at the signature of this method
public static void someMethodThatThrowsRuntimeException() /* no need for throws here */ {
throw new RuntimeException();
}
Classes that extend RuntimeException won't require a throws declaration as well.
And a word from Oracle about it:
Here's the bottom line guideline: If a client can reasonably be expected to recover from an exception, make it a checked exception. If a client cannot do anything to recover from the exception, make it an unchecked exception.
There are 3 things you can do :
Throw a RuntimeException (or something extending a RuntimeException, like NullPointerException, IllegalArgumentException,...), you don't have to catch these as they are unchecked exceptions.
Catch the exception and do nothing (not recommended) :
public static void exceptionTest() {
makeNullPointer(); //The compiler allows me not to check this
try {
throwAnException(); //I'm forced to handle the exception, but I don't want to
} catch (Exception e) {
// Do nothing
}
}
Change exceptionTest () declaration to say that it throws an Exception, and let the method calling it catch the Exception and do what is appropriate :
public static void exceptionTest() throws Exception {
makeNullPointer(); //The compiler allows me not to check this
throwAnException(); //I'm no more forced to handle the exception
}
In Java there is two kinds of Exceptions, Checked Exceptions and Unchecked Exceptions.
Exception is a checked exception, must caught or thrown.
NullPointerException is a RuntimeException, (the compiler doesn’t forces them to be declared in the throws claus) you can ignore it, ,but it still may occur in the Runtime, and your application will crash.
From Exception documentation:
The class Exception and any subclasses that are not also subclasses of
RuntimeException are checked exceptions. Checked exceptions need to be
declared in a method or constructor's throws clause if they can be
thrown by the execution of the method or constructor and propagate
outside the method or constructor boundary.
From the RuntimeException documentation:
RuntimeException is the superclass of those exceptions that can be
thrown during the normal operation of the Java Virtual Machine.
RuntimeException and its subclasses are unchecked exceptions.
Unchecked exceptions do not need to be declared in a method or
constructor's throws clause if they can be thrown by the execution of
the method or constructor and propagate outside the method or
constructor boundary.
No, it raises a compiler error. Being a checked exception, you must either catch it or propagate it by declaring your method as potentially throwing it.
Check this and this.
Throw a RuntimeException or an exception which is derived from RuntimeException. Then the compiler will not force you to catch it.
The other answers are right, in that they correctly tell you what you should do, but it is actually possible to throw a undeclared checked exception. There are a few ways this can be done; the simplest is:
public void methodThatSecretlyThrowsAnException() {
Thread.currentThread().stop(new Exception());
}
or if your goal is to wrap an existing method that does declare its exception
public void methodThatSecretlyThrowsAnException() {
try {
methodThatAdmitsItThrowsAnException();
} catch(final Exception e) {
Thread.currentThread().stop(e);
}
}
(Needless to say, you should never do this.)
Just catch an exception and dont do any thing with it, leave it as it is and catch the generic exception in case you are not aware of the specific exception
try{
//Your logic goes here
}
catch(Exception e)//Exception is generic
{
//do nothing
}
AS I know, it's impossible in the case. Only unchecked exception, compiler can skip to check. such as RuntimeException.
You can use a loophole in the Java Compiler. Add the following code:
public RuntimeException hideThrow(Throwable e) {
if (e == null)
throw new NullPointerException("e");
this.<RuntimeException>hideThrow0(e);
return null;
}
#SuppressWarnings("unchecked")
private <GenericThrowable extends Throwable> void hideThrow0(Throwable e) throws GenericThrowable {
throw (GenericThrowable) e;
}
You can catch the exception, then invoke hideThrow with the exception to throw it without the compiler noticing. This works because of type erasure. At compile time, GenericThrowable represents RuntimeException because that is what we are passing. At run time, GenericThrowable represents Throwable because that is the basic type in the type parameter specification.
It is not advisable to avoid an exception with an empty catch block even though you are completely sure that is not going to fail under any circumstance. Sometimes, we are not aware of the human factor.
If you are sure that an exception is very unlikely to happen (if not impossible) you should create your own Exception and and wrap the unexpected exception in it.
For example:
private class UnlikelyException extends RuntimeException {
public UnlikelyException (Exception e){
super (e);
}
}
Then wrap your code with a try-catch block and throw your exception, which you don't have to catch
try {
// Your code
} catch (Exception e) {
throw new UnlikelyException(e);
}

throw exception

Why can't you throw an InterruptedException in the following way:
try {
System.in.wait(5) //Just an example
} catch (InterruptedException exception) {
exception.printStackTrace();
//On this next line I am confused as to why it will not let me throw the exception
throw exception;
}
I went to http://java24hours.com, but it didn't tell me why I couldn't throw an InterruptedException.
If anyone knows why, PLEASE tell me! I'm desperate! :S
You can only throw it if the method you're writing declares that it throws InterruptedException (or a base class).
For example:
public void valid() throws InterruptedException {
try {
System.in.wait(5) //Just an example
} catch (InterruptedException exception) {
exception.printStackTrace();
throw exception;
}
}
// Note the lack of a "throws" clause.
public void invalid() {
try {
System.in.wait(5) //Just an example
} catch (InterruptedException exception) {
exception.printStackTrace();
throw exception;
}
}
You should read up on checked exceptions for more details.
(Having said this, calling wait() on System.in almost certainly isn't doing what you expect it to...)
There are two kinds of exceptions in Java: checked and unchecked exceptions.
For checked exceptions, the compiler checks if your program handles them, either by catching them or by specifying (with a throws clause) that the method in which the exception might happen, that the method might throw that kind of exception.
Exception classes that are subclasses of java.lang.RuntimeException (and RuntimeException itself) are unchecked exceptions. For those exceptions, the compiler doesn't do the check - so you are not required to catch them or to specify that you might throw them.
Class InterruptedException is a checked exception, so you must either catch it or declare that your method might throw it. You are throwing the exception from the catch block, so you must specify that your method might throw it:
public void invalid() throws InterruptedException {
// ...
Exception classes that extend java.lang.Exception (except RuntimeException and subclasses) are checked exceptions.
See Sun's Java Tutorial about exceptions for detailed information.
InterruptedException is not a RuntimeException so it must be caught or checked (with a throws clause on the method signature). You can only throw a RuntimeException and not be forced by the compiler to catch it.

How safe is my safe rethrow?

(Late edit: This question will hopefully be obsolete when Java 7 comes, because of the "final rethrow" feature which seems like it will be added.)
Quite often, I find myself in situations looking like this:
do some initialization
try {
do some work
} catch any exception {
undo initialization
rethrow exception
}
In C# you can do it like this:
InitializeStuff();
try
{
DoSomeWork();
}
catch
{
UndoInitialize();
throw;
}
For Java, there's no good substitution, and since the proposal for improved exception handling was cut from Java 7, it looks like it'll take at best several years until we get something like it. Thus, I decided to roll my own:
(Edit: Half a year later, final rethrow is back, or so it seems.)
public final class Rethrow {
private Rethrow() { throw new AssertionError("uninstantiable"); }
/** Rethrows t if it is an unchecked exception. */
public static void unchecked(Throwable t) {
if (t instanceof Error)
throw (Error) t;
if (t instanceof RuntimeException)
throw (RuntimeException) t;
}
/** Rethrows t if it is an unchecked exception or an instance of E. */
public static <E extends Exception> void instanceOrUnchecked(
Class<E> exceptionClass, Throwable t) throws E, Error,
RuntimeException {
Rethrow.unchecked(t);
if (exceptionClass.isInstance(t))
throw exceptionClass.cast(t);
}
}
Typical usage:
public void doStuff() throws SomeException {
initializeStuff();
try {
doSomeWork();
} catch (Throwable t) {
undoInitialize();
Rethrow.instanceOrUnchecked(SomeException.class, t);
// We shouldn't get past the above line as only unchecked or
// SomeException exceptions are thrown in the try block, but
// we don't want to risk swallowing an error, so:
throw new SomeException("Unexpected exception", t);
}
private void doSomeWork() throws SomeException { ... }
}
It's a bit wordy, catching Throwable is usually frowned upon, I'm not really happy at using reflection just to rethrow an exception, and I always feel a bit uneasy writing "this will not happen" comments, but in practice it works well (or seems to, at least). What I wonder is:
Do I have any flaws in my rethrow helper methods? Some corner cases I've missed? (I know that the Throwable may have been caused by something so severe that my undoInitialize will fail, but that's OK.)
Has someone already invented this? I looked at Commons Lang's ExceptionUtils but that does other things.
Edit:
finally is not the droid I'm looking for. I'm only interested to do stuff when an exception is thrown.
Yes, I know catching Throwable is a big no-no, but I think it's the lesser evil here compared to having three catch clauses (for Error, RuntimeException and SomeException, respectively) with identical code.
Note that I'm not trying to suppress any errors - the idea is that any exceptions thrown in the try block will continue to bubble up through the call stack as soon as I've rewinded a few things.
There are a couple of way to handle this. The first is my preference if you don't need to know what the exception was.
boolean okay = false;
try {
// do some work which might throw an exception
okay = true;
} finally {
if (!okay) // do some clean up.
}
In some cases you can do the same without an extra variable, depending on what the try block does.
A second option is a hack but also works.
try {
// do some work which might throw an exception
} catch (Throwable t) {
// do something with t.
Thread.currentThread().stop(t);
}
The stop(Throwable t) method doesn't stop the thread, instead it causes the thread to throw the exception provided in an unchecked way.
You can use Unsafe.throwException() with a bit of fiddling and there is a way to do this with Generics which I have forgotten.
If you are that concerned about getting your uninitialization to happen then you may want to just put that code into a finally block, as, if it should be called at some point, then you perhaps should always clean up.
I am leery of catching Throwable as some of the exceptions I want to handle, and some I just log, as, there is no use passing exceptions that the user can't do anything about, such as a NullPointerException.
But, you didn't show what SomeException is defined as, but if an OutOfMemoryException is thrown, your throwable will catch it, but it may not be the same type as SomeException so your wrapper will be needed in your sample function, at least when I look at the instanceOrUnchecked method.
You may want to write a unit test, try different classes of Exceptions and see what does or doesn't work as expected, so you can document the expected behavior.
An alternative is to have a factory which creates SomeException only if the cause is a checked exception:
public static SomeException throwException(String message, Throwable cause) throws SomeException {
unchecked(cause); //calls the method you defined in the question.
throw new SomeException(message, cause);
}
The reason why I put in the return value in the method is so that the client can do something like this:
catch (Throwable e) {
undoInitialize();
throw SomeException.throwException("message", e);
}
so that the compiler is fooled into not requiring a return after the catch statement if the method has a return type, but it still throws the exception if the client forgot to put the throw before the call to the factory method.
The disadvantage of this over your code is that it is less portable (it works for SomeException, but not for SomeOtherException), but that may be ok, because it won't be for every exception type that you need to have an undo initialize.
If it fits your use case you could put the unchecked call in the constructor of SomeException and have the logic available to all subclasses, but that would have to fit your specific project - it would not be a good idea in the general case as it would prevent wrapping runtime exceptions.
public SomeException(message, cause) {
super(message, unchecked(cause));
}
private static Throwable unchecked(Throwable cause) {
if (cause instanceof Error) throw (Error) cause;
if (cause instanceof RuntimeException) throw (RuntimeException) cause;
return cause;
}

Categories