diff options
10 files changed, 101 insertions, 50 deletions
diff --git a/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/ProxyProtocolTest.java b/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/ProxyProtocolTest.java index d4d6dcee957..42ce0284602 100644 --- a/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/ProxyProtocolTest.java +++ b/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/ProxyProtocolTest.java @@ -27,7 +27,7 @@ import java.util.logging.Level; import java.util.logging.Logger; import static com.yahoo.jdisc.http.server.jetty.Utils.generatePrivateKeyAndCertificate; -import static com.yahoo.yolean.Exceptions.uncheckInterrupted; +import static com.yahoo.yolean.Exceptions.uncheck; import static org.eclipse.jetty.client.ProxyProtocolClientConnectionFactory.V1; import static org.eclipse.jetty.client.ProxyProtocolClientConnectionFactory.V2; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -221,7 +221,7 @@ class ProxyProtocolTest { private static void assertLogSize(int expectedItems, Collection<?> items) { for (int attempt = 0; attempt < 10; attempt++) { if (items.size() >= expectedItems) break; - uncheckInterrupted(() -> Thread.sleep(200)); + uncheck(() -> Thread.sleep(200)); } Assertions.assertThat(items).hasSize(expectedItems); } diff --git a/container-search/src/test/java/com/yahoo/search/handler/SearchHandlerTest.java b/container-search/src/test/java/com/yahoo/search/handler/SearchHandlerTest.java index b1354106f19..34b838f996c 100644 --- a/container-search/src/test/java/com/yahoo/search/handler/SearchHandlerTest.java +++ b/container-search/src/test/java/com/yahoo/search/handler/SearchHandlerTest.java @@ -36,7 +36,7 @@ import java.io.IOException; import java.net.URI; import java.util.concurrent.Executors; -import static com.yahoo.yolean.Exceptions.uncheckInterrupted; +import static com.yahoo.yolean.Exceptions.uncheck; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotSame; @@ -306,7 +306,7 @@ public class SearchHandlerTest { private void assertMetricPresent(String key) { for (int i = 0; i < 200; i++) { if (metric.metrics().containsKey(key)) return; - uncheckInterrupted(() -> Thread.sleep(1)); + uncheck(() -> Thread.sleep(1)); } fail(String.format("Could not find metric with key '%s' in '%s'", key, metric)); } diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/IOExceptionUtil.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/IOExceptionUtil.java index 1f757bd6aba..f43995602fa 100644 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/IOExceptionUtil.java +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/IOExceptionUtil.java @@ -7,8 +7,6 @@ import java.io.UncheckedIOException; import java.nio.file.NoSuchFileException; import java.util.Optional; -import static com.yahoo.yolean.Exceptions.uncheck; - /** * Utils related to IOException. * @@ -19,9 +17,9 @@ public class IOExceptionUtil { * Useful if it's not known whether a file or directory exists, in case e.g. * NoSuchFileException is thrown and the caller wants an Optional.empty() in that case. */ - public static <T> Optional<T> ifExists(Exceptions.SupplierThrowingIOException<T> supplier) { + public static <T> Optional<T> ifExists(Exceptions.SupplierThrowingException<T> supplier) { try { - return Optional.ofNullable(uncheck(supplier)); + return Optional.ofNullable(Exceptions.uncheck(supplier)); } catch (UncheckedIOException e) { if (e.getCause() instanceof NoSuchFileException) { return Optional.empty(); diff --git a/vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/resource/DocumentV1ApiHandler.java b/vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/resource/DocumentV1ApiHandler.java index 73bea9f7a00..34200a2393d 100644 --- a/vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/resource/DocumentV1ApiHandler.java +++ b/vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/resource/DocumentV1ApiHandler.java @@ -3,8 +3,8 @@ package com.yahoo.document.restapi.resource; import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.core.JsonGenerator; -import com.yahoo.component.annotation.Inject; import com.yahoo.cloud.config.ClusterListConfig; +import com.yahoo.component.annotation.Inject; import com.yahoo.concurrent.DaemonThreadFactory; import com.yahoo.concurrent.SystemTimer; import com.yahoo.container.core.HandlerMetricContextUtil; @@ -69,7 +69,7 @@ import com.yahoo.text.Text; import com.yahoo.vespa.config.content.AllClustersBucketSpacesConfig; import com.yahoo.vespa.http.server.MetricNames; import com.yahoo.yolean.Exceptions; -import com.yahoo.yolean.Exceptions.RunnableThrowingIOException; +import com.yahoo.yolean.Exceptions.RunnableThrowingException; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -850,7 +850,7 @@ public class DocumentV1ApiHandler extends AbstractRequestHandler { }); } - private static void loggingException(RunnableThrowingIOException runnable) { + private static void loggingException(RunnableThrowingException runnable) { try { runnable.run(); } diff --git a/yolean/abi-spec.json b/yolean/abi-spec.json index 8c10006e7e1..568535fbf39 100644 --- a/yolean/abi-spec.json +++ b/yolean/abi-spec.json @@ -1,5 +1,5 @@ { - "com.yahoo.yolean.Exceptions$RunnableThrowingIOException": { + "com.yahoo.yolean.Exceptions$RunnableThrowingException": { "superClass": "java.lang.Object", "interfaces": [], "attributes": [ @@ -25,7 +25,7 @@ ], "fields": [] }, - "com.yahoo.yolean.Exceptions$SupplierThrowingIOException": { + "com.yahoo.yolean.Exceptions$SupplierThrowingException": { "superClass": "java.lang.Object", "interfaces": [], "attributes": [ @@ -48,25 +48,38 @@ "public void <init>()", "public static java.lang.String toMessageString(java.lang.Throwable)", "public static java.util.Optional findCause(java.lang.Throwable, java.lang.Class)", - "public static void uncheck(com.yahoo.yolean.Exceptions$RunnableThrowingIOException)", + "public static void uncheck(com.yahoo.yolean.Exceptions$RunnableThrowingException)", "public static void uncheckInterrupted(com.yahoo.yolean.Exceptions$RunnableThrowingInterruptedException)", "public static void uncheckInterruptedAndRestoreFlag(com.yahoo.yolean.Exceptions$RunnableThrowingInterruptedException)", - "public static varargs void uncheck(com.yahoo.yolean.Exceptions$RunnableThrowingIOException, java.lang.String, java.lang.String[])", - "public static void uncheckAndIgnore(com.yahoo.yolean.Exceptions$RunnableThrowingIOException, java.lang.Class)", - "public static java.lang.Object uncheck(com.yahoo.yolean.Exceptions$SupplierThrowingIOException)", - "public static varargs java.lang.Object uncheck(com.yahoo.yolean.Exceptions$SupplierThrowingIOException, java.lang.String, java.lang.String[])", - "public static java.lang.Object uncheckAndIgnore(com.yahoo.yolean.Exceptions$SupplierThrowingIOException, java.lang.Class)", + "public static varargs void uncheck(com.yahoo.yolean.Exceptions$RunnableThrowingException, java.lang.String, java.lang.String[])", + "public static void uncheckAndIgnore(com.yahoo.yolean.Exceptions$RunnableThrowingException, java.lang.Class)", + "public static java.lang.Object uncheck(com.yahoo.yolean.Exceptions$SupplierThrowingException)", + "public static varargs java.lang.Object uncheck(com.yahoo.yolean.Exceptions$SupplierThrowingException, java.lang.String, java.lang.String[])", + "public static java.lang.Object uncheckAndIgnore(com.yahoo.yolean.Exceptions$SupplierThrowingException, java.lang.Class)", "public static java.lang.RuntimeException throwUnchecked(java.lang.Throwable)" ], "fields": [] }, - "com.yahoo.yolean.UncheckedInterruptedException": { + "com.yahoo.yolean.UncheckedException": { "superClass": "java.lang.RuntimeException", "interfaces": [], "attributes": [ "public" ], "methods": [ + "public void <init>(java.lang.String, java.lang.Exception)", + "public void <init>(java.lang.Exception)", + "public void <init>(java.lang.String)" + ], + "fields": [] + }, + "com.yahoo.yolean.UncheckedInterruptedException": { + "superClass": "com.yahoo.yolean.UncheckedException", + "interfaces": [], + "attributes": [ + "public" + ], + "methods": [ "public void <init>(java.lang.String, java.lang.InterruptedException, boolean)", "public void <init>(java.lang.InterruptedException, boolean)", "public void <init>(java.lang.String, boolean)", diff --git a/yolean/src/main/java/com/yahoo/yolean/Exceptions.java b/yolean/src/main/java/com/yahoo/yolean/Exceptions.java index 89b4e76368b..9776bdb54a8 100644 --- a/yolean/src/main/java/com/yahoo/yolean/Exceptions.java +++ b/yolean/src/main/java/com/yahoo/yolean/Exceptions.java @@ -62,22 +62,26 @@ public class Exceptions { /** * Wraps any IOException thrown from a runnable in an UncheckedIOException. */ - public static void uncheck(RunnableThrowingIOException runnable) { + public static void uncheck(RunnableThrowingException runnable) { try { runnable.run(); } catch (IOException e) { throw new UncheckedIOException(e); + } catch (InterruptedException e) { + throw new UncheckedInterruptedException(e); + } catch (Exception e) { + if (e instanceof RuntimeException) throw (RuntimeException) e; + throw new UncheckedException(e); } } + /** Use {@link #uncheck(RunnableThrowingException)} instead */ + @Deprecated(since="7", forRemoval = true) public static void uncheckInterrupted(RunnableThrowingInterruptedException runnable) { - try { - runnable.run(); - } catch (InterruptedException e) { - throw new UncheckedInterruptedException(e, false); - } + uncheck(runnable::run); } + @Deprecated(since="7", forRemoval = true) public static void uncheckInterruptedAndRestoreFlag(RunnableThrowingInterruptedException runnable) { try { runnable.run(); @@ -89,17 +93,25 @@ public class Exceptions { /** * Wraps any IOException thrown from a runnable in an UncheckedIOException w/message. */ - public static void uncheck(RunnableThrowingIOException runnable, String format, String... args) { + public static void uncheck(RunnableThrowingException runnable, String format, String... args) { try { runnable.run(); } catch (IOException e) { String message = String.format(format, (Object[]) args); throw new UncheckedIOException(message, e); + } catch (InterruptedException e) { + String message = String.format(format, (Object[]) args); + throw new UncheckedInterruptedException(message, e); + } catch (Exception e) { + if (e instanceof RuntimeException) throw (RuntimeException) e; + String message = String.format(format, (Object[]) args); + throw new UncheckedException(message, e); } } /** Similar to uncheck(), except an exceptionToIgnore exception is silently ignored. */ - public static <T extends IOException> void uncheckAndIgnore(RunnableThrowingIOException runnable, Class<T> exceptionToIgnore) { + @Deprecated(since="7", forRemoval = true) + public static <T extends IOException> void uncheckAndIgnore(RunnableThrowingException runnable, Class<T> exceptionToIgnore) { try { runnable.run(); } catch (UncheckedIOException e) { @@ -111,48 +123,58 @@ public class Exceptions { throw e; } // Do nothing - OK - } catch (IOException e) { + } catch (Exception e) { try { e.getClass().asSubclass(exceptionToIgnore); } catch (ClassCastException f) { - throw new UncheckedIOException(e); + throw new UncheckedException(e); } // Do nothing - OK } } - @FunctionalInterface - public interface RunnableThrowingIOException { - void run() throws IOException; - } - + @FunctionalInterface public interface RunnableThrowingException { void run() throws Exception; } @FunctionalInterface public interface RunnableThrowingInterruptedException { void run() throws InterruptedException; } + @FunctionalInterface public interface SupplierThrowingException<T> { T get() throws Exception; } /** * Wraps any IOException thrown from a supplier in an UncheckedIOException. */ - public static <T> T uncheck(SupplierThrowingIOException<T> supplier) { + public static <T> T uncheck(SupplierThrowingException<T> supplier) { try { return supplier.get(); } catch (IOException e) { throw new UncheckedIOException(e); + } catch (InterruptedException e) { + throw new UncheckedInterruptedException(e); + } catch (Exception e) { + if (e instanceof RuntimeException) throw (RuntimeException) e; + throw new UncheckedException(e); } } /** * Wraps any IOException thrown from a supplier in an UncheckedIOException w/message. */ - public static <T> T uncheck(SupplierThrowingIOException<T> supplier, String format, String... args) { + public static <T> T uncheck(SupplierThrowingException<T> supplier, String format, String... args) { try { return supplier.get(); } catch (IOException e) { String message = String.format(format, (Object[]) args); throw new UncheckedIOException(message, e); + } catch (InterruptedException e) { + String message = String.format(format, (Object[]) args); + throw new UncheckedInterruptedException(message, e); + } catch (Exception e) { + if (e instanceof RuntimeException) throw (RuntimeException) e; + String message = String.format(format, (Object[]) args); + throw new UncheckedException(message, e); } } /** Similar to uncheck(), except null is returned if exceptionToIgnore is thrown. */ - public static <R, T extends IOException> R uncheckAndIgnore(SupplierThrowingIOException<R> supplier, Class<T> exceptionToIgnore) { + @Deprecated(since="7", forRemoval = true) + public static <R, T extends IOException> R uncheckAndIgnore(SupplierThrowingException<R> supplier, Class<T> exceptionToIgnore) { try { return supplier.get(); } catch (UncheckedIOException e) { @@ -164,21 +186,16 @@ public class Exceptions { throw e; } return null; - } catch (IOException e) { + } catch (Exception e) { try { e.getClass().asSubclass(exceptionToIgnore); } catch (ClassCastException f) { - throw new UncheckedIOException(e); + throw new UncheckedException(e); } return null; } } - @FunctionalInterface - public interface SupplierThrowingIOException<T> { - T get() throws IOException; - } - /** * Allows treating checked exceptions as unchecked. * Usage: diff --git a/yolean/src/main/java/com/yahoo/yolean/UncheckedException.java b/yolean/src/main/java/com/yahoo/yolean/UncheckedException.java new file mode 100644 index 00000000000..39892c102a2 --- /dev/null +++ b/yolean/src/main/java/com/yahoo/yolean/UncheckedException.java @@ -0,0 +1,23 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.yolean; + +/** + * Wraps an {@link Exception} with an unchecked exception. + * + * @author freva + */ +public class UncheckedException extends RuntimeException { + + public UncheckedException(String message, Exception cause) { + super(message, cause); + if (cause instanceof RuntimeException) + throw new IllegalArgumentException(cause.getClass() + " is not a checked exception"); + } + + public UncheckedException(Exception cause) { + this(cause.toString(), cause); + } + + public UncheckedException(String message) { this(message, null); } + +} diff --git a/yolean/src/main/java/com/yahoo/yolean/UncheckedInterruptedException.java b/yolean/src/main/java/com/yahoo/yolean/UncheckedInterruptedException.java index d3317b5fb26..f7b6d50465a 100644 --- a/yolean/src/main/java/com/yahoo/yolean/UncheckedInterruptedException.java +++ b/yolean/src/main/java/com/yahoo/yolean/UncheckedInterruptedException.java @@ -6,7 +6,7 @@ package com.yahoo.yolean; * * @author bjorncs */ -public class UncheckedInterruptedException extends RuntimeException { +public class UncheckedInterruptedException extends UncheckedException { public UncheckedInterruptedException(String message, InterruptedException cause, boolean restoreInterruptFlag) { super(message, cause); diff --git a/yolean/src/main/java/com/yahoo/yolean/concurrent/Sleeper.java b/yolean/src/main/java/com/yahoo/yolean/concurrent/Sleeper.java index 530be935bc1..16a304aca25 100644 --- a/yolean/src/main/java/com/yahoo/yolean/concurrent/Sleeper.java +++ b/yolean/src/main/java/com/yahoo/yolean/concurrent/Sleeper.java @@ -5,7 +5,7 @@ import com.yahoo.yolean.UncheckedInterruptedException; import java.time.Duration; -import static com.yahoo.yolean.Exceptions.uncheckInterrupted; +import static com.yahoo.yolean.Exceptions.uncheck; /** * An abstraction used for mocking {@link Thread#sleep(long)} in unit tests. @@ -14,12 +14,12 @@ import static com.yahoo.yolean.Exceptions.uncheckInterrupted; */ public interface Sleeper { default void sleep(Duration duration) throws UncheckedInterruptedException { - uncheckInterrupted(() -> sleepChecked(duration.toMillis())); + uncheck(() -> sleepChecked(duration.toMillis())); } default void sleepChecked(Duration duration) throws InterruptedException { sleepChecked(duration.toMillis()); } - default void sleep(long millis) throws UncheckedInterruptedException { uncheckInterrupted(() -> sleepChecked(millis)); } + default void sleep(long millis) throws UncheckedInterruptedException { uncheck(() -> sleepChecked(millis)); } void sleepChecked(long millis) throws InterruptedException; diff --git a/yolean/src/test/java/com/yahoo/yolean/ExceptionsTestCase.java b/yolean/src/test/java/com/yahoo/yolean/ExceptionsTestCase.java index 53cf3efe363..ed36a550928 100644 --- a/yolean/src/test/java/com/yahoo/yolean/ExceptionsTestCase.java +++ b/yolean/src/test/java/com/yahoo/yolean/ExceptionsTestCase.java @@ -9,7 +9,6 @@ import java.nio.file.NoSuchFileException; import java.util.Optional; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; /** @@ -42,6 +41,7 @@ public class ExceptionsTestCase { } @Test + @SuppressWarnings({"removal"}) public void testUnchecks() { try { Exceptions.uncheck(this::throwNoSuchFileException); |