Skip to content

Commit 251ba53

Browse files
committed
OAK-11571: commons: add Closer class (similar to Guava Closer) - rethrow() just silences the close() method
1 parent 72f5375 commit 251ba53

File tree

2 files changed

+37
-19
lines changed
  • oak-commons/src

2 files changed

+37
-19
lines changed

oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/pio/Closer.java

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,7 @@ private Closer() {
4242
private final Deque<Closeable> closeables = new ArrayDeque<>();
4343

4444
// set by rethrow method
45-
private Throwable rethrow = null;
46-
45+
private boolean suppressExceptionsOnClose = false;
4746
/**
4847
* Create instance of Closer.
4948
*/
@@ -90,33 +89,23 @@ public void close() throws IOException {
9089
}
9190
}
9291

93-
// consider exceptions passed to rethrow()
94-
if (rethrow instanceof IOException) {
95-
throw (IOException) rethrow;
96-
} else if (rethrow instanceof RuntimeException) {
97-
throw (RuntimeException) rethrow;
98-
} else if (rethrow != null) {
99-
throw new RuntimeException(rethrow);
100-
}
101-
102-
// otherwise throw the IOException we selected
103-
if (toThrow != null) {
92+
// potential IOException is suppressed when retrow was called
93+
if (!suppressExceptionsOnClose && toThrow != null) {
10494
throw toThrow;
10595
}
10696
}
10797

10898
/**
109-
* Stores a {@link Throwable} for later use in {@link #close()} and
110-
* rethrows it (potentially wrapped into {@link RuntimeException} or
111-
* {@link Error}).
99+
* Sets a flag indicating that this method was called, then rethrows the
100+
* given exception.
112101
* <p>
113-
* {@link #close()} will use the exception passed in the last call of this
114-
* method.
102+
* {@link #close()} will not throw when this method was called before.
115103
* @return never returns
116104
* @throws IOException wrapping the input, when needed
117105
*/
118106
public RuntimeException rethrow(@NotNull Throwable throwable) throws IOException {
119-
rethrow = Objects.requireNonNull(throwable);
107+
Objects.requireNonNull(throwable);
108+
suppressExceptionsOnClose = true;
120109
if (throwable instanceof IOException) {
121110
throw (IOException) throwable;
122111
} else if (throwable instanceof RuntimeException) {

oak-commons/src/test/java/org/apache/jackrabbit/oak/commons/pio/CloserTest.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import java.util.concurrent.atomic.AtomicBoolean;
2828

2929
import static org.junit.Assert.assertEquals;
30+
import static org.junit.Assert.assertNull;
3031
import static org.junit.Assert.assertThrows;
3132
import static org.junit.Assert.assertTrue;
3233
import static org.junit.Assert.fail;
@@ -151,4 +152,32 @@ public void testRethrowChecked() throws IOException {
151152
ex.getCause() instanceof InterruptedException);
152153
}
153154
}
155+
156+
@Test
157+
public void compareClosers() {
158+
// when rethrow was called, IOExceptions that happened upon close will be swallowed
159+
160+
com.google.common.io.Closer guavaCloser = com.google.common.io.Closer.create();
161+
Closer oakCloser = Closer.create();
162+
163+
try {
164+
throw oakCloser.rethrow(new InterruptedException());
165+
} catch (Exception e) {}
166+
167+
try {
168+
throw guavaCloser.rethrow(new InterruptedException());
169+
} catch (Exception e) {}
170+
171+
try {
172+
oakCloser.close();
173+
} catch (Exception e) {
174+
fail("should not throw but got: " + e);
175+
}
176+
177+
try {
178+
guavaCloser.close();
179+
} catch (Exception e) {
180+
fail("should not throw but got: " + e);
181+
}
182+
}
154183
}

0 commit comments

Comments
 (0)