7

私は、他の点では非常に便利なJSR223スクリプト環境とは何かという汚い小さな秘密に出くわし始めています。

Java 6 SEに同梱されているRhinoの組み込みバージョンを使用しており、JSR223などを介してアクセスしていScriptingEngineます。

Javascript環境にエクスポートしたJavaオブジェクトが原因で例外が発生した場合、それは私の実際の例外(例など)ScriptingExceptionをラップするものです。sun.org.mozilla.javascript.internal.WrappedExceptionUnsupportedOperationException

getFileName()のScriptingException場合はnullを返し、getLineNumber()の場合は-1を返します。しかし、メッセージとデバッガーを見ると、WrappedExceptionファイル名と行番号が正しいので、ScriptingExceptionのgetterメソッドを介してメッセージを公開していません。

素晴らしい。今、私は何をしますか?とにかくパブリッククラスではないsun.org.mozilla.javascript.internal.wrappedExceptionをどのように使用するのかわかりません。

4

1 に答える 1

1

ああ。sun.org.mozilla.javascript.internal.EvaluatorExceptionJava 6のRhinoは、他の例外の数を知っている人と同じことを行います(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;
}
于 2011-04-06T14:23:04.613 に答える