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.

ProxySimpleTest.java 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  1. package test.javassist.proxy;
  2. import java.io.FileInputStream;
  3. import java.io.FileOutputStream;
  4. import java.io.ObjectInputStream;
  5. import java.io.ObjectOutputStream;
  6. import java.io.Serializable;
  7. import java.lang.reflect.Method;
  8. import javassist.util.proxy.MethodFilter;
  9. import javassist.util.proxy.MethodHandler;
  10. import javassist.util.proxy.Proxy;
  11. import javassist.util.proxy.ProxyFactory;
  12. import junit.framework.TestCase;
  13. @SuppressWarnings({"rawtypes","unchecked"})
  14. public class ProxySimpleTest extends TestCase {
  15. String testResult;
  16. public void testProxyFactory() throws Exception {
  17. ProxyFactory f = new ProxyFactory();
  18. f.writeDirectory = "./proxy";
  19. f.setSuperclass(Foo.class);
  20. f.setFilter(new MethodFilter() {
  21. public boolean isHandled(Method m) {
  22. return m.getName().startsWith("f");
  23. }
  24. });
  25. Class c = f.createClass();
  26. MethodHandler mi = new MethodHandler() {
  27. public Object invoke(Object self, Method m, Method proceed,
  28. Object[] args) throws Throwable {
  29. testResult += args[0].toString();
  30. return proceed.invoke(self, args); // execute the original method.
  31. }
  32. };
  33. Foo foo = (Foo)c.getConstructor().newInstance();
  34. ((Proxy)foo).setHandler(mi);
  35. testResult = "";
  36. foo.foo(1);
  37. foo.foo2(2);
  38. foo.bar(3);
  39. assertEquals("12", testResult);
  40. }
  41. public static class Foo {
  42. public int foo(int i) { return i + 1; }
  43. public int foo2(int i) { return i + 2; }
  44. public int bar(int i) { return i + 1; }
  45. }
  46. public void testReadWrite() throws Exception {
  47. final String fileName = "read-write.bin";
  48. ProxyFactory.ClassLoaderProvider cp = ProxyFactory.classLoaderProvider;
  49. try {
  50. ProxyFactory.classLoaderProvider = new ProxyFactory.ClassLoaderProvider() {
  51. public ClassLoader get(ProxyFactory pf) {
  52. /* If javassist.Loader is returned, the super type of ReadWriteData class,
  53. * which is Serializable, is loaded by javassist.Loader as well as ReadWriteData.
  54. * This breaks the implementation of the object serializer.
  55. */
  56. // return new javassist.Loader();
  57. return Thread.currentThread().getContextClassLoader();
  58. }
  59. };
  60. ProxyFactory pf = new ProxyFactory();
  61. pf.setSuperclass(ReadWriteData.class);
  62. Object data = pf.createClass().getConstructor().newInstance();
  63. // Object data = new ReadWriteData();
  64. ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(fileName));
  65. oos.writeObject(data);
  66. oos.close();
  67. }
  68. finally {
  69. ProxyFactory.classLoaderProvider = cp;
  70. }
  71. ObjectInputStream ois = new ObjectInputStream(new FileInputStream(fileName));
  72. Object data2 = ois.readObject();
  73. ois.close();
  74. int i = ((ReadWriteData)data2).foo();
  75. assertEquals(4, i);
  76. }
  77. public static class ReadWriteData implements Serializable {
  78. /** default serialVersionUID */
  79. private static final long serialVersionUID = 1L;
  80. public int foo() { return 4; }
  81. }
  82. public void testWriteReplace() throws Exception {
  83. ProxyFactory pf = new ProxyFactory();
  84. pf.setSuperclass(WriteReplace.class);
  85. Object data = pf.createClass().getConstructor().newInstance();
  86. assertEquals(data, ((WriteReplace)data).writeReplace());
  87. ProxyFactory pf2 = new ProxyFactory();
  88. pf2.setSuperclass(WriteReplace2.class);
  89. Object data2 = pf2.createClass().getConstructor().newInstance();
  90. Method meth = data2.getClass().getDeclaredMethod("writeReplace", new Class[0]);
  91. assertEquals("javassist.util.proxy.SerializedProxy",
  92. meth.invoke(data2, new Object[0]).getClass().getName());
  93. }
  94. public static class WriteReplace implements Serializable {
  95. /** default serialVersionUID */
  96. private static final long serialVersionUID = 1L;
  97. public Object writeReplace() { return this; }
  98. }
  99. public static class WriteReplace2 implements Serializable {
  100. /** default serialVersionUID */
  101. private static final long serialVersionUID = 1L;
  102. public Object writeReplace(int i) { return Integer.valueOf(i); }
  103. }
  104. String value244;
  105. public void testJIRA244() throws Exception {
  106. ProxyFactory factory = new ProxyFactory();
  107. factory.setSuperclass(Extended244.class);
  108. Extended244 e = (Extended244)factory.create(null, null, new MethodHandler() {
  109. @Override
  110. public Object invoke(Object self, Method thisMethod,
  111. Method proceed, Object[] args) throws Throwable {
  112. value244 += thisMethod.getDeclaringClass().getName();
  113. return proceed.invoke(self);
  114. }
  115. });
  116. value244 = "";
  117. assertEquals("base", e.base());
  118. System.out.println(value244);
  119. assertEquals(Extended244.class.getName(), value244);
  120. value244 = "";
  121. assertEquals("ext", e.extended());
  122. System.out.println(value244);
  123. assertEquals(Extended244.class.getName(), value244);
  124. value244 = "";
  125. assertEquals("base2ext2", e.base2());
  126. System.out.println(value244);
  127. assertEquals(Extended244.class.getName(), value244);
  128. }
  129. // if Base244 is private, then Extended244 has a bridge method for base().
  130. private static abstract class Base244 {
  131. public String base() { return "base"; }
  132. public String base2() { return "base2"; }
  133. }
  134. public static class Extended244 extends Base244 {
  135. public String extended() { return "ext"; }
  136. public String base2() { return super.base2() + "ext2"; }
  137. }
  138. String valueDefaultMethods = "";
  139. public void testDefaultMethods() throws Exception {
  140. valueDefaultMethods = "";
  141. ProxyFactory f = new ProxyFactory();
  142. f.writeDirectory = "./proxy";
  143. f.setSuperclass(Default3.class);
  144. Class c = f.createClass();
  145. MethodHandler mi = new MethodHandler() {
  146. public Object invoke(Object self, Method m, Method proceed,
  147. Object[] args) throws Throwable {
  148. valueDefaultMethods += "1";
  149. return proceed.invoke(self, args); // execute the original method.
  150. }
  151. };
  152. Default3 foo = (Default3)c.getConstructor().newInstance();
  153. ((Proxy)foo).setHandler(mi);
  154. foo.foo();
  155. foo.bar();
  156. assertEquals("11", valueDefaultMethods);
  157. }
  158. public void testDefaultMethods2() throws Exception {
  159. valueDefaultMethods = "";
  160. ProxyFactory f = new ProxyFactory();
  161. f.writeDirectory = "./proxy";
  162. f.setInterfaces(new Class[] { Default2.class });
  163. Class c = f.createClass();
  164. MethodHandler mi = new MethodHandler() {
  165. public Object invoke(Object self, Method m, Method proceed,
  166. Object[] args) throws Throwable {
  167. valueDefaultMethods += "1";
  168. return proceed.invoke(self, args); // execute the original method.
  169. }
  170. };
  171. Default2 foo = (Default2)c.getConstructor().newInstance();
  172. ((Proxy)foo).setHandler(mi);
  173. foo.foo();
  174. foo.bar();
  175. assertEquals("11", valueDefaultMethods);
  176. }
  177. public static interface Default1 {
  178. default int foo() { return 0; }
  179. default int baz() { return 2; }
  180. }
  181. public static interface Default2 extends Default1 {
  182. default int bar() { return 1; }
  183. }
  184. public static class Default3 implements Default2 {
  185. public int foo() { return Default2.super.foo(); }
  186. }
  187. public static class Default4 extends Default3 {
  188. public int baz() { return super.baz(); }
  189. }
  190. public void testPublicProxy() throws Exception {
  191. ProxyFactory f = new ProxyFactory();
  192. f.writeDirectory = "./proxy";
  193. f.setSuperclass(PubProxy.class);
  194. Class c = f.createClass();
  195. MethodHandler mi = new MethodHandler() {
  196. public Object invoke(Object self, Method m, Method proceed,
  197. Object[] args) throws Throwable {
  198. PubProxy.result += args[0].toString();
  199. return proceed.invoke(self, args);
  200. }
  201. };
  202. PubProxy.result = "";
  203. PubProxy foo = (PubProxy)c.getConstructor().newInstance();
  204. ((Proxy)foo).setHandler(mi);
  205. foo.foo(1);
  206. foo.bar(2);
  207. foo.baz(3);
  208. assertEquals("c1p2q3r", PubProxy.result);
  209. }
  210. public static class PubProxy {
  211. public static String result;
  212. public PubProxy() { result += "c"; }
  213. PubProxy(int i) { result += "d"; }
  214. void foo(int i) { result += "p"; }
  215. protected void bar(int i) { result += "q"; }
  216. public void baz(int i) { result += "r"; }
  217. }
  218. public void testPublicProxy2() throws Exception {
  219. boolean b = ProxyFactory.onlyPublicMethods;
  220. ProxyFactory.onlyPublicMethods = true;
  221. ProxyFactory f = new ProxyFactory();
  222. f.writeDirectory = "./proxy";
  223. f.setSuperclass(PubProxy2.class);
  224. Class c = f.createClass();
  225. MethodHandler mi = new MethodHandler() {
  226. public Object invoke(Object self, Method m, Method proceed,
  227. Object[] args) throws Throwable {
  228. PubProxy2.result += args[0].toString();
  229. return proceed.invoke(self, args);
  230. }
  231. };
  232. PubProxy2.result = "";
  233. try {
  234. PubProxy2 foo = (PubProxy2)c.getConstructor().newInstance();
  235. ((Proxy)foo).setHandler(mi);
  236. foo.foo(1); // mi does not intercept this call.
  237. foo.bar(2);
  238. foo.baz(3);
  239. assertEquals("cp2q3r", PubProxy2.result);
  240. }
  241. finally {
  242. ProxyFactory.onlyPublicMethods = b;
  243. }
  244. }
  245. public static class PubProxy2 {
  246. public static String result;
  247. public PubProxy2() { result += "c"; }
  248. PubProxy2(int i) { result += "d"; }
  249. void foo(int i) { result += "p"; }
  250. protected void bar(int i) { result += "q"; }
  251. public void baz(int i) { result += "r"; }
  252. }
  253. String value267;
  254. public void testJIRA267() throws Exception {
  255. Extended267 extended267 = new Extended267();
  256. for (Method method: extended267.getClass().getMethods()) {
  257. System.out.println(method.getName() + "::" + method.getModifiers() + ":" + method.getParameterCount() + ":" + method.isSynthetic() + ":" + method.isBridge());
  258. }
  259. ProxyFactory factory = new ProxyFactory();
  260. factory.setSuperclass(Extended267.class);
  261. Extended267 e = (Extended267)factory.create(null, null, new MethodHandler() {
  262. @Override
  263. public Object invoke(Object self, Method thisMethod,
  264. Method proceed, Object[] args) throws Throwable {
  265. value267 += thisMethod.getDeclaringClass().getName();
  266. return proceed.invoke(self, args);
  267. }
  268. });
  269. value267 = "";
  270. assertEquals("base", e.base());
  271. System.out.println(value267);
  272. assertEquals(Extended267.class.getName(), value267);
  273. value267 = "";
  274. assertEquals("base2", e.base("2"));
  275. System.out.println(value267);
  276. assertEquals(Extended267.class.getName(), value267);
  277. value267 = "";
  278. assertEquals("extended22", e.base(2));
  279. System.out.println(value267);
  280. assertEquals(Extended267.class.getName(), value267);
  281. }
  282. private static abstract class Base267 {
  283. public String base() { return "base"; }
  284. public String base(String s) { return "base" + s; }
  285. public String base(Integer i) { return "base" + i; }
  286. }
  287. public static class Extended267 extends Base267 {
  288. public String base(Integer i) { return "extended" + i + i; }
  289. }
  290. String value267b;
  291. public void testJIRA267b() throws Exception {
  292. Extended267b extended267 = new Extended267b();
  293. ProxyFactory factory = new ProxyFactory();
  294. factory.setSuperclass(Extended267b.class);
  295. Extended267b e = (Extended267b)factory.create(null, null, new MethodHandler() {
  296. @Override
  297. public Object invoke(Object self, Method thisMethod,
  298. Method proceed, Object[] args) throws Throwable {
  299. value267b += thisMethod.getDeclaringClass().getName();
  300. value267b += ";" + thisMethod.getReturnType().getName();
  301. return proceed.invoke(self, args);
  302. }
  303. });
  304. value267b = "";
  305. assertEquals("extended", e.base());
  306. System.out.println(value267b);
  307. assertEquals(Extended267b.class.getName() + ";" + String.class.getName(), value267b);
  308. }
  309. public static class Base267b {
  310. public Object base() { return "base"; }
  311. }
  312. // Extended267b has a bridge method for base():Object,
  313. // since Extended267b#base() is covariant.
  314. public static class Extended267b extends Base267b {
  315. public String base() { return "extended"; }
  316. }
  317. }