Byteman JUnit Runner-无法在自动关闭的InputStream#close上触发IOException

Byteman JUnit Runner-无法在自动关闭的InputStream#close上触发IOException,junit,java-7,try-with-resources,byteman,Junit,Java 7,Try With Resources,Byteman,我有以下代码: Collection<String> errors = ...; try (InputStream stream = My.class.getResourceAsStream(resource)) { // do stuff } catch(IOException ex) { errors.add("Fail"); } 收集错误=。。。; try(InputStream=My.class.getResourceAsStream(资源)){ //做事 }

我有以下代码:

Collection<String> errors = ...;
try (InputStream stream = My.class.getResourceAsStream(resource)) {
   // do stuff
}
catch(IOException ex) {
   errors.add("Fail");
}
收集错误=。。。; try(InputStream=My.class.getResourceAsStream(资源)){ //做事 } 捕获(IOEX异常){ 错误。添加(“失败”); } 我正在尝试使用Byteman Junit Runner在我提供的(有效)输入流假定已关闭时触发IOException:

@RunWith(BMUnitRunner.class)
public class MyTest {

    private My my = new My();

    @BMRule(
       name = "force_read_error",
       targetClass = "java.io.InputStream",
       targetMethod = "close()",
       action = "throw new IOException(\"bazinga\")"
    )
    @Test
    public void catches_read_error() throws IOException {
       Collection<String> errors = my.foo("/valid-resource-in-classpath");

       assertThat(errors).containsExactly("Fail");
    }
}
@RunWith(BMUnitRunner.class)
公共类MyTest{
private My=new My();
@BMRule(
name=“强制读取错误”,
targetClass=“java.io.InputStream”,
targetMethod=“close()”,
action=“抛出新IOException(\“bazinga\”)
)
@试验
public void捕获\u read\u error()引发IOException{
集合错误=my.foo(“/valid resource in classpath”);
资产(错误)。实际包含(“失败”);
}
}
我的测试失败:错误总是空的,这意味着Byteman规则显然没有被执行(代理加载得很好,所以我不知道发生了什么)


如何在通过try with resources调用的close方法上触发IOException?

您的规则没有触发,因为调用时收到的流对象的类

InputStream stream = My.class.getResourceAsStream(resource)
不是“java.io.InputStream”类。它是一个扩展了“java.io.InputStream”的类,很可能是一个“BufferedInputStream”

要让byteman“为任何扩展java.io.InputStream的类触发规则”,您需要在类名前加一个“^”:

targetClass = "^java.io.InputStream"
此更改可能会产生不必要的副作用,即当扩展“java.io.InputStream”的其他对象关闭时,也会触发该规则。为了防止这种情况发生,应该在规则中添加一个条件,使其仅在调用方匹配“My”类的“foo”方法时触发。Byteman有一个名为“callerMatches”()的助手方法

您的案例的工作条件为:

condition = "callerMatches(\".+My.foo\",true,true)"
作为BMRule注释的完整Byteman规则定义应如下所示:

@BMRule(
    name = "force_read_error",
    targetClass = "^java.io.InputStream",
    targetMethod = "close()",
    condition = "callerMatches(\".+My.foo\",true,true)",
    action = "throw new java.io.IOException(\"bazinga\")"
)