到底什么是“不允许自我压制"?为什么Javac会生成导致此错误的代码? [英] What on earth is "Self-suppression not permitted" and why is Javac generating code which results in this error?

查看:950
本文介绍了到底什么是“不允许自我压制"?为什么Javac会生成导致此错误的代码?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个新的Java 7 try-with-resources构造非常好.或者至少, 很好,直到出现异常情况并破坏了我的一天.

This new Java 7 try-with-resources construct is quite nice. Or at least, it was nice until an exception came along and ruined my day.

我终于设法将其简化为可重现的测试,该测试只使用JUnit + jMock.

I've finally managed to boil it down to a reproducible test which uses nothing but JUnit+jMock.

@Test
public void testAddSuppressedIssue() throws Exception {
    Mockery mockery = new Mockery();
    final Dependency dependency = mockery.mock(Dependency.class);

    mockery.checking(new Expectations() {{
        allowing(dependency).expectedCall();
        allowing(dependency).close();
    }});

    try (DependencyUser user = new DependencyUser(dependency)) {
        user.doStuff();
    }
}

// A class we're testing.
private static class DependencyUser implements Closeable {
    private final Dependency dependency;

    private DependencyUser(Dependency dependency) {
        this.dependency = dependency;
    }

    public void doStuff() {
        dependency.unexpectedCall(); // bug
    }

    @Override
    public void close() throws IOException {
        dependency.close();
    }
}

// Interface for its dependent component.
private static interface Dependency extends Closeable {
    void expectedCall();
    void unexpectedCall();
}

运行此示例,我得到:

java.lang.IllegalArgumentException: Self-suppression not permitted
    at java.lang.Throwable.addSuppressed(Throwable.java:1042)
    at com.acme.Java7FeaturesTest.testTryWithResources(Java7FeaturesTest.java:35)

在阅读文档时,他们似乎在说,如果您要向自身添加抑制的异常,则将触发此错误.但是,我不是这样做,我是只是使用try-with-resources块.然后, Java编译器会生成看似非法的代码,从而使该功能实际上无法使用.

Reading the documentation, they seem to be saying that if you were to add a suppressed exception back to itself, that is what triggers this error. But I'm not doing that, I'm just using a try-with-resources block. The Java compiler then generates what would seem to be illegal code, which makes the feature effectively unusable.

当然,当测试通过时,不会出现问题.当测试失败时,将发生异常.因此,既然我已经解决了最初发现的问题,我就恢复了使用try-with-resources的权限.但是,下次发生异常时,我宁愿将异常作为期望失败,而不是看似没有充分的理由发出一个Java本身.

Of course, when the test passes, no problem occurs. And when the test fails, an exception occurs. So now that I have fixed the problem I originally discovered I have reverted to using try-with-resources. But next time an exception occurs, I would much rather the exception be the expectation failure, instead of one Java itself has emitted for seemingly no good reason.

所以...有没有办法在这里获得正确的错误报告,而又不放弃尝试资源的问题?

So... is there a way to get proper error reporting here, without giving up on try-with-resources?

推荐答案

看起来jMock从这两个方法中抛出相同的异常实例.这就是不用jMock可以复制它的方式:

It looks like jMock throws the same instance of exception from the both methods. That's how it can be reproduced without jMock:

public class Test implements Closeable {
    private RuntimeException ex = new RuntimeException();

    public void doStuff() {
        throw ex;
    }

    public void close() {
        throw ex;
    }
}

try (Test t = new Test()) {
    t.doStuff();
}

如果是这样,我认为这是jMock的问题,而不是Java编译器的问题.

If so, I think it's a problem of jMock rather than of Java compiler.

这篇关于到底什么是“不允许自我压制"?为什么Javac会生成导致此错误的代码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆