JSR223 Rhino抛出的ScriptException的合理处理

发布于 2024-10-31 01:34:01 字数 618 浏览 4 评论 0原文

我开始遇到一个本来非常有用的 JSR223 脚本环境的肮脏小秘密。

我使用 Java 6 SE 附带的内置版本的 Rhino,通过 JSR223 的 ScriptingEngine 等访问它。

当我收到由导出到 Javascript 环境的 Java 对象引起的异常时,它是包装 sun.org.mozilla.javascript.internal.WrappedExceptionScriptingException > 包装了我真正的异常(例如 UnsupportedOperationException 或其他)

ScriptingException 对于 getFileName() 返回 null,对于 getLineNumber() 返回 -1。 但是,当我查看消息和调试器时,WrappedException 具有正确的文件名和行号,它只是没有通过 ScriptingException 的 getter 方法发布它。

伟大的。 现在我该怎么办?我不知道如何使用 sun.org.mozilla.javascript.internal.wrappedException ,它无论如何都不是公共类。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

未蓝澄海的烟 2024-11-07 01:34:01

啊。 Java 6 的 Rhino 使用 sun.org.mozilla.javascript.internal.EvaluatorException 做了同样的事情(不通过 ScriptingException 的方法发布文件名/行号/等),谁知道还有多少其他异常。

我能想到的处理这个问题的唯一合理方法是使用反射。这是我的解决方案。

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

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文