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.lang.reflect.InvocationTargetException; import java.util.Arrays; import java.util.Collection; import static junit.framework.TestCase.fail; import static net.bytebuddy.matcher.ElementMatchers.named; import static org.hamcrest.CoreMatchers.instanceOf; import static org.hamcrest.MatcherAssert.assertThat; @RunWith(Parameterized.class) public class AdviceNoRegularReturnTest { private static final String FOO = "foo"; private final Class<?> type; public AdviceNoRegularReturnTest(Class<?> type) { this.type = type; } @Parameterized.Parameters public static Collection<Object[]> data() { return Arrays.asList(new Object[][]{ {VoidSample.class}, {BooleanSample.class}, {ByteSample.class}, {ShortSample.class}, {CharacterSample.class}, {IntegerSample.class}, {LongSample.class}, {FloatSample.class}, {DoubleSample.class}, {ReferenceSample.class} }); } @Test public void testNoRegularReturnWithSkip() throws Exception { Class<?> type = new ByteBuddy() .redefine(this.type) .visit(Advice.to(EnterAdviceSkip.class).on(named(FOO))) .make() .load(ClassLoadingStrategy.BOOTSTRAP_LOADER, ClassLoadingStrategy.Default.WRAPPER) .getLoaded(); try { type.getDeclaredMethod(FOO).invoke(type.getDeclaredConstructor().newInstance()); fail(); } catch (InvocationTargetException exception) { assertThat(exception.getCause(), instanceOf(RuntimeException.class)); } } @Test public void testNoRegularReturnWithoutHandler() throws Exception { Class<?> type = new ByteBuddy() .redefine(this.type) .visit(Advice.to(ExitAdviceWithoutHandler.class).on(named(FOO))) .make() .load(ClassLoadingStrategy.BOOTSTRAP_LOADER, ClassLoadingStrategy.Default.WRAPPER) .getLoaded(); try { type.getDeclaredMethod(FOO).invoke(type.getDeclaredConstructor().newInstance()); fail(); } catch (InvocationTargetException exception) { assertThat(exception.getCause(), instanceOf(RuntimeException.class)); } } @Test public void testNoRegularReturnWithHandler() throws Exception { Class<?> type = new ByteBuddy() .redefine(this.type) .visit(Advice.to(ExitAdviceWithHandler.class).on(named(FOO))) .make() .load(ClassLoadingStrategy.BOOTSTRAP_LOADER, ClassLoadingStrategy.Default.WRAPPER) .getLoaded(); try { type.getDeclaredMethod(FOO).invoke(type.getDeclaredConstructor().newInstance()); fail(); } catch (InvocationTargetException exception) { assertThat(exception.getCause(), instanceOf(RuntimeException.class)); } } private static class EnterAdviceSkip { @Advice.OnMethodEnter(skipOn = Advice.OnNonDefaultValue.class) private static boolean enter() { return false; } } private static class ExitAdviceWithoutHandler { @Advice.OnMethodExit private static void exit() { /* empty */ } } private static class ExitAdviceWithHandler { @Advice.OnMethodExit(onThrowable = RuntimeException.class) private static void exit() { /* empty */ } } public static class VoidSample { public void foo() { throw new RuntimeException(); } } public static class BooleanSample { public boolean foo() { throw new RuntimeException(); } } public static class ByteSample { public byte foo() { throw new RuntimeException(); } } public static class ShortSample { public short foo() { throw new RuntimeException(); } } public static class CharacterSample { public char foo() { throw new RuntimeException(); } } public static class IntegerSample { public int foo() { throw new RuntimeException(); } } public static class LongSample { public long foo() { throw new RuntimeException(); } } public static class FloatSample { public float foo() { throw new RuntimeException(); } } public static class DoubleSample { public double foo() { throw new RuntimeException(); } } public static class ReferenceSample { public Object foo() { throw new RuntimeException(); } } }