调试 API 修改
旧 API 与新 API 的主要区别在于应用程序需要同时实现 org.mozilla.javascript.debugger.Debugger 和 org.mozilla.javascript.debugger.DebugFrame 接口,以便在脚本执行期间接收调试信息。有关这些类的详细信息,请参阅 API 文档:
此外,org.mozilla.javascript.debugger.DebuggableEngine 接口和 org.mozilla.javascript.Context 中的 getDebuggableEngine 方法已被 Context 中的 3 个新方法替代:setDebugger、getDebugger 和 getDebuggerContextData,用于在当前线程上下文中设置/获取调试器及其上下文数据: org.mozilla.javascript.Context
以下提供了一些示例,说明如何将当前应用程序更新到新 API。
设置和查询 Debugger 实现
旧 API:
cx.getDebuggableEngine.setDebugger(debugger);
cx.getDebuggableEngine.getDebugger();
新 API:
cx.setDebugger(debugger);
cx.getDebugger();
监控脚本中每行的执行
旧实现:
public MyDebugger implement Debugger {
public void handleCompilationDone(Context cx,
DebuggableScript fnOrScript,
StringBuffer source)
{
}
void handleBreakpointHit(Context cx)
{
DebugFrame frame = cx.getDebuggableEngine().getFrame(0);
System.out.println("新行:" + frame.getLineNumber());
}
void handleExceptionThrown(Context cx, Object exception)
{
}
}
...
cx.getDebuggableEngine.setDebugger(new MyDebugger());
cx.getDebuggableEngine.setBreakNextLine(true);
新实现:
public MyDebugger implement Debugger
{
public void handleCompilationDone(Context cx,
DebuggableScript fnOrScript,
StringBuffer source)
{
}
public DebugFrame getFrame(Context cx, DebuggableScript fnOrScript)
{
return new MyDebugFrame();
}
}
class MyDebugFrame implements DebugFrame
{
public void onEnter(Context cx, Scriptable activation,
Scriptable thisObj, Object[] args)
{
}
public void onExceptionThrown(Context cx, Throwable ex)
{
}
public void onExit(Context cx, boolean byThrow,
Object resultOrException)
{
}
public void onLineChange(Context cx, int lineNumber)
{
System.out.println("新行:" + frame.getLineNumber());
}
}
...
cx.setDebugger(new MyDebugger());
注意,在新实现中,应用程序可以通过定制 enterFrame 和 onExit 来监控函数的进入和退出。
断点处理
旧实现:
public MyDebugger implement Debugger {
public void handleCompilationDone(Context cx, DebuggableScript fnOrScript,
StringBuffer source)
{
int breakpointLine = ...;
fnOrScript.placeBreakpoint(breakpointLine);
}
void handleBreakpointHit(Context cx) {
DebugFrame frame = cx.getDebuggableEngine().getFrame(0);
System.out.println("断点命中: "+frame.getSourceName()+":"+frame.getLineNumber());
}
void handleExceptionThrown(Context cx, Object exception)
{
}
}
...
cx.getDebuggableEngine.setDebugger(new MyDebugger());
新实现:
public MyDebugger implement Debugger
{
public void handleCompilationDone(Context cx,
DebuggableScript fnOrScript,
StringBuffer source)
{
}
public DebugFrame getFrame(Context cx, DebuggableScript fnOrScript)
{
return new MyDebugFrame(fnOrScript);
}
}
class MyDebugFrame implements DebugFrame
{
DebuggableScript fnOrScript;
MyDebugFrame(DebuggableScript fnOrScript)
{
this.fnOrScript = fnOrScript;
}
public void onEnter(Context cx, Scriptable activation,
Scriptable thisObj, Object[] args)
{
System.out.println("帧进入");
}
public void onLineChange(Context cx, int lineNumber)
{
if (isBreakpoint(lineNumber)) {
System.out.println("断点命中: "+fnOrScript.getSourceName()+":"+lineNumber);
}
}
public void onExceptionThrown(Context cx, Throwable ex)
{
}
public void onExit(Context cx, boolean byThrow,
Object resultOrException)
{
System.out.println("帧退出,结果="+resultOrException);
}
private boolean isBreakpoint(int lineNumber)
{
...
}
}
...
cx.setDebugger(new MyDebugger());
此处调试器在执行过程中需要决定特定行是否已经设置了断点,而不是在脚本初始化时决定。 另请参阅 Rhino 调试器,它可以充分利用新 API。调试器更新包括支持调试 eval 和 Function 脚本以及在脚本未初始化时从其 URL 加载脚本源码。