有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

GraalVM中的java异常链

我使用GraalVM来执行JavaScript文件,但在异常处理方面遇到了问题。我的JS代码将调用返回Java,如果从这些Java方法中的一个抛出异常,那么我将丢失原因链

public class Example {
    public static void doSomething() {
        throw new RuntimeException("Example", new RuntimeException("Some nested exception"));
    }
}

// --------------

var Example = Java.type("ex.Example");
function f() {
    Example.doSomething();
}

// -------------

String src = ... 
Source s = Source.newBuilder("js", src, "example").build();
try {
    context.eval(s);
} catch (PolyglotException e) {
    e.printStackTrace(); // This only prints the PolyglotException with the message "Example"
}

之所以会发生这种情况,是因为Graal/Truffle生成了一个HostException的实例,该实例有一个不调用super(e)的构造函数,它将它分配给一个内部字段,该字段用于获取消息,而没有其他内容。这似乎是故意的,但我不明白原因。这是安全问题吗?你能想个办法改变这种行为吗?我非常希望在我的日志中可以找到异常的全部原因,但此时它会停在HostException,这通常只是说类似于“A”(例如,如果错误的原始原因是NoSuchElementException("A")

final class HostException extends RuntimeException implements TruffleException {

    private final Throwable original;

    HostException(Throwable original) {
        this.original = original;
    }

    Throwable getOriginal() {
        return original;
    }

    @Override
    public String getMessage() {
        return getOriginal().getMessage();
    }

    @Override
    public synchronized Throwable fillInStackTrace() {
        return this;
    }

    public Node getLocation() {
        return null;
    }

    public boolean isCancelled() {
        return getOriginal() instanceof InterruptedException;
    }

}

共 (1) 个答案

  1. # 1 楼答案

    我也遇到过同样的问题,结果证明,JS错误具有以下功能:

    printStackTrace: [Function],
    fillInStackTrace: [Function],
    getCause: [Function],
    initCause: [Function],
    toString: [Function],
    getMessage: [Function],
    getLocalizedMessage: [Function],
    getStackTrace: [Function],
    setStackTrace: [Function],
    addSuppressed: [Function],
    getSuppressed: [Function]
    

    printStackTrace例如,打印java堆栈跟踪:

    try {
        Java.type('ClassWithException').throwRuntimeEx();
    } catch (e) {
        console.log(e.printStackTrace())
    }
    

    提供以下信息:

    java.lang.RuntimeException: Example message
    at ex.ClassWithException.throwRuntimeEx(ClassWithException.java:6)
    at com.oracle.truffle.polyglot.HostMethodDesc$SingleMethod$MHBase.invokeHandle(HostMethodDesc.java:269)
    at com.oracle.truffle.polyglot.HostMethodDesc$SingleMethod$MHBase.invoke(HostMethodDesc.java:261)
    at com.oracle.truffle.polyglot.HostExecuteNode$1.executeImpl(HostExecuteNode.java:776)
    at com.oracle.truffle.polyglot.GuestToHostRootNode.execute(GuestToHostRootNode.java:87)
    at org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.callProxy(OptimizedCallTarget.java:328)
    ...
    at com.oracle.truffle.polyglot.PolyglotValue$InteropValue.execute(PolyglotValue.java:2008)
    at org.graalvm.polyglot.Value.execute(Value.java:338)
    at com.oracle.truffle.trufflenode.GraalJSAccess.isolateEnterPolyglotEngine(GraalJSAccess.java:2629)
    Caused by: java.lang.RuntimeException: Inner exception
    ... 245 more