2011-04-05 16 views
7

Estoy empezando a toparme con los pequeños y sucios secretos de lo que es un entorno de scripts JSR223 muy útil.manejo razonable de ScriptException lanzado por JSR223 Rhino

Estoy utilizando la versión integrada de Rhino enviada con Java 6 SE, accediendo a ella a través de ScriptingEngine de JSR223 y otros.

Cuando llego a una excepción causada por un objeto Java que he exportado en el medio ambiente Javascript, que es una ScriptingException que envuelve un sun.org.mozilla.javascript.internal.WrappedException que envuelve mi verdadera excepción (por ejemplo UnsupportedOperationException o lo que sea)

Los ScriptingException devuelva null para getFileName() y -1 para getLineNumber(). Pero cuando miro el mensaje y en el depurador, el WrappedException tiene el nombre de archivo y número de línea correctos, simplemente no lo está publicando a través de los métodos getter de ScriptingException.

Genial. ¿Ahora qué hago? No sé cómo voy a usar sun.org.mozilla.javascript.internal.wrappedException que no es una clase pública de todos modos.

Respuesta

1

Argh. Rhino de Java 6 hace lo mismo (no publica el nombre de archivo/número de línea/etc. a través de los métodos de ScriptingException) con sun.org.mozilla.javascript.internal.EvaluatorException y quién sabe cuántas otras excepciones.

La única manera razonable que se me ocurre para manejar esto es usar la reflexión. Aquí está mi solución.

void handleScriptingException(ScriptingException se) 
{ 
    final Throwable t1 = se.getCause(); 
    String lineSource = null; 
    String filename = null; 
    Integer lineNumber = null; 

    if (hasGetterMethod(t1, "sourceName")) 
    { 
     lineNumber = getProperty(t1, "lineNumber", Integer.class); 
     filename = getProperty(t1, "sourceName", String.class); 
     lineSource = getProperty(t1, "lineSource", String.class); 
    } 
    else 
    { 
     filename = se.getFileName(); 
     lineNumber = se.getLineNumber(); 
    } 
    /* do something with this info */ 
} 

static private Method getGetterMethod(Object object, String propertyName) 
{ 
    String methodName = "get"+getBeanSuffix(propertyName); 
    try { 
     Class<?> cl = object.getClass(); 
     return cl.getMethod(methodName); 
    } 
    catch (NoSuchMethodException e) { 
     return null; 
     /* gulp */ 
    } 
} 
static private String getBeanSuffix(String propertyName) { 
    return propertyName.substring(0,1).toUpperCase() 
     +propertyName.substring(1); 
} 
static private boolean hasGetterMethod(Object object, String propertyName) 
{ 
    return getGetterMethod(object, propertyName) != null; 
} 
static private <T> T getProperty(Object object, String propertyName, 
     Class<T> cl) { 
    try { 
     Object result = getGetterMethod(object, propertyName).invoke(object); 
     return cl.cast(result); 
    } 
    catch (Exception e) { 
     e.printStackTrace(); 
    } 
    return null; 
} 
Cuestiones relacionadas