10

Given that I basically want to eliminate checked exception usage and transform them to runtime exceptions, I would normally be doing something like this:

try {
    file.read();
} catch (IOException e){
    throw new RuntimeException(e); 
}

There are several disadvantages to doing this, but the one that irritates me the most is that my runtime exception would contain a nested stacktrace. Basically I would like to re-throw the "IOException" as a RuntimeException (or "IORuntimeException") with the original message and stacktrace, so I can avoid the useless nested stacktrace. The "fact" that I have re-thrown the exception somewhere in the middle seems like just useless noise to me.

Is this possible ? Is there any library that does this ?

krosenvold
  • 75,535
  • 32
  • 152
  • 208

6 Answers6

4

Project Lombok allows you to disable checked exceptions altogether.

missingfaktor
  • 90,905
  • 62
  • 285
  • 365
3

Follow up from my comment. Here's an article that has to throw some light on the issue. It uses sun.misc.Unsafe to rethrow exceptions without wrapping them.

Kazekage Gaara
  • 14,972
  • 14
  • 61
  • 108
2
class IORuntimeException extends RuntimeException {

    final IOException ioex;

    public IORuntimeException(IOException ioex) {
        this.ioex = ioex;
    }

    @Override
    public String getMessage() {
        return ioex.getMessage();
    }

    @Override
    public StackTraceElement[] getStackTrace() {
        return ioex.getStackTrace();
    }

    //@Override
    // ...
}

(Full class available here, as produced by Eclipse "Generate Delegate Methods" macro.)

Usage:

try {
    ...
} catch (IOException ioex) {
    throw new IORuntimeException(ioex);
}
aioobe
  • 413,195
  • 112
  • 811
  • 826
  • The problem with this approach is that it cannot be generalized for any `Exception` type, and thus causes too much boilerplate and code duplication. – missingfaktor Jun 08 '12 at 07:13
  • Yes, but the type information is lost. Only if Java had reified generics... then we could have done this with generics. – missingfaktor Jun 08 '12 at 07:20
  • An interesting aspect of this response is that it does not really work ;) "fillInStackTrace" is called from the the throwable constructor, meaning the member variable in the subclass hasnt been initialized. – krosenvold Jun 13 '12 at 11:29
  • Ah, so remove @Override ... fillInStackTrace then? – aioobe Jun 13 '12 at 11:34
2

If you're considering the other answer's use of Unsafe (I recommend not, but anyway), another option is to abuse generics to throw a checked exception with this evil pair of methods (from http://james-iry.blogspot.co.uk/2010/08/on-removing-java-checked-exceptions-by.html):

   @SuppressWarnings("unchecked")
   private static <T extends Throwable, A> 
     A pervertException(Throwable x) throws T {
      throw (T) x;
   }


   public static <A> A chuck(Throwable t) {
      return Unchecked.
        <RuntimeException, A>pervertException(t);
   }

You might also check out com.google.common.base.Throwables.getRootCause(Throwable) and just print its (root) stack trace.

artbristol
  • 32,010
  • 5
  • 70
  • 103
0

sounds like you actually NEED checked Exceptions

Oliver Watkins
  • 12,575
  • 33
  • 119
  • 225
0

As of Java 8 there's another way:

try {
  // some code that can throw both checked and runtime exception
} catch (Exception e) {
  throw rethrow(e);
}

@SuppressWarnings("unchecked")
public static <T extends Throwable> RuntimeException rethrow(Throwable throwable) throws T {
    throw (T) throwable; // rely on vacuous cast
}

* More info here.

Community
  • 1
  • 1
AlikElzin-kilaka
  • 34,335
  • 35
  • 194
  • 277