You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ProxyCacheGCTest.java 5.1KB

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