2010-12-02 6 views
5

¿Es posible escribir código de bytes para un método que se supone arrojar una excepción marcada?¿Cómo el código de bytes generado por scala cae la excepción marcada?

Por ejemplo, la siguiente clase Java no compila menos que el método declara que lanza la excepción comprobada:

public class CheckedExceptionJava { 
    public Class<?> testChecked(String s) throws ClassNotFoundException { 
    return Class.forName(s); 
    } 
} 

Aunque la siguiente equivalente Scala hace (porque Scala no haber comprobado excepciones):

class CheckedException { 
    def testChecked(s : String) = Class.forName(s) 
} 

Incluso si el código de bytes generados son casi idénticos:

Compiled from "CheckedExceptionJava.java" 
public class CheckedExceptionJava extends java.lang.Object{ 
public CheckedExceptionJava(); 
    Code: 
    0: aload_0 
    1: invokespecial #1; //Method java/lang/Object."<init>":()V 
    4: return 

public java.lang.Class testChecked(java.lang.String) throws java.lang.ClassNotFoundException; 
    Code: 
    0: aload_1 
    1: invokestatic #2; //Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class; 
    4: areturn 

} 

Compiled from "CheckedException.scala" 
public class CheckedException extends java.lang.Object implements scala.ScalaObject{ 
public CheckedException(); 
    Code: 
    0: aload_0 
    1: invokespecial #24; //Method java/lang/Object."<init>":()V 
    4: return 

public java.lang.Class testChecked(java.lang.String); 
    Code: 
    0: aload_1 
    1: invokestatic #11; //Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class; 
    4: areturn 

} 

Pregunta: ¿Es posible (y cómo) generar bytecode para que no marque arrojar una excepción marcada incluso si el código dentro de ese método no lo maneja?

Respuesta

13

Simple. Si bien el bytecode de JVM incluye especificaciones de excepción comprobadas en los métodos, el verificador de bytecode que se ejecuta antes de que se ejecute específicamente un bytecode no verifica que los métodos realmente cumplan con las especificaciones de excepción. Podría escribir un programa que tomara el bytecode de JVM existente y eliminara todas las especificaciones de excepción, y el bytecode resultante sería perfectamente válido y se ejecutaría de forma idéntica al original (excepto la reflexión).

+0

Ohhh veo. ¿Probablemente con una herramienta como javassist? :) http://bit.ly/gNzXfA – OscarRyz

Cuestiones relacionadas