Эта новая конструкция Java 7 try-with-resources довольно приятная. Или, по крайней мере, было хорошо, пока не возникло исключение и не испортил мой день.
Наконец-то мне удалось свернуть его до воспроизводимого теста, который не использует ничего, кроме 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 генерирует то, что кажется незаконным кодом, что делает эту функцию непригодной для использования.
Конечно, когда тест проходит, проблем не возникает. И когда тест не выполняется, возникает исключение. Итак, теперь, когда я исправил проблему, которую я изначально обнаружил, я вернулся к использованию try-with-resources. Но в следующий раз, когда произойдет исключение, я предпочел бы скорее исключение ожидания, вместо того, чтобы одна Java сама испустила, по-видимому, не очень вескую причину.
Итак... есть ли способ получить правильное сообщение об ошибках здесь, не отказываясь от try-with-resources?