1 package testproxy; 2 3 import java.lang.reflect.Method; 4 import java.lang.reflect.Constructor; 5 import java.lang.reflect.Modifier; 6 7 import org.junit.Assert; 8 9 import java.lang.reflect.InvocationTargetException; 10 import javassist.util.proxy.ProxyFactory; 11 import javassist.util.proxy.MethodFilter; 12 import javassist.util.proxy.MethodHandler; 13 import javassist.util.proxy.ProxyObject; 14 import javassist.util.proxy.Proxy; 15 import junit.framework.TestCase; 16 import java.io.*; 17 18 @SuppressWarnings({"unchecked", "rawtypes","unused"}) 19 public class ProxyTester extends TestCase { ProxyTester(String s)20 public ProxyTester(String s) { 21 super(s); 22 } 23 ProxyTester()24 public ProxyTester() { 25 this("proxy"); 26 } 27 28 static class Interceptor1 implements MethodHandler { 29 int counter = 0; 30 invoke(Object self, Method m, Method proceed, Object[] args)31 public Object invoke(Object self, Method m, Method proceed, 32 Object[] args) throws Exception { 33 System.out.println("intercept: " + m + ", proceed: " + proceed); 34 System.out.println(" modifier: " 35 + Modifier.toString(proceed.getModifiers())); 36 counter++; 37 return proceed.invoke(self, args); 38 } 39 } 40 41 static class Interceptor2 implements MethodHandler { 42 int counter = 0; invoke(Object self, Method m, Method proceed, Object[] args)43 public Object invoke(Object self, Method m, Method proceed, 44 Object[] args) throws Exception { 45 System.out.println("intercept: " + m + ", proceed: " + proceed); 46 counter++; 47 if (proceed != null) 48 return proceed.invoke(self, args); 49 else 50 if (m.getReturnType() == int.class) 51 return Integer.valueOf(3); 52 else 53 return "OK"; 54 } 55 } 56 57 static MethodFilter finalizeRemover = new MethodFilter() { 58 public boolean isHandled(Method m) { 59 return !m.getName().equals("finalize"); 60 } 61 }; 62 testTarget()63 public void testTarget() throws Exception { 64 ProxyFactory f = new ProxyFactory(); 65 f.setSuperclass(Target.class); 66 Interceptor1 interceptor = new Interceptor1(); 67 // f.setHandler(interceptor); 68 f.setFilter(finalizeRemover); 69 f.writeDirectory = "."; 70 Class c = f.createClass(); 71 Target obj = (Target)c.getConstructor().newInstance(); 72 ((Proxy)obj).setHandler(interceptor); 73 obj.m(); 74 assertEquals(true, obj.m(true)); 75 assertEquals((byte)1, obj.m1((byte)1)); 76 assertEquals('a', obj.m2('a')); 77 assertEquals((short)2, obj.m3((short)2)); 78 assertEquals(3, obj.m(3)); 79 assertEquals(4L, obj.m5(4L)); 80 assertTrue(5.0F == obj.m6(5.0F)); 81 assertTrue(6.0 == obj.m7(6.0)); 82 assertEquals("test", obj.m("test")); 83 int[] ia = { 1, 2, 3 }; 84 assertEquals(ia, obj.m7(ia)); 85 String[] sa = { "1", "2" }; 86 assertEquals(sa, obj.m8(sa)); 87 assertEquals(obj, obj.m9(3, obj, null)); 88 assertEquals(14, interceptor.counter); 89 } 90 testTarget1()91 public void testTarget1() throws Exception { 92 ProxyFactory f = new ProxyFactory(); 93 f.setSuperclass(Target1.class); 94 Interceptor1 interceptor = new Interceptor1(); 95 // f.setHandler(interceptor); 96 f.setFilter(finalizeRemover); 97 Class c = f.createClass(); 98 Target1 obj = (Target1)c.getConstructor().newInstance(); 99 ((Proxy)obj).setHandler(interceptor); 100 assertEquals(null, obj.m(null)); 101 assertEquals(1, interceptor.counter); 102 } 103 testObject()104 public void testObject() throws Exception { 105 ProxyFactory f = new ProxyFactory(); 106 Interceptor1 interceptor = new Interceptor1(); 107 // f.setHandler(interceptor); 108 f.setFilter(finalizeRemover); 109 Class c = f.createClass(); 110 Object obj = (Object)c.getConstructor().newInstance(); 111 ((Proxy)obj).setHandler(interceptor); 112 System.out.println(obj.toString()); 113 assertEquals(2, interceptor.counter); 114 } 115 testSetter()116 public void testSetter() throws Exception { 117 ProxyFactory f = new ProxyFactory(); 118 f.writeDirectory = "."; 119 Interceptor1 interceptor = new Interceptor1(); 120 // f.setHandler(interceptor); 121 f.setFilter(finalizeRemover); 122 Class c = f.createClass(); 123 Object obj = (Object)c.getConstructor().newInstance(); 124 ((Proxy)obj).setHandler(interceptor); 125 System.out.println("setter1: " + obj.toString()); 126 ((ProxyObject)obj).setHandler(new MethodHandler() { 127 public Object invoke(Object self, Method m, Method proceed, 128 Object[] args) throws Exception { 129 System.out.print("intercept: " + m); 130 return "OK"; 131 } 132 }); 133 assertEquals("OK", obj.toString()); 134 } 135 testString()136 public void testString() throws Exception { 137 ProxyFactory f = new ProxyFactory(); 138 Interceptor1 interceptor = new Interceptor1(); 139 // f.setHandler(interceptor); 140 f.setFilter(finalizeRemover); 141 f.setSuperclass(String.class); 142 try { 143 Class c = f.createClass(); 144 Assert.fail("String is final!"); 145 } 146 catch (RuntimeException e) { 147 System.out.println(e); 148 } 149 } 150 testConstructor()151 public void testConstructor() throws Exception { 152 ProxyFactory f = new ProxyFactory(); 153 Interceptor1 interceptor = new Interceptor1(); 154 // f.setHandler(interceptor); 155 f.setFilter(finalizeRemover); 156 f.setSuperclass(Target2.class); 157 Class c = f.createClass(); 158 Constructor[] cons = c.getDeclaredConstructors(); 159 assertEquals(3, cons.length); 160 Constructor con1 = c.getDeclaredConstructor(new Class[] { int.class }); 161 Constructor con2 = c.getDeclaredConstructor(new Class[] { int.class, int.class }); 162 Method m1 = c.getDeclaredMethod("get", new Class[0]); 163 Method m2 = c.getDeclaredMethod("foo", new Class[0]); 164 assertEquals(0, m1.getExceptionTypes().length); 165 assertEquals("java.io.IOException", m2.getExceptionTypes()[0].getName()); 166 167 Target2 t2 = (Target2)con1.newInstance(new Object[] { Integer.valueOf(1) }); 168 ((Proxy)t2).setHandler(interceptor); 169 System.out.println(t2.toString()); 170 assertEquals(2, interceptor.counter); 171 172 interceptor.counter = 0; 173 assertEquals(2, t2.foo()); 174 assertEquals(4, t2._dfoo()); 175 assertEquals(2, interceptor.counter); 176 } 177 testInterface()178 public void testInterface() throws Exception { 179 ProxyFactory f = new ProxyFactory(); 180 Interceptor2 interceptor2 = new Interceptor2(); 181 // f.setHandler(interceptor2); 182 f.setFilter(finalizeRemover); 183 f.setInterfaces(new Class[] { Target3.class }); 184 Class c = f.createClass(); 185 Target3 obj = (Target3)c.getConstructor().newInstance(); 186 ((Proxy)obj).setHandler(interceptor2); 187 assertEquals("OK", obj.m()); 188 System.out.println(obj.toString()); 189 assertEquals(3, interceptor2.counter); 190 } 191 test2Interfaces()192 public void test2Interfaces() throws Exception { 193 ProxyFactory f = new ProxyFactory(); 194 Interceptor2 interceptor2 = new Interceptor2(); 195 // f.setHandler(interceptor2); 196 f.setFilter(finalizeRemover); 197 f.setInterfaces(new Class[] { Target3.class, Target4.class }); 198 Class c = f.createClass(); 199 Target3 obj = (Target3)c.getConstructor().newInstance(); 200 ((Proxy)obj).setHandler(interceptor2); 201 assertEquals("OK", obj.m()); 202 System.out.println(obj.toString()); 203 assertEquals(3, interceptor2.counter); 204 205 interceptor2.counter = 0; 206 Target4 obj4 = (Target4)c.getConstructor().newInstance(); 207 ((Proxy)obj4).setHandler(interceptor2); 208 assertEquals(3, obj4.bar4()); 209 assertEquals(3, obj4.foo4()); 210 assertEquals(2, interceptor2.counter); 211 } 212 testFilter()213 public void testFilter() throws Exception { 214 ProxyFactory f = new ProxyFactory(); 215 Interceptor2 interceptor2 = new Interceptor2(); 216 // f.setHandler(interceptor2); 217 f.setFilter(finalizeRemover); 218 f.setInterfaces(new Class[] { Target3.class }); 219 f.setFilter(new MethodFilter() { 220 public boolean isHandled(Method m) { 221 return m.getDeclaringClass() != Object.class; 222 } 223 }); 224 Class c = f.createClass(); 225 Target3 obj = (Target3)c.getConstructor().newInstance(); 226 ((Proxy)obj).setHandler(interceptor2); 227 assertEquals("OK", obj.m()); 228 System.out.println(obj.toString()); 229 assertEquals(1, interceptor2.counter); 230 } 231 232 public static boolean testInitFlag; 233 testInit()234 public void testInit() throws Exception { 235 ProxyFactory f = new ProxyFactory(); 236 f.setSuperclass(TargetInit.class); 237 MethodHandler handler = new MethodHandler() { 238 public Object invoke(Object self, Method m, 239 Method proceed, Object[] args) throws Exception { 240 System.out.println("testInit " + testInitFlag); 241 return proceed.invoke(self, args); 242 } 243 }; 244 testInitFlag = false; 245 Class c = f.createClass(); 246 assertTrue(testInitFlag); // since 3.12. Before then, this line was assertFalse(testInitFlag); 247 System.out.println("testInit createClass(): " + testInitFlag); 248 TargetInit obj = (TargetInit)c.getConstructor().newInstance(); 249 assertTrue(testInitFlag); 250 System.out.println("testInit newInstance(): " + testInitFlag); 251 ((ProxyObject)obj).setHandler(handler); 252 assertEquals("OK", obj.m()); 253 } 254 testCreate()255 public void testCreate() throws Exception { 256 ProxyFactory f = new ProxyFactory(); 257 f.setSuperclass(Target5.class); 258 Interceptor1 interceptor = new Interceptor1(); 259 // f.setHandler(interceptor); 260 f.setFilter(finalizeRemover); 261 Class c = f.createClass(); 262 Target5 obj = (Target5)f.create(new Class[] { int.class }, new Object[] { Integer.valueOf(3) }); 263 ((Proxy)obj).setHandler(interceptor); 264 assertEquals(3, obj.get()); 265 } 266 267 testBridgeMethod()268 public void testBridgeMethod() throws Exception { 269 ProxyFactory f = new ProxyFactory(); 270 f.writeDirectory = "."; 271 f.setSuperclass(BridgeMethod.class); 272 Interceptor1 interceptor = new Interceptor1(); 273 // f.setHandler(interceptor); 274 f.setFilter(finalizeRemover); 275 Class c = f.createClass(); 276 BridgeMethod obj = (BridgeMethod)c.getConstructor().newInstance(); 277 ((Proxy)obj).setHandler(interceptor); 278 Integer value = obj.m1(); 279 assertEquals(7, value.intValue()); 280 BridgeMethodInf inf = (BridgeMethodInf)obj; 281 Number num = inf.m1(); 282 assertEquals(7, num.intValue()); 283 BridgeMethodSuper sup = obj; 284 try { 285 Object x = sup.id(new Object()); 286 fail("not cast error"); 287 } 288 catch (ClassCastException e) {} 289 catch (Exception e) { 290 if (e instanceof InvocationTargetException) 291 if (e.getCause() instanceof ClassCastException) 292 return; 293 294 throw e; 295 } 296 } 297 testGetters()298 public void testGetters() throws Exception { 299 ProxyFactory f = new ProxyFactory(); 300 Class c = ProxyTester.class; 301 f.setSuperclass(c); 302 assertEquals(c, f.getSuperclass()); 303 Class i = java.io.Serializable.class; 304 f.setInterfaces(new Class[] { i }); 305 assertEquals(i, f.getInterfaces()[0]); 306 } 307 308 static class ProxyFactory2 extends ProxyFactory { getClassLoader2()309 public ClassLoader getClassLoader2() { 310 return getClassLoader(); 311 } 312 } 313 testProvider()314 public void testProvider() throws Exception { 315 ProxyFactory.ClassLoaderProvider cp = ProxyFactory.classLoaderProvider; 316 try { 317 final ClassLoader cl = Thread.currentThread().getContextClassLoader(); 318 ProxyFactory.classLoaderProvider = new ProxyFactory.ClassLoaderProvider() { 319 public ClassLoader get(ProxyFactory pf) { 320 return Thread.currentThread().getContextClassLoader(); 321 } 322 }; 323 324 ProxyFactory2 pf = new ProxyFactory2(); 325 assertEquals(cl, pf.getClassLoader2()); 326 } 327 finally { 328 ProxyFactory.classLoaderProvider = cp; 329 } 330 } 331 332 @SuppressWarnings("deprecation") testCache()333 public void testCache() throws Exception { 334 boolean prev = ProxyFactory.useCache; 335 ProxyFactory.useCache = true; 336 ProxyFactory f = new ProxyFactory(); 337 f.setSuperclass(Cache1.class); 338 Class c = f.createClass(); 339 ProxyFactory f2 = new ProxyFactory(); 340 f2.setSuperclass(Cache1.class); 341 assertEquals(c, f2.createClass()); 342 ProxyFactory f3 = new ProxyFactory(); 343 f3.setSuperclass(Cache1.class); 344 f3.setHandler(new Interceptor1()); // deprecated 345 assertFalse(c == f3.createClass()); 346 ProxyFactory.useCache = true; 347 ProxyFactory f4 = new ProxyFactory(); 348 f4.setSuperclass(Cache1.class); 349 f4.setInterfaces(new Class[] { Cache2.class }); 350 Class c4 = f4.createClass(); 351 assertFalse(c == c4); 352 ProxyFactory f5 = new ProxyFactory(); 353 f5.setSuperclass(Cache1.class); 354 f5.setInterfaces(new Class[] { Cache2.class }); 355 assertEquals(c4, f5.createClass()); 356 ProxyFactory f6 = new ProxyFactory(); 357 f6.setInterfaces(new Class[] { Cache2.class }); 358 assertFalse(c4 == f6.createClass()); 359 ProxyFactory.useCache = prev; 360 } 361 362 public static class Cache1 { foo()363 public int foo() { return 0; } 364 } 365 366 public static interface Cache2 { bar()367 public int bar(); 368 } 369 testReadWrite()370 public void testReadWrite() throws Exception { 371 final String fileName = "read-write.bin"; 372 ProxyFactory.ClassLoaderProvider cp = ProxyFactory.classLoaderProvider; 373 try { 374 ProxyFactory.classLoaderProvider = new ProxyFactory.ClassLoaderProvider() { 375 public ClassLoader get(ProxyFactory pf) { 376 /* If javassist.Loader is returned, the super type of ReadWriteData class, 377 * which is Serializable, is loaded by javassist.Loader as well as ReadWriteData. 378 * This breaks the implementation of the object serializer. 379 */ 380 // return new javassist.Loader(); 381 return Thread.currentThread().getContextClassLoader(); 382 } 383 }; 384 ProxyFactory pf = new ProxyFactory(); 385 pf.setSuperclass(ReadWriteData.class); 386 Object data = pf.createClass().getConstructor().newInstance(); 387 //Object data = new ReadWriteData(); 388 ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(fileName)); 389 oos.writeObject(data); 390 oos.close(); 391 } 392 finally { 393 ProxyFactory.classLoaderProvider = cp; 394 } 395 396 ObjectInputStream ois = new ObjectInputStream(new FileInputStream(fileName)); 397 Object data2 = ois.readObject(); 398 ois.close(); 399 int i = ((ReadWriteData)data2).foo(); 400 assertEquals(4, i); 401 } 402 403 public static class ReadWriteData implements Serializable { 404 /** default serialVersionUID */ 405 private static final long serialVersionUID = 1L; 406 foo()407 public int foo() { return 4; } 408 } 409 testWriteReplace()410 public void testWriteReplace() throws Exception { 411 ProxyFactory pf = new ProxyFactory(); 412 pf.setSuperclass(WriteReplace.class); 413 Object data = pf.createClass().getConstructor().newInstance(); 414 assertEquals(data, ((WriteReplace)data).writeReplace()); 415 416 ProxyFactory pf2 = new ProxyFactory(); 417 pf2.setSuperclass(WriteReplace2.class); 418 Object data2 = pf2.createClass().getConstructor().newInstance(); 419 Method meth = data2.getClass().getDeclaredMethod("writeReplace", new Class[0]); 420 assertEquals("javassist.util.proxy.SerializedProxy", 421 meth.invoke(data2, new Object[0]).getClass().getName()); 422 } 423 424 public static class WriteReplace implements Serializable { 425 /** default serialVersionUID */ 426 private static final long serialVersionUID = 1L; 427 writeReplace()428 public Object writeReplace() { return this; } 429 } 430 431 public static class WriteReplace2 implements Serializable { 432 /** default serialVersionUID */ 433 private static final long serialVersionUID = 1L; 434 writeReplace(int i)435 public Object writeReplace(int i) { return Integer.valueOf(i); } 436 } 437 testJIRA189()438 public static void testJIRA189() throws Exception { 439 Class persistentClass = Target189.PublishedArticle.class; 440 ProxyFactory factory = new ProxyFactory(); 441 //factory.writeDirectory = "."; 442 factory.setUseCache(false); 443 factory.setSuperclass(persistentClass); 444 factory.setInterfaces(new Class[] { Target189.TestProxy.class }); 445 Class cl = factory.createClass(); 446 Object obj = cl.getConstructor().newInstance(); 447 System.out.println("JIRA189:" + obj.getClass().getClassLoader() + ", " + obj.getClass().getSuperclass().getName() 448 + ", " + Target189.PublishedArticle.class.getClassLoader()); 449 Target189.TestProxy proxy = (Target189.TestProxy)cl.getConstructor().newInstance(); 450 Target189.TestMethodHandler methodHandler = new Target189.TestMethodHandler(); 451 ((ProxyObject)proxy).setHandler(methodHandler); 452 ((Target189.Article)proxy).getIssue(); 453 assertTrue(methodHandler.wasInvokedOnce()); 454 methodHandler.reset(); 455 Target189.PublishedArticle article = (Target189.PublishedArticle)proxy; 456 article.getIssue(); 457 assertTrue(methodHandler.wasInvokedOnce()); 458 } 459 testJIRA127()460 public void testJIRA127() throws Exception { 461 ProxyFactory proxyFactory = new ProxyFactory(); 462 // proxyFactory.writeDirectory = "."; 463 proxyFactory.setInterfaces(new Class[]{ Target127.Sub.class }); 464 Target127.Sub proxy = (Target127.Sub)proxyFactory.create(new Class[0], new Object[0], new MethodHandler() { 465 public Object invoke(Object self, Method thisMethod, Method proceed, Object[] args) throws Throwable { 466 return null; 467 } 468 }); 469 ((Target127.Super)proxy).item(); // proxyFactory must generate a bridge method. 470 ((Target127.Sub)proxy).item(); 471 } 472 main(String[] args)473 public static void main(String[] args) { 474 // javassist.bytecode.ClassFile.MAJOR_VERSION = javassist.bytecode.ClassFile.JAVA_6; 475 junit.textui.TestRunner.run(ProxyTester.class); 476 } 477 } 478