reasonable handling of ScriptException thrown by JSR223 Rhino

寵の児 提交于 2019-12-22 04:56:11

问题


I'm starting to run into the dirty little secrets of what is an otherwise very useful JSR223 scripting environment.

I'm using the builtin version of Rhino shipped with Java 6 SE, accessing it through JSR223's ScriptingEngine et al.

When I get an exception caused by a Java object I've exported into the Javascript environment, it is a ScriptingException that wraps a sun.org.mozilla.javascript.internal.WrappedException that wraps my real exception (e.g. UnsupportedOperationException or whatever)

The ScriptingException returns null for getFileName() and -1 for getLineNumber(). But when I look at the message and at the debugger, the WrappedException has the correct filename and line number, it's just not publishing it via the ScriptingException's getter methods.

Great. Now what do I do? I don't know how I'm going to use sun.org.mozilla.javascript.internal.wrappedException which isn't a public class anyway.


回答1:


Argh. Java 6's Rhino does the same thing (doesn't publish the file name / line number / etc via ScriptingException's methods) with sun.org.mozilla.javascript.internal.EvaluatorException and who knows how many other exceptions.

The only reasonable way I can think of to handle this is to use reflection. Here's my solution.

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;
}


来源:https://stackoverflow.com/questions/5557113/reasonable-handling-of-scriptexception-thrown-by-jsr223-rhino

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!