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