繁体   English   中英

如何检测字节代码以告知何时执行catch子句?

[英]How to instrument the byte code to tell when a catch clause is being executed?

基于布雷特·沃克Brett Walker )对这个问题的评论,我想知道如何做到这一点。

“如果您想使单元测试失败,那么从最一般的意义上讲,当使用此方法的代码执行catch子句时,您将必须检测字节码以告诉您何时执行catch子句。这是一项复杂的任务。我不建议这样做。”

如何测试某些方法已执行catch子句? (以下示例中的isCatched()

假设我有以下课程:

public class A {
  public void method() {
    try {
      // some code that may or may not throw an exception
    } catch(Exception e) {
      // do nothing
    }
  }
}

然后在其他地方:

public class CatchTester {
  private A a;
  public CatchTester(A a) {
    this.a = a;
  }
  public boolean isCatched() {
    // how to do this?
  }
}

有两种方法,两种方法都需要有关如何操作Java字节码的知识。 存在诸如ASM之类的工具,这些工具使操作字节码变得更加容易。 然后,可以连接Java代理或编写自定义类加载器,以在将类字节加载到JVM时对其进行修改。

https://github.com/google/allocation-instrumenter就是这种方法的一个很好的例子。 Allocation-Instrumenter修改类的字节码,以便可以注册一个回调方法,该回调方法在对象分配发生时被调用。 可以想象有一个类似的库用于try / catch工具,这并不是一件容易的事。

如果要通过工具检测是否已执行某些代码,则必须修改该代码,注入某种日志记录代码,这将有效地调用一种方法来记录该代码已被命中的事实。 然后,您可以检查检查的方法返回后是否立即存在这样的记录。

尽管在每个异常处理程序的开始处插入这样的日志记录代码并不难,但存在一个问题,在字节码级别上,没有对catchfinallytry(…)子句进行区分。 它们都以定义异常处理程序结尾,其中一些可能会重新引发捕获的异常。 如果要排除重新引发异常的处理程序,则必须跟踪每个可能的代码路径,从异常处理程序的条目开始,检查它是否以正常完成结尾或引发异常,无论是捕获的异常还是另一个新构造的异常。

如果您只想知道是否已执行任何 catch子句,则情况要简单得多。 如果在method()的执行过程中引发了异常,但method()正常完成,即调用者未收到该异常,则必须执行了异常处理程序。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM