• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package test.javassist.proxy;
2 
3 import javassist.*;
4 import javassist.util.proxy.MethodFilter;
5 import javassist.util.proxy.MethodHandler;
6 import javassist.util.proxy.ProxyFactory;
7 import javassist.util.proxy.ProxyObject;
8 import junit.framework.TestCase;
9 
10 /**
11  * test which checks that proxy classes are not retained after their classloader is released.
12  * this is a before and after test which validates JASSIST-104
13  */
14 public class ProxyCacheGCTest extends TestCase
15 {
16     /**
17      * creates a large number of proxies in separate classloaders then lets go of the classloaders and
18      * forces a GC. If we run out of heap then we know there is a problem.
19      */
20 
21     public final static int REPETITION_COUNT = 10000;
22     private ClassPool basePool;
23     private CtClass baseHandler;
24     private CtClass baseFilter;
25 
setUp()26     protected void setUp()
27     {
28         basePool = ClassPool.getDefault();
29         try {
30             baseHandler = basePool.get("javassist.util.proxy.MethodHandler");
31             baseFilter = basePool.get("javassist.util.proxy.MethodFilter");
32         } catch (NotFoundException e) {
33             e.printStackTrace();
34             fail("could not find class " + e);
35         }
36     }
37 
testCacheGC()38     public void testCacheGC()
39     {
40         ClassLoader oldCL = Thread.currentThread().getContextClassLoader();
41         try {
42         ProxyFactory.useCache = false;
43         for (int i = 0; i < REPETITION_COUNT; i++) {
44             ClassLoader newCL = new TestLoader();
45             try {
46                 Thread.currentThread().setContextClassLoader(newCL);
47                 createProxy(i);
48             } finally {
49                 Thread.currentThread().setContextClassLoader(oldCL);
50             }
51         }
52         } finally {
53             ProxyFactory.useCache = true;
54         }
55     }
56 
57     /**
58      * called when a specific classloader is in place on the thread to create a method handler, method filter
59      * and proxy in the current loader and then
60      */
createProxy(int counter)61     public void createProxy(int counter)
62     {
63         try {
64             ClassPool classPool = new ClassPool(basePool);
65 
66             // create a target class in the current class loader
67             String targetName = "test.javassist.MyTarget_" + counter;
68             String targetConstructorName = "MyTarget_" + counter;
69             CtClass ctTargetClass =  classPool.makeClass(targetName);
70             CtMethod targetMethod = CtNewMethod.make("public Object test() { return this; }", ctTargetClass);
71             ctTargetClass.addMethod(targetMethod);
72             CtConstructor targetConstructor = CtNewConstructor.make("public " + targetConstructorName + "() { }", ctTargetClass);
73             ctTargetClass.addConstructor(targetConstructor);
74 
75             // create a handler in the current classloader
76             String handlerName = "test.javassist.MyHandler_" + counter;
77             CtClass ctHandlerClass =  classPool.makeClass(handlerName);
78             ctHandlerClass.addInterface(baseHandler);
79             CtMethod handlerInvoke = CtNewMethod.make("public Object invoke(Object self, java.lang.reflect.Method thisMethod, java.lang.reflect.Method proceed, Object[] args) throws Throwable { return proceed.invoke(self, args); }", ctHandlerClass);
80             ctHandlerClass.addMethod(handlerInvoke);
81 
82             // create a filter in the current classloader
83             String filterName = "test.javassist.MyFilter" + counter;
84             CtClass ctFilterClass =  classPool.makeClass(filterName);
85             ctFilterClass.addInterface(baseFilter);
86             CtMethod filterIsHandled = CtNewMethod.make("public boolean isHandled(java.lang.reflect.Method m) { return true; }", ctFilterClass);
87             ctFilterClass.addMethod(filterIsHandled);
88 
89             // now create a proxyfactory and use it to create a proxy
90 
91             ProxyFactory factory = new ProxyFactory();
92             Class javaTargetClass = classPool.toClass(ctTargetClass);
93             Class javaHandlerClass = classPool.toClass(ctHandlerClass);
94             Class javaFilterClass = classPool.toClass(ctFilterClass);
95 
96             MethodHandler handler= (MethodHandler)javaHandlerClass.newInstance();
97             MethodFilter filter = (MethodFilter)javaFilterClass.newInstance();
98 
99             // ok, now create a factory and a proxy class and proxy from that factory
100             factory.setFilter(filter);
101             factory.setSuperclass(javaTargetClass);
102             // factory.setSuperclass(Object.class);
103 
104             Class proxyClass = factory.createClass();
105             Object target = proxyClass.newInstance();
106             ((ProxyObject)target).setHandler(handler);
107         } catch (Exception e) {
108             e.printStackTrace();
109             fail("cannot create proxy " + e);
110         }
111 
112     }
113 
114     /**
115      * a classloader which inherits from the system class loader and within which a proxy handler,
116      * filter and proxy will be located.
117      */
118     public static class TestLoader extends ClassLoader
119     {
120     }
121 }
122