views:

24

answers:

2

How can I make my dynamic proxy throw checked exceptions?

I need a transparent wrapper for an interface which sometimes throws checked exceptions such as IOException. Is it possible without 3rd party AOP or writing my own proxy? Modifying all 20 methods of the interface by hand is not an option either.

+3  A: 

You can use a dynamic proxy. As long as the checked exceptions are part of the interface you can throw the checked exceptions from the invocation handler. Otherwise this is illegal and will create an UndeclaredThrowableException that wraps the thrown checked exception.

interface A{
    void x() throws IOException;
}

A proxy = (A) newProxyInstance(classLoader, new Class<?>[]{A.class}, 
  new InvocationHandler() {      
        @Override
        public Object invoke(Object arg0, Method arg1, Object[] arg2) 
            throws Throwable {
            throw new IOException();
        }
   }
);
proxy.x();

Output:

Exception in thread "main" java.io.IOException
at X$1.invoke(X.java:19)
at $Proxy0.x(Unknown Source)
at X.main(X.java:22)

With an undeclared checked exception for interface A:

interface A{
    void x();
}

Exception in thread "main" java.lang.reflect.UndeclaredThrowableException
  at $Proxy0.x(Unknown Source)
  at X.main(X.java:22)
Caused by: java.io.IOException
  at X$1.invoke(X.java:19)
  ... 2 more
Thomas Jung
Thanks. One note, Method.invoke() (often used in `InvocationHandler.invoke()` wraps the original exception in `InvocationTargetException`, so it needs to be unwrapped.
Konrad Garus
A: 

A dynamic proxy can throw checked exception if the exception is declared in the signature of the method of the interface it is proxying. From the Sun's Dynamic Proxy reference:

If an exception is thrown by the invoke method, it will be also thrown by the method invocation on the proxy instance.

The exception's type must be assignable to either any of the exception types declared in the signature of the interface method or to the unchecked exception types java.lang.RuntimeException or java.lang.Error.

If a checked exception is thrown by invoke that is not assignable to any of the exception types declared in the throws clause of the interface method, then an UndeclaredThrowableException will be thrown by the method invocation on the proxy instance. The UndeclaredThrowableException will be constructed with the exception that was thrown by the invoke method.

abhin4v