2010-09-15 8 views
9

¿Cómo puedo hacer que mi proxy dinámico arroje excepciones controladas?Proxy dinámico y excepciones marcadas

Necesito un contenedor transparente para una interfaz que a veces arroja excepciones comprobadas como IOException. ¿Es posible sin AOP de terceros o escribir mi propio proxy? La modificación manual de los 20 métodos de la interfaz tampoco es una opción.

Respuesta

10

Puede usar un proxy dinámico. Siempre que las excepciones marcadas sean parte de la interfaz, puede lanzar las excepciones marcadas desde el controlador de invocación. De lo contrario, esto es ilegal y creará una excepción de detección no detectable que envuelve la excepción comprobada arrojada.

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(); 

Salida:

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) 

Con una excepción no declarado comprobado para la interfaz R:

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 
+10

Gracias. Una nota, Method.invoke() (a menudo se usa en 'InvocationHandler.invoke()' envuelve la excepción original en 'InvocationTargetException', por lo que necesita ser desenvuelta. –

1

un proxy dinámico puede lanzar una excepción comprobado si la excepción se declara en la firma del método de la interfaz que está proxying. Desde el Dynamic Proxy reference del Sun:

Si el método de invocación arroja una excepción, también será invocado por el método en la instancia del proxy.

El tipo de la excepción debe ser asignable a cualquiera de los tipos de excepción declarados en la firma del método de interfaz o a los tipos de excepción sin marcar java.lang.RuntimeException o java.lang.Error.

Si se lanza una excepción marcada que no es asignable a ninguno de los tipos de excepción declarados en la cláusula throws del método de interfaz, se lanzará un UndeclaredThrowableException por la invocación del método en la instancia de proxy. El UndeclaredThrowableException se construirá con la excepción de que fue lanzado por el método de invocación.

17

Lo que probablemente está buscando es esto, como Konrad menciona arriba:

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 
    try { 
     Object value = method.invoke(delegate, args); 
     return value; 
    } 
    catch (InvocationTargetException ex) { 
     throw ex.getCause(); 
    } 
} 

Fuente: http://benpryor.com/blog/2006/08/15/java-dynamic-proxies-and-invocationtargetexception/

+0

el enlace al blog externo anterior se ha ido, pero por ejemplo https: //amitstechblog.wordpress.com/2011/07/24/java-proxies-and-undeclaredthrowableexception/ también tiene algunos comentarios sobre por qué es una buena idea hacer esto – vorburger

Cuestiones relacionadas