package org.hotswap.agent.plugin.proxy.test.methods; import static org.hotswap.agent.plugin.proxy.test.util.HotSwapTestHelper.*; import static org.junit.Assert.*; import java.io.IOException; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import org.junit.Before; import org.junit.Test; /** * Tests accessing added method on a proxy. * * @author Erki Ehtla */ public class AddMethodProxyTest { static public class DummyHandler implements InvocationHandler { private Object a; public DummyHandler(Object a) { this.a = a; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return method.invoke(a, args); } } // Version 0 public static class AImpl implements A { @Override public int getValue1() { return 1; } /* * (non-Javadoc) * * @see com.github.dcevm.test.methods.AddMethodProxyTest.A#getValue1(java.lang.Object[]) */ @Override public int getValue3(Object[] o) { return 1; } } // Version 0 public static class AImpl___0 implements A___0 { @Override public int getValue1() { return 1; } /* * (non-Javadoc) * * @see com.github.dcevm.test.methods.AddMethodProxyTest.A#getValue1(java.lang.Object[]) */ @Override public int getValue3(Object[] o) { return 1; } } // Version 1 public static class AImpl___1 implements A___1 { @Override public int getValue2() { return 2; } @Override public int getValue33(Object[] o) { return 2; } } // Version 0 public interface A { public int getValue1(); public int getValue3(Object[] o); } // Version 0 public interface A___0 { public int getValue1(); public int getValue3(Object[] o); } // Version 1 public interface A___1 { public int getValue2(); public int getValue33(Object[] o); } @Before public void setUp() throws Exception { __toVersion__Delayed_JavaProxy(0); } @Test public void addMethodToInterfaceAndImplementation() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { assert __version__() == 0; final A a = new AImpl(); assertEquals(1, a.getValue1()); __toVersion__Delayed_JavaProxy(1); Method method = getMethod(a, "getValue2"); assertEquals(2, method.invoke(a, null)); } @Test public void accessNewMethodOnProxy() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { assert __version__() == 0; final A a = (A) Proxy.newProxyInstance(getClass().getClassLoader(), new Class[] { A.class }, new DummyHandler( new AImpl())); assertEquals(1, a.getValue1()); __toVersion__Delayed_JavaProxy(1); Method method = getMethod(a, "getValue33"); assertEquals("getValue33", method.getName()); assertEquals(2, method.invoke(a, new Object[] { new Object[] { new Object() } })); } @Test public void accessNewMethodOnProxyCreatedAfterSwap() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, IOException { assert __version__() == 0; A a = (A) Proxy.newProxyInstance(getClass().getClassLoader(), new Class[] { A.class }, new DummyHandler( new AImpl())); assertEquals(1, a.getValue1()); __toVersion__Delayed_JavaProxy(1); a = (A) Proxy.newProxyInstance(getClass().getClassLoader(), new Class[] { A.class }, new DummyHandler( new AImpl())); Method method = getMethod(a, "getValue2"); assertEquals("getValue2", method.getName()); assertEquals(2, method.invoke(a, null)); method = getMethod(a, "getValue33"); assertEquals("getValue33", method.getName()); assertEquals(2, method.invoke(a, new Object[] { new Object[] { new Object() } })); } private Method getMethod(Object a, String methodName) { Method[] declaredMethods = a.getClass().getDeclaredMethods(); Method m = null; for (Method method : declaredMethods) { if (method.getName().equals(methodName)) m = method; } if (m == null) { fail(a.getClass().getSimpleName() + " does not have method " + methodName); } return m; } }