diff --git a/common/src/main/java/io/netty/util/internal/SuppressJava6Requirement.java b/common/src/main/java/io/netty/util/internal/SuppressJava6Requirement.java new file mode 100644 index 0000000000..557d0095a6 --- /dev/null +++ b/common/src/main/java/io/netty/util/internal/SuppressJava6Requirement.java @@ -0,0 +1,32 @@ +/* + * Copyright 2018 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package io.netty.util.internal; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Annotation to suppress the Java 6 source code requirement checks for a method. + */ +@Retention(RetentionPolicy.CLASS) +@Target({ ElementType.METHOD }) +public @interface SuppressJava6Requirement { + + String reason(); +} diff --git a/common/src/main/java/io/netty/util/internal/ThrowableUtil.java b/common/src/main/java/io/netty/util/internal/ThrowableUtil.java index 4c1cf8fdd5..de336b7e3c 100644 --- a/common/src/main/java/io/netty/util/internal/ThrowableUtil.java +++ b/common/src/main/java/io/netty/util/internal/ThrowableUtil.java @@ -18,26 +18,10 @@ package io.netty.util.internal; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.PrintStream; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import java.util.List; public final class ThrowableUtil { - private static final Method addSupressedMethod = getAddSuppressed(); - - private static Method getAddSuppressed() { - if (PlatformDependent.javaVersion() < 7) { - return null; - } - try { - // addSuppressed is final, so we only need to look it up on Throwable. - return Throwable.class.getDeclaredMethod("addSuppressed", Throwable.class); - } catch (NoSuchMethodException e) { - throw new RuntimeException(e); - } - } - private ThrowableUtil() { } /** @@ -71,20 +55,15 @@ public final class ThrowableUtil { } public static boolean haveSuppressed() { - return addSupressedMethod != null; + return PlatformDependent.javaVersion() >= 7; } + @SuppressJava6Requirement(reason = "Throwable addSuppressed is only available for >= 7. Has check for < 7.") public static void addSuppressed(Throwable target, Throwable suppressed) { if (!haveSuppressed()) { return; } - try { - addSupressedMethod.invoke(target, suppressed); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } catch (InvocationTargetException e) { - throw new RuntimeException(e); - } + target.addSuppressed(suppressed); } public static void addSuppressedAndClear(Throwable target, List suppressed) { diff --git a/common/src/test/java/io/netty/util/internal/NativeLibraryLoaderTest.java b/common/src/test/java/io/netty/util/internal/NativeLibraryLoaderTest.java index 0a40fb85b5..de73b9ecf5 100644 --- a/common/src/test/java/io/netty/util/internal/NativeLibraryLoaderTest.java +++ b/common/src/test/java/io/netty/util/internal/NativeLibraryLoaderTest.java @@ -17,7 +17,6 @@ package io.netty.util.internal; import org.junit.Test; -import java.lang.reflect.Method; import java.io.FileNotFoundException; import java.util.UUID; @@ -26,8 +25,6 @@ import static org.junit.Assert.fail; public class NativeLibraryLoaderTest { - private static final Method getSupressedMethod = getGetSuppressed(); - @Test public void testFileNotFound() { try { @@ -35,7 +32,7 @@ public class NativeLibraryLoaderTest { fail(); } catch (UnsatisfiedLinkError error) { assertTrue(error.getCause() instanceof FileNotFoundException); - if (getSupressedMethod != null) { + if (PlatformDependent.javaVersion() >= 7) { verifySuppressedException(error, UnsatisfiedLinkError.class); } } @@ -48,34 +45,24 @@ public class NativeLibraryLoaderTest { fail(); } catch (UnsatisfiedLinkError error) { assertTrue(error.getCause() instanceof FileNotFoundException); - if (getSupressedMethod != null) { + if (PlatformDependent.javaVersion() >= 7) { verifySuppressedException(error, ClassNotFoundException.class); } } } + @SuppressJava6Requirement(reason = "uses Java 7+ Throwable#getSuppressed but is guarded by version checks") private static void verifySuppressedException(UnsatisfiedLinkError error, Class expectedSuppressedExceptionClass) { try { - Throwable[] suppressed = (Throwable[]) getSupressedMethod.invoke(error.getCause()); + Throwable[] suppressed = error.getCause().getSuppressed(); assertTrue(suppressed.length == 1); assertTrue(suppressed[0] instanceof UnsatisfiedLinkError); - suppressed = (Throwable[]) getSupressedMethod.invoke(suppressed[0]); + suppressed = (suppressed[0]).getSuppressed(); assertTrue(suppressed.length == 1); assertTrue(expectedSuppressedExceptionClass.isInstance(suppressed[0])); } catch (Exception e) { throw new RuntimeException(e); } } - - private static Method getGetSuppressed() { - if (PlatformDependent.javaVersion() < 7) { - return null; - } - try { - return Throwable.class.getDeclaredMethod("getSuppressed"); - } catch (NoSuchMethodException e) { - throw new RuntimeException(e); - } - } } diff --git a/pom.xml b/pom.xml index 9d217cce3c..a4936d8610 100644 --- a/pom.xml +++ b/pom.xml @@ -721,6 +721,9 @@ java.nio.file.Path java.io.File + + io.netty.util.internal.SuppressJava6Requirement +