解释时获取 Nashorn 脚本行号
Get Nashorn script line number during interpretation
我的代码使用 Nashorn 为用户提供脚本功能,许多 类 和在 Java 上实现的功能通过 Nashorn 暴露给脚本。
程序的任务之一当然是在遇到任何与脚本相关的错误时向用户报告。如果出现 ScriptException
,这非常简单,只需捕获异常并使用方法 getLineNumber()
returns 正确的值即可。然而,偶尔会发生异常,不是由于语法,而是由于调用 Java 端代码的方式,例如由于本应是有效对象的 null 参数。这些会导致其他类型的异常,仍然可以在对 eval
方法的调用周围捕获,但由于这些没有 getLineNumber()
方法,因此无法猜测解释器的位置。
有什么方法可以从 Nashorn 引擎获取最后执行的行吗?
代码大致如下:
try {
engine.eval( script);
// successful
return -1;
} catch ( ScriptException e)
{
// the ScriptException reports the line number
return e.getLineNumber();
}
catch ( Exception e)
{
// is it possible to get the line number here too?
// ...
return lineNumber;
}
您可以遍历异常堆栈,找到 class 名称以 jdk.nashorn.internal.scripts.
开头的第一个 StackTraceElement
并报告其行号:
for(StackTraceElement ste: e.getStackTrace()) {
if (ste.getClassName().startsWith("jdk.nashorn.internal.scripts.")) {
return ste.getLineNumber();
}
}
return -1; // couldn't figure it out
如果 ste.getFileName().endsWith(".js")
更适合您的情况,您也可以尝试使用 ste.getFileName().endsWith(".js")
。
有一个标准的 Nashorn API 可以从给定的任意 Throwable 对象中获取 "script frames" 的 StackTraceElement[]。
jdk.nashorn.api.scripting.NashornException class 有
public static StackTraceElement[] getScriptFrames(可抛异常)
方法
您可以传递任意 Throwable 对象并返回脚本框架的 StackTraceElement 数组。最顶部的脚本框架将是数组的第零个元素,您可以在 StackTraceElement 对象上调用 getLineNumber。
这样,您就可以避免对 nashorn 内部包前缀的依赖。
我的代码使用 Nashorn 为用户提供脚本功能,许多 类 和在 Java 上实现的功能通过 Nashorn 暴露给脚本。
程序的任务之一当然是在遇到任何与脚本相关的错误时向用户报告。如果出现 ScriptException
,这非常简单,只需捕获异常并使用方法 getLineNumber()
returns 正确的值即可。然而,偶尔会发生异常,不是由于语法,而是由于调用 Java 端代码的方式,例如由于本应是有效对象的 null 参数。这些会导致其他类型的异常,仍然可以在对 eval
方法的调用周围捕获,但由于这些没有 getLineNumber()
方法,因此无法猜测解释器的位置。
有什么方法可以从 Nashorn 引擎获取最后执行的行吗?
代码大致如下:
try {
engine.eval( script);
// successful
return -1;
} catch ( ScriptException e)
{
// the ScriptException reports the line number
return e.getLineNumber();
}
catch ( Exception e)
{
// is it possible to get the line number here too?
// ...
return lineNumber;
}
您可以遍历异常堆栈,找到 class 名称以 jdk.nashorn.internal.scripts.
开头的第一个 StackTraceElement
并报告其行号:
for(StackTraceElement ste: e.getStackTrace()) {
if (ste.getClassName().startsWith("jdk.nashorn.internal.scripts.")) {
return ste.getLineNumber();
}
}
return -1; // couldn't figure it out
如果 ste.getFileName().endsWith(".js")
更适合您的情况,您也可以尝试使用 ste.getFileName().endsWith(".js")
。
有一个标准的 Nashorn API 可以从给定的任意 Throwable 对象中获取 "script frames" 的 StackTraceElement[]。
jdk.nashorn.api.scripting.NashornException class 有
public static StackTraceElement[] getScriptFrames(可抛异常)
方法
您可以传递任意 Throwable 对象并返回脚本框架的 StackTraceElement 数组。最顶部的脚本框架将是数组的第零个元素,您可以在 StackTraceElement 对象上调用 getLineNumber。
这样,您就可以避免对 nashorn 内部包前缀的依赖。