| package testproxy; |
| |
| import java.lang.reflect.Method; |
| import java.lang.reflect.Constructor; |
| import java.lang.reflect.Modifier; |
| |
| import org.junit.Assert; |
| |
| import java.lang.reflect.InvocationTargetException; |
| import javassist.util.proxy.ProxyFactory; |
| import javassist.util.proxy.MethodFilter; |
| import javassist.util.proxy.MethodHandler; |
| import javassist.util.proxy.ProxyObject; |
| import javassist.util.proxy.Proxy; |
| import junit.framework.TestCase; |
| import java.io.*; |
| |
| @SuppressWarnings({"unchecked", "rawtypes","unused"}) |
| public class ProxyTester extends TestCase { |
| public ProxyTester(String s) { |
| super(s); |
| } |
| |
| public ProxyTester() { |
| this("proxy"); |
| } |
| |
| static class Interceptor1 implements MethodHandler { |
| int counter = 0; |
| |
| public Object invoke(Object self, Method m, Method proceed, |
| Object[] args) throws Exception { |
| System.out.println("intercept: " + m + ", proceed: " + proceed); |
| System.out.println(" modifier: " |
| + Modifier.toString(proceed.getModifiers())); |
| counter++; |
| return proceed.invoke(self, args); |
| } |
| } |
| |
| static class Interceptor2 implements MethodHandler { |
| int counter = 0; |
| public Object invoke(Object self, Method m, Method proceed, |
| Object[] args) throws Exception { |
| System.out.println("intercept: " + m + ", proceed: " + proceed); |
| counter++; |
| if (proceed != null) |
| return proceed.invoke(self, args); |
| else |
| if (m.getReturnType() == int.class) |
| return Integer.valueOf(3); |
| else |
| return "OK"; |
| } |
| } |
| |
| static MethodFilter finalizeRemover = new MethodFilter() { |
| public boolean isHandled(Method m) { |
| return !m.getName().equals("finalize"); |
| } |
| }; |
| |
| public void testTarget() throws Exception { |
| ProxyFactory f = new ProxyFactory(); |
| f.setSuperclass(Target.class); |
| Interceptor1 interceptor = new Interceptor1(); |
| // f.setHandler(interceptor); |
| f.setFilter(finalizeRemover); |
| f.writeDirectory = "."; |
| Class c = f.createClass(); |
| Target obj = (Target)c.getConstructor().newInstance(); |
| ((Proxy)obj).setHandler(interceptor); |
| obj.m(); |
| assertEquals(true, obj.m(true)); |
| assertEquals((byte)1, obj.m1((byte)1)); |
| assertEquals('a', obj.m2('a')); |
| assertEquals((short)2, obj.m3((short)2)); |
| assertEquals(3, obj.m(3)); |
| assertEquals(4L, obj.m5(4L)); |
| assertTrue(5.0F == obj.m6(5.0F)); |
| assertTrue(6.0 == obj.m7(6.0)); |
| assertEquals("test", obj.m("test")); |
| int[] ia = { 1, 2, 3 }; |
| assertEquals(ia, obj.m7(ia)); |
| String[] sa = { "1", "2" }; |
| assertEquals(sa, obj.m8(sa)); |
| assertEquals(obj, obj.m9(3, obj, null)); |
| assertEquals(14, interceptor.counter); |
| } |
| |
| public void testTarget1() throws Exception { |
| ProxyFactory f = new ProxyFactory(); |
| f.setSuperclass(Target1.class); |
| Interceptor1 interceptor = new Interceptor1(); |
| // f.setHandler(interceptor); |
| f.setFilter(finalizeRemover); |
| Class c = f.createClass(); |
| Target1 obj = (Target1)c.getConstructor().newInstance(); |
| ((Proxy)obj).setHandler(interceptor); |
| assertEquals(null, obj.m(null)); |
| assertEquals(1, interceptor.counter); |
| } |
| |
| public void testObject() throws Exception { |
| ProxyFactory f = new ProxyFactory(); |
| Interceptor1 interceptor = new Interceptor1(); |
| // f.setHandler(interceptor); |
| f.setFilter(finalizeRemover); |
| Class c = f.createClass(); |
| Object obj = (Object)c.getConstructor().newInstance(); |
| ((Proxy)obj).setHandler(interceptor); |
| System.out.println(obj.toString()); |
| assertEquals(2, interceptor.counter); |
| } |
| |
| public void testSetter() throws Exception { |
| ProxyFactory f = new ProxyFactory(); |
| f.writeDirectory = "."; |
| Interceptor1 interceptor = new Interceptor1(); |
| // f.setHandler(interceptor); |
| f.setFilter(finalizeRemover); |
| Class c = f.createClass(); |
| Object obj = (Object)c.getConstructor().newInstance(); |
| ((Proxy)obj).setHandler(interceptor); |
| System.out.println("setter1: " + obj.toString()); |
| ((ProxyObject)obj).setHandler(new MethodHandler() { |
| public Object invoke(Object self, Method m, Method proceed, |
| Object[] args) throws Exception { |
| System.out.print("intercept: " + m); |
| return "OK"; |
| } |
| }); |
| assertEquals("OK", obj.toString()); |
| } |
| |
| public void testString() throws Exception { |
| ProxyFactory f = new ProxyFactory(); |
| Interceptor1 interceptor = new Interceptor1(); |
| // f.setHandler(interceptor); |
| f.setFilter(finalizeRemover); |
| f.setSuperclass(String.class); |
| try { |
| Class c = f.createClass(); |
| Assert.fail("String is final!"); |
| } |
| catch (RuntimeException e) { |
| System.out.println(e); |
| } |
| } |
| |
| public void testConstructor() throws Exception { |
| ProxyFactory f = new ProxyFactory(); |
| Interceptor1 interceptor = new Interceptor1(); |
| // f.setHandler(interceptor); |
| f.setFilter(finalizeRemover); |
| f.setSuperclass(Target2.class); |
| Class c = f.createClass(); |
| Constructor[] cons = c.getDeclaredConstructors(); |
| assertEquals(3, cons.length); |
| Constructor con1 = c.getDeclaredConstructor(new Class[] { int.class }); |
| Constructor con2 = c.getDeclaredConstructor(new Class[] { int.class, int.class }); |
| Method m1 = c.getDeclaredMethod("get", new Class[0]); |
| Method m2 = c.getDeclaredMethod("foo", new Class[0]); |
| assertEquals(0, m1.getExceptionTypes().length); |
| assertEquals("java.io.IOException", m2.getExceptionTypes()[0].getName()); |
| |
| Target2 t2 = (Target2)con1.newInstance(new Object[] { Integer.valueOf(1) }); |
| ((Proxy)t2).setHandler(interceptor); |
| System.out.println(t2.toString()); |
| assertEquals(2, interceptor.counter); |
| |
| interceptor.counter = 0; |
| assertEquals(2, t2.foo()); |
| assertEquals(4, t2._dfoo()); |
| assertEquals(2, interceptor.counter); |
| } |
| |
| public void testInterface() throws Exception { |
| ProxyFactory f = new ProxyFactory(); |
| Interceptor2 interceptor2 = new Interceptor2(); |
| // f.setHandler(interceptor2); |
| f.setFilter(finalizeRemover); |
| f.setInterfaces(new Class[] { Target3.class }); |
| Class c = f.createClass(); |
| Target3 obj = (Target3)c.getConstructor().newInstance(); |
| ((Proxy)obj).setHandler(interceptor2); |
| assertEquals("OK", obj.m()); |
| System.out.println(obj.toString()); |
| assertEquals(3, interceptor2.counter); |
| } |
| |
| public void test2Interfaces() throws Exception { |
| ProxyFactory f = new ProxyFactory(); |
| Interceptor2 interceptor2 = new Interceptor2(); |
| // f.setHandler(interceptor2); |
| f.setFilter(finalizeRemover); |
| f.setInterfaces(new Class[] { Target3.class, Target4.class }); |
| Class c = f.createClass(); |
| Target3 obj = (Target3)c.getConstructor().newInstance(); |
| ((Proxy)obj).setHandler(interceptor2); |
| assertEquals("OK", obj.m()); |
| System.out.println(obj.toString()); |
| assertEquals(3, interceptor2.counter); |
| |
| interceptor2.counter = 0; |
| Target4 obj4 = (Target4)c.getConstructor().newInstance(); |
| ((Proxy)obj4).setHandler(interceptor2); |
| assertEquals(3, obj4.bar4()); |
| assertEquals(3, obj4.foo4()); |
| assertEquals(2, interceptor2.counter); |
| } |
| |
| public void testFilter() throws Exception { |
| ProxyFactory f = new ProxyFactory(); |
| Interceptor2 interceptor2 = new Interceptor2(); |
| // f.setHandler(interceptor2); |
| f.setFilter(finalizeRemover); |
| f.setInterfaces(new Class[] { Target3.class }); |
| f.setFilter(new MethodFilter() { |
| public boolean isHandled(Method m) { |
| return m.getDeclaringClass() != Object.class; |
| } |
| }); |
| Class c = f.createClass(); |
| Target3 obj = (Target3)c.getConstructor().newInstance(); |
| ((Proxy)obj).setHandler(interceptor2); |
| assertEquals("OK", obj.m()); |
| System.out.println(obj.toString()); |
| assertEquals(1, interceptor2.counter); |
| } |
| |
| public static boolean testInitFlag; |
| |
| public void testInit() throws Exception { |
| ProxyFactory f = new ProxyFactory(); |
| f.setSuperclass(TargetInit.class); |
| MethodHandler handler = new MethodHandler() { |
| public Object invoke(Object self, Method m, |
| Method proceed, Object[] args) throws Exception { |
| System.out.println("testInit " + testInitFlag); |
| return proceed.invoke(self, args); |
| } |
| }; |
| testInitFlag = false; |
| Class c = f.createClass(); |
| assertTrue(testInitFlag); // since 3.12. Before then, this line was assertFalse(testInitFlag); |
| System.out.println("testInit createClass(): " + testInitFlag); |
| TargetInit obj = (TargetInit)c.getConstructor().newInstance(); |
| assertTrue(testInitFlag); |
| System.out.println("testInit newInstance(): " + testInitFlag); |
| ((ProxyObject)obj).setHandler(handler); |
| assertEquals("OK", obj.m()); |
| } |
| |
| public void testCreate() throws Exception { |
| ProxyFactory f = new ProxyFactory(); |
| f.setSuperclass(Target5.class); |
| Interceptor1 interceptor = new Interceptor1(); |
| // f.setHandler(interceptor); |
| f.setFilter(finalizeRemover); |
| Class c = f.createClass(); |
| Target5 obj = (Target5)f.create(new Class[] { int.class }, new Object[] { Integer.valueOf(3) }); |
| ((Proxy)obj).setHandler(interceptor); |
| assertEquals(3, obj.get()); |
| } |
| |
| |
| public void testBridgeMethod() throws Exception { |
| ProxyFactory f = new ProxyFactory(); |
| f.writeDirectory = "."; |
| f.setSuperclass(BridgeMethod.class); |
| Interceptor1 interceptor = new Interceptor1(); |
| // f.setHandler(interceptor); |
| f.setFilter(finalizeRemover); |
| Class c = f.createClass(); |
| BridgeMethod obj = (BridgeMethod)c.getConstructor().newInstance(); |
| ((Proxy)obj).setHandler(interceptor); |
| Integer value = obj.m1(); |
| assertEquals(7, value.intValue()); |
| BridgeMethodInf inf = (BridgeMethodInf)obj; |
| Number num = inf.m1(); |
| assertEquals(7, num.intValue()); |
| BridgeMethodSuper sup = obj; |
| try { |
| Object x = sup.id(new Object()); |
| fail("not cast error"); |
| } |
| catch (ClassCastException e) {} |
| catch (Exception e) { |
| if (e instanceof InvocationTargetException) |
| if (e.getCause() instanceof ClassCastException) |
| return; |
| |
| throw e; |
| } |
| } |
| |
| public void testGetters() throws Exception { |
| ProxyFactory f = new ProxyFactory(); |
| Class c = ProxyTester.class; |
| f.setSuperclass(c); |
| assertEquals(c, f.getSuperclass()); |
| Class i = java.io.Serializable.class; |
| f.setInterfaces(new Class[] { i }); |
| assertEquals(i, f.getInterfaces()[0]); |
| } |
| |
| static class ProxyFactory2 extends ProxyFactory { |
| public ClassLoader getClassLoader2() { |
| return getClassLoader(); |
| } |
| } |
| |
| public void testProvider() throws Exception { |
| ProxyFactory.ClassLoaderProvider cp = ProxyFactory.classLoaderProvider; |
| try { |
| final ClassLoader cl = Thread.currentThread().getContextClassLoader(); |
| ProxyFactory.classLoaderProvider = new ProxyFactory.ClassLoaderProvider() { |
| public ClassLoader get(ProxyFactory pf) { |
| return Thread.currentThread().getContextClassLoader(); |
| } |
| }; |
| |
| ProxyFactory2 pf = new ProxyFactory2(); |
| assertEquals(cl, pf.getClassLoader2()); |
| } |
| finally { |
| ProxyFactory.classLoaderProvider = cp; |
| } |
| } |
| |
| @SuppressWarnings("deprecation") |
| public void testCache() throws Exception { |
| boolean prev = ProxyFactory.useCache; |
| ProxyFactory.useCache = true; |
| ProxyFactory f = new ProxyFactory(); |
| f.setSuperclass(Cache1.class); |
| Class c = f.createClass(); |
| ProxyFactory f2 = new ProxyFactory(); |
| f2.setSuperclass(Cache1.class); |
| assertEquals(c, f2.createClass()); |
| ProxyFactory f3 = new ProxyFactory(); |
| f3.setSuperclass(Cache1.class); |
| f3.setHandler(new Interceptor1()); // deprecated |
| assertFalse(c == f3.createClass()); |
| ProxyFactory.useCache = true; |
| ProxyFactory f4 = new ProxyFactory(); |
| f4.setSuperclass(Cache1.class); |
| f4.setInterfaces(new Class[] { Cache2.class }); |
| Class c4 = f4.createClass(); |
| assertFalse(c == c4); |
| ProxyFactory f5 = new ProxyFactory(); |
| f5.setSuperclass(Cache1.class); |
| f5.setInterfaces(new Class[] { Cache2.class }); |
| assertEquals(c4, f5.createClass()); |
| ProxyFactory f6 = new ProxyFactory(); |
| f6.setInterfaces(new Class[] { Cache2.class }); |
| assertFalse(c4 == f6.createClass()); |
| ProxyFactory.useCache = prev; |
| } |
| |
| public static class Cache1 { |
| public int foo() { return 0; } |
| } |
| |
| public static interface Cache2 { |
| public int bar(); |
| } |
| |
| public void testReadWrite() throws Exception { |
| final String fileName = "read-write.bin"; |
| ProxyFactory.ClassLoaderProvider cp = ProxyFactory.classLoaderProvider; |
| try { |
| ProxyFactory.classLoaderProvider = new ProxyFactory.ClassLoaderProvider() { |
| public ClassLoader get(ProxyFactory pf) { |
| /* If javassist.Loader is returned, the super type of ReadWriteData class, |
| * which is Serializable, is loaded by javassist.Loader as well as ReadWriteData. |
| * This breaks the implementation of the object serializer. |
| */ |
| // return new javassist.Loader(); |
| return Thread.currentThread().getContextClassLoader(); |
| } |
| }; |
| ProxyFactory pf = new ProxyFactory(); |
| pf.setSuperclass(ReadWriteData.class); |
| Object data = pf.createClass().getConstructor().newInstance(); |
| //Object data = new ReadWriteData(); |
| ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(fileName)); |
| oos.writeObject(data); |
| oos.close(); |
| } |
| finally { |
| ProxyFactory.classLoaderProvider = cp; |
| } |
| |
| ObjectInputStream ois = new ObjectInputStream(new FileInputStream(fileName)); |
| Object data2 = ois.readObject(); |
| ois.close(); |
| int i = ((ReadWriteData)data2).foo(); |
| assertEquals(4, i); |
| } |
| |
| public static class ReadWriteData implements Serializable { |
| /** default serialVersionUID */ |
| private static final long serialVersionUID = 1L; |
| |
| public int foo() { return 4; } |
| } |
| |
| public void testWriteReplace() throws Exception { |
| ProxyFactory pf = new ProxyFactory(); |
| pf.setSuperclass(WriteReplace.class); |
| Object data = pf.createClass().getConstructor().newInstance(); |
| assertEquals(data, ((WriteReplace)data).writeReplace()); |
| |
| ProxyFactory pf2 = new ProxyFactory(); |
| pf2.setSuperclass(WriteReplace2.class); |
| Object data2 = pf2.createClass().getConstructor().newInstance(); |
| Method meth = data2.getClass().getDeclaredMethod("writeReplace", new Class[0]); |
| assertEquals("javassist.util.proxy.SerializedProxy", |
| meth.invoke(data2, new Object[0]).getClass().getName()); |
| } |
| |
| public static class WriteReplace implements Serializable { |
| /** default serialVersionUID */ |
| private static final long serialVersionUID = 1L; |
| |
| public Object writeReplace() { return this; } |
| } |
| |
| public static class WriteReplace2 implements Serializable { |
| /** default serialVersionUID */ |
| private static final long serialVersionUID = 1L; |
| |
| public Object writeReplace(int i) { return Integer.valueOf(i); } |
| } |
| |
| public static void testJIRA189() throws Exception { |
| Class persistentClass = Target189.PublishedArticle.class; |
| ProxyFactory factory = new ProxyFactory(); |
| //factory.writeDirectory = "."; |
| factory.setUseCache(false); |
| factory.setSuperclass(persistentClass); |
| factory.setInterfaces(new Class[] { Target189.TestProxy.class }); |
| Class cl = factory.createClass(); |
| Object obj = cl.getConstructor().newInstance(); |
| System.out.println("JIRA189:" + obj.getClass().getClassLoader() + ", " + obj.getClass().getSuperclass().getName() |
| + ", " + Target189.PublishedArticle.class.getClassLoader()); |
| Target189.TestProxy proxy = (Target189.TestProxy)cl.getConstructor().newInstance(); |
| Target189.TestMethodHandler methodHandler = new Target189.TestMethodHandler(); |
| ((ProxyObject)proxy).setHandler(methodHandler); |
| ((Target189.Article)proxy).getIssue(); |
| assertTrue(methodHandler.wasInvokedOnce()); |
| methodHandler.reset(); |
| Target189.PublishedArticle article = (Target189.PublishedArticle)proxy; |
| article.getIssue(); |
| assertTrue(methodHandler.wasInvokedOnce()); |
| } |
| |
| public void testJIRA127() throws Exception { |
| ProxyFactory proxyFactory = new ProxyFactory(); |
| // proxyFactory.writeDirectory = "."; |
| proxyFactory.setInterfaces(new Class[]{ Target127.Sub.class }); |
| Target127.Sub proxy = (Target127.Sub)proxyFactory.create(new Class[0], new Object[0], new MethodHandler() { |
| public Object invoke(Object self, Method thisMethod, Method proceed, Object[] args) throws Throwable { |
| return null; |
| } |
| }); |
| ((Target127.Super)proxy).item(); // proxyFactory must generate a bridge method. |
| ((Target127.Sub)proxy).item(); |
| } |
| |
| public static void main(String[] args) { |
| // javassist.bytecode.ClassFile.MAJOR_VERSION = javassist.bytecode.ClassFile.JAVA_6; |
| junit.textui.TestRunner.run(ProxyTester.class); |
| } |
| } |