package net.bytebuddy.asm; import net.bytebuddy.ByteBuddy; import net.bytebuddy.dynamic.loading.ClassLoadingStrategy; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import java.util.Arrays; import java.util.Collection; import static net.bytebuddy.matcher.ElementMatchers.named; import static org.hamcrest.CoreMatchers.nullValue; import static org.hamcrest.MatcherAssert.assertThat; @RunWith(Parameterized.class) public class AdviceSuppressionTest { private static final String FOO = "foo"; @Parameterized.Parameters public static Collection<Object[]> data() { return Arrays.asList(new Object[][]{ {VoidInlineEnterAdvice.class}, {BooleanInlineEnterAdvice.class}, {ByteInlineEnterAdvice.class}, {ShortInlineEnterAdvice.class}, {CharacterInlineEnterAdvice.class}, {IntegerInlineEnterAdvice.class}, {LongInlineEnterAdvice.class}, {FloatInlineEnterAdvice.class}, {DoubleInlineEnterAdvice.class}, {ReferenceInlineEnterAdvice.class}, {VoidDelegationEnterAdvice.class}, {BooleanDelegationEnterAdvice.class}, {ByteDelegationEnterAdvice.class}, {ShortDelegationEnterAdvice.class}, {CharacterDelegationEnterAdvice.class}, {IntegerDelegationEnterAdvice.class}, {LongDelegationEnterAdvice.class}, {FloatDelegationEnterAdvice.class}, {DoubleDelegationEnterAdvice.class}, {ReferenceDelegationEnterAdvice.class}, {VoidInlineExitAdvice.class}, {BooleanInlineExitAdvice.class}, {ByteInlineExitAdvice.class}, {ShortInlineExitAdvice.class}, {CharacterInlineExitAdvice.class}, {IntegerInlineExitAdvice.class}, {LongInlineExitAdvice.class}, {FloatInlineExitAdvice.class}, {DoubleInlineExitAdvice.class}, {ReferenceInlineExitAdvice.class}, {VoidDelegationExitAdvice.class}, {BooleanDelegationExitAdvice.class}, {ByteDelegationExitAdvice.class}, {ShortDelegationExitAdvice.class}, {CharacterDelegationExitAdvice.class}, {IntegerDelegationExitAdvice.class}, {LongDelegationExitAdvice.class}, {FloatDelegationExitAdvice.class}, {DoubleDelegationExitAdvice.class}, {ReferenceDelegationExitAdvice.class} }); } private final Class<?> type; public AdviceSuppressionTest(Class<?> type) { this.type = type; } @Test public void testIllegalAssignment() throws Exception { Class<?> dynamicType = new ByteBuddy() .redefine(type) .visit(Advice.to(type).on(named(FOO))) .make() .load(ClassLoadingStrategy.BOOTSTRAP_LOADER, ClassLoadingStrategy.Default.WRAPPER) .getLoaded(); assertThat(dynamicType.getDeclaredMethod(FOO).invoke(dynamicType.getDeclaredConstructor().newInstance()), nullValue(Object.class)); } @SuppressWarnings("unused") public static class VoidInlineEnterAdvice { public void foo() { /* empty */ } @Advice.OnMethodExit(suppress = RuntimeException.class) public static void exit() { throw new RuntimeException(); } } @SuppressWarnings("unused") public static class BooleanInlineEnterAdvice { public void foo() { /* empty */ } @Advice.OnMethodExit(suppress = RuntimeException.class) public static boolean exit() { throw new RuntimeException(); } } @SuppressWarnings("unused") public static class ByteInlineEnterAdvice { public void foo() { /* empty */ } @Advice.OnMethodExit(suppress = RuntimeException.class) public static byte exit() { throw new RuntimeException(); } } @SuppressWarnings("unused") public static class ShortInlineEnterAdvice { public void foo() { /* empty */ } @Advice.OnMethodExit(suppress = RuntimeException.class) public static short exit() { throw new RuntimeException(); } } @SuppressWarnings("unused") public static class CharacterInlineEnterAdvice { public void foo() { /* empty */ } @Advice.OnMethodExit(suppress = RuntimeException.class) public static byte exit() { throw new RuntimeException(); } } @SuppressWarnings("unused") public static class IntegerInlineEnterAdvice { public void foo() { /* empty */ } @Advice.OnMethodExit(suppress = RuntimeException.class) public static int exit() { throw new RuntimeException(); } } @SuppressWarnings("unused") public static class LongInlineEnterAdvice { public void foo() { /* empty */ } @Advice.OnMethodExit(suppress = RuntimeException.class) public static long exit() { throw new RuntimeException(); } } @SuppressWarnings("unused") public static class FloatInlineEnterAdvice { public void foo() { /* empty */ } @Advice.OnMethodExit(suppress = RuntimeException.class) public static float exit() { throw new RuntimeException(); } } @SuppressWarnings("unused") public static class DoubleInlineEnterAdvice { public void foo() { /* empty */ } @Advice.OnMethodExit(suppress = RuntimeException.class) public static double exit() { throw new RuntimeException(); } } @SuppressWarnings("unused") public static class ReferenceInlineEnterAdvice { public void foo() { /* empty */ } @Advice.OnMethodExit(suppress = RuntimeException.class) public static Object exit() { throw new RuntimeException(); } } @SuppressWarnings("unused") public static class BooleanDelegationEnterAdvice { public void foo() { /* empty */ } @Advice.OnMethodExit(suppress = RuntimeException.class, inline = false) public static boolean exit() { throw new RuntimeException(); } } @SuppressWarnings("unused") public static class VoidDelegationEnterAdvice { public void foo() { /* empty */ } @Advice.OnMethodExit(suppress = RuntimeException.class, inline = false) public static void exit() { throw new RuntimeException(); } } @SuppressWarnings("unused") public static class ByteDelegationEnterAdvice { public void foo() { /* empty */ } @Advice.OnMethodExit(suppress = RuntimeException.class, inline = false) public static byte exit() { throw new RuntimeException(); } } @SuppressWarnings("unused") public static class ShortDelegationEnterAdvice { public void foo() { /* empty */ } @Advice.OnMethodExit(suppress = RuntimeException.class, inline = false) public static short exit() { throw new RuntimeException(); } } @SuppressWarnings("unused") public static class CharacterDelegationEnterAdvice { public void foo() { /* empty */ } @Advice.OnMethodExit(suppress = RuntimeException.class, inline = false) public static byte exit() { throw new RuntimeException(); } } @SuppressWarnings("unused") public static class IntegerDelegationEnterAdvice { public void foo() { /* empty */ } @Advice.OnMethodExit(suppress = RuntimeException.class, inline = false) public static int exit() { throw new RuntimeException(); } } @SuppressWarnings("unused") public static class LongDelegationEnterAdvice { public void foo() { /* empty */ } @Advice.OnMethodExit(suppress = RuntimeException.class, inline = false) public static long exit() { throw new RuntimeException(); } } @SuppressWarnings("unused") public static class FloatDelegationEnterAdvice { public void foo() { /* empty */ } @Advice.OnMethodExit(suppress = RuntimeException.class, inline = false) public static float exit() { throw new RuntimeException(); } } @SuppressWarnings("unused") public static class DoubleDelegationEnterAdvice { public void foo() { /* empty */ } @Advice.OnMethodExit(suppress = RuntimeException.class, inline = false) public static double exit() { throw new RuntimeException(); } } @SuppressWarnings("unused") public static class ReferenceDelegationEnterAdvice { public void foo() { /* empty */ } @Advice.OnMethodExit(suppress = RuntimeException.class, inline = false) public static Object exit() { throw new RuntimeException(); } } @SuppressWarnings("unused") public static class VoidInlineExitAdvice { public void foo() { /* empty */ } @Advice.OnMethodEnter(suppress = RuntimeException.class) public static void enter() { throw new RuntimeException(); } } @SuppressWarnings("unused") public static class BooleanInlineExitAdvice { public void foo() { /* empty */ } @Advice.OnMethodEnter(suppress = RuntimeException.class) public static boolean enter() { throw new RuntimeException(); } @Advice.OnMethodExit @SuppressWarnings("all") public static void exit(@Advice.Enter boolean value) { if (value) { throw new AssertionError(); } } } @SuppressWarnings("unused") public static class ByteInlineExitAdvice { public void foo() { /* empty */ } @Advice.OnMethodEnter(suppress = RuntimeException.class) public static byte enter() { throw new RuntimeException(); } @Advice.OnMethodExit public static void exit(@Advice.Enter byte value) { if (value != 0) { throw new AssertionError(); } } } @SuppressWarnings("unused") public static class ShortInlineExitAdvice { public void foo() { /* empty */ } @Advice.OnMethodEnter(suppress = RuntimeException.class) public static short enter() { throw new RuntimeException(); } @Advice.OnMethodExit public static void exit(@Advice.Enter short value) { if (value != 0) { throw new AssertionError(); } } } @SuppressWarnings("unused") public static class CharacterInlineExitAdvice { public void foo() { /* empty */ } @Advice.OnMethodEnter(suppress = RuntimeException.class) public static byte enter() { throw new RuntimeException(); } @Advice.OnMethodExit public static void exit(@Advice.Enter byte value) { if (value != 0) { throw new AssertionError(); } } } @SuppressWarnings("unused") public static class IntegerInlineExitAdvice { public void foo() { /* empty */ } @Advice.OnMethodEnter(suppress = RuntimeException.class) public static int enter() { throw new RuntimeException(); } @Advice.OnMethodExit public static void exit(@Advice.Enter int value) { if (value != 0) { throw new AssertionError(); } } } @SuppressWarnings("unused") public static class LongInlineExitAdvice { public void foo() { /* empty */ } @Advice.OnMethodEnter(suppress = RuntimeException.class) public static long enter() { throw new RuntimeException(); } @Advice.OnMethodExit public static void exit(@Advice.Enter long value) { if (value != 0) { throw new AssertionError(); } } } @SuppressWarnings("unused") public static class FloatInlineExitAdvice { public void foo() { /* empty */ } @Advice.OnMethodEnter(suppress = RuntimeException.class) public static float enter() { throw new RuntimeException(); } @Advice.OnMethodExit public static void exit(@Advice.Enter float value) { if (value != 0) { throw new AssertionError(); } } } @SuppressWarnings("unused") public static class DoubleInlineExitAdvice { public void foo() { /* empty */ } @Advice.OnMethodEnter(suppress = RuntimeException.class) public static double enter() { throw new RuntimeException(); } @Advice.OnMethodExit public static void exit(@Advice.Enter double value) { if (value != 0) { throw new AssertionError(); } } } @SuppressWarnings("unused") public static class ReferenceInlineExitAdvice { public void foo() { /* empty */ } @Advice.OnMethodEnter(suppress = RuntimeException.class) public static Object enter() { throw new RuntimeException(); } @Advice.OnMethodExit public static void exit(@Advice.Enter Object value) { if (value != null) { throw new AssertionError(); } } } @SuppressWarnings("unused") public static class VoidDelegationExitAdvice { public void foo() { /* empty */ } @Advice.OnMethodEnter(suppress = RuntimeException.class, inline = false) public static void enter() { throw new RuntimeException(); } } @SuppressWarnings("unused") public static class BooleanDelegationExitAdvice { public void foo() { /* empty */ } @Advice.OnMethodEnter(suppress = RuntimeException.class, inline = false) public static boolean enter() { throw new RuntimeException(); } @Advice.OnMethodExit(inline = false) @SuppressWarnings("all") public static void exit(@Advice.Enter boolean value) { if (value) { throw new AssertionError(); } } } @SuppressWarnings("unused") public static class ByteDelegationExitAdvice { public void foo() { /* empty */ } @Advice.OnMethodEnter(suppress = RuntimeException.class, inline = false) public static byte enter() { throw new RuntimeException(); } @Advice.OnMethodExit(inline = false) public static void exit(@Advice.Enter byte value) { if (value != 0) { throw new AssertionError(); } } } @SuppressWarnings("unused") public static class ShortDelegationExitAdvice { public void foo() { /* empty */ } @Advice.OnMethodEnter(suppress = RuntimeException.class, inline = false) public static short enter() { throw new RuntimeException(); } @Advice.OnMethodExit(inline = false) public static void exit(@Advice.Enter short value) { if (value != 0) { throw new AssertionError(); } } } @SuppressWarnings("unused") public static class CharacterDelegationExitAdvice { public void foo() { /* empty */ } @Advice.OnMethodEnter(suppress = RuntimeException.class, inline = false) public static byte enter() { throw new RuntimeException(); } @Advice.OnMethodExit(inline = false) public static void exit(@Advice.Enter byte value) { if (value != 0) { throw new AssertionError(); } } } @SuppressWarnings("unused") public static class IntegerDelegationExitAdvice { public void foo() { /* empty */ } @Advice.OnMethodEnter(suppress = RuntimeException.class, inline = false) public static int enter() { throw new RuntimeException(); } @Advice.OnMethodExit(inline = false) public static void exit(@Advice.Enter int value) { if (value != 0) { throw new AssertionError(); } } } @SuppressWarnings("unused") public static class LongDelegationExitAdvice { public void foo() { /* empty */ } @Advice.OnMethodEnter(suppress = RuntimeException.class, inline = false) public static long enter() { throw new RuntimeException(); } @Advice.OnMethodExit(inline = false) public static void exit(@Advice.Enter long value) { if (value != 0) { throw new AssertionError(); } } } @SuppressWarnings("unused") public static class FloatDelegationExitAdvice { public void foo() { /* empty */ } @Advice.OnMethodEnter(suppress = RuntimeException.class, inline = false) public static float enter() { throw new RuntimeException(); } @Advice.OnMethodExit(inline = false) public static void exit(@Advice.Enter float value) { if (value != 0) { throw new AssertionError(); } } } @SuppressWarnings("unused") public static class DoubleDelegationExitAdvice { public void foo() { /* empty */ } @Advice.OnMethodEnter(suppress = RuntimeException.class, inline = false) public static double enter() { throw new RuntimeException(); } @Advice.OnMethodExit(inline = false) public static void exit(@Advice.Enter double value) { if (value != 0) { throw new AssertionError(); } } } @SuppressWarnings("unused") public static class ReferenceDelegationExitAdvice { public void foo() { /* empty */ } @Advice.OnMethodEnter(suppress = RuntimeException.class, inline = false) public static Object enter() { throw new RuntimeException(); } @Advice.OnMethodExit(inline = false) public static void exit(@Advice.Enter Object value) { if (value != null) { throw new AssertionError(); } } } }