1 /*
2  *  Licensed to the Apache Software Foundation (ASF) under one or more
3  *  contributor license agreements.  See the NOTICE file distributed with
4  *  this work for additional information regarding copyright ownership.
5  *  The ASF licenses this file to You under the Apache License, Version 2.0
6  *  (the "License"); you may not use this file except in compliance with
7  *  the License.  You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  */
17 
18 package org.apache.harmony.tests.java.lang.reflect;
19 
20 import tests.support.Support_Proxy_I1;
21 import tests.support.Support_Proxy_I2;
22 import tests.support.Support_Proxy_ParentException;
23 import tests.support.Support_Proxy_SubException;
24 import java.io.IOException;
25 import java.lang.reflect.InvocationHandler;
26 import java.lang.reflect.Method;
27 import java.lang.reflect.Proxy;
28 import java.lang.reflect.UndeclaredThrowableException;
29 import java.security.AllPermission;
30 import java.security.ProtectionDomain;
31 import java.util.ArrayList;
32 
33 public class ProxyTest extends junit.framework.TestCase {
34 
35     /*
36      * When multiple interfaces define the same method, the list of thrown
37      * exceptions are those which can be mapped to another exception in the
38      * other method:
39      *
40      * String foo(String s) throws SubException, LinkageError;
41      *
42      * UndeclaredThrowableException wrappers any checked exception which is not
43      * in the merged list. So ParentException would be wrapped, BUT LinkageError
44      * would not be since its not an Error/RuntimeException.
45      *
46      * interface I1 { String foo(String s) throws ParentException, LinkageError; }
47      * interface I2 { String foo(String s) throws SubException, Error; }
48      */
49 
50     interface Broken1 {
method(float _number0, float _number1)51         public float method(float _number0, float _number1);
52     }
53 
54     class Broken1Invoke implements InvocationHandler {
invoke(Object proxy, Method method, Object[] args)55         public Object invoke(Object proxy, Method method, Object[] args)
56                 throws Throwable {
57             return args[1];
58         }
59     }
60 
61     class ProxyCoonstructorTest extends Proxy {
ProxyCoonstructorTest(InvocationHandler h)62         protected ProxyCoonstructorTest(InvocationHandler h) {
63             super(h);
64         }
65     }
66 
67     /**
68      * java.lang.reflect.Proxy#getProxyClass(java.lang.ClassLoader,
69      *        java.lang.Class[])
70      */
test_getProxyClassLjava_lang_ClassLoader$Ljava_lang_Class()71     public void test_getProxyClassLjava_lang_ClassLoader$Ljava_lang_Class() {
72         Class proxy = Proxy.getProxyClass(Support_Proxy_I1.class
73                 .getClassLoader(), new Class[] { Support_Proxy_I1.class });
74 
75         assertTrue("Did not create a Proxy subclass ",
76                 proxy.getSuperclass() == Proxy.class);
77         assertTrue("Does not believe its a Proxy class ", Proxy
78                 .isProxyClass(proxy));
79 
80         assertTrue("Does not believe it's a Proxy class ", Proxy
81                 .isProxyClass(Proxy.getProxyClass(null,
82                         new Class[] { Comparable.class })));
83 
84         try {
85             Proxy.getProxyClass(Support_Proxy_I1.class.getClassLoader(),
86                     (Class<?>[]) null);
87             fail("NPE expected");
88         } catch (NullPointerException expected) {
89         }
90 
91         try {
92             Proxy.getProxyClass(Support_Proxy_I1.class.getClassLoader(),
93                     new Class<?>[] {Support_Proxy_I1.class, null});
94             fail("NPE expected");
95         } catch (NullPointerException expected) {
96         }
97     }
98 
99     /**
100      * java.lang.reflect.Proxy#Proxy(java.lang.reflect.InvocationHandler)
101      */
test_ProxyLjava_lang_reflect_InvocationHandler()102     public void test_ProxyLjava_lang_reflect_InvocationHandler() {
103         assertNotNull(new ProxyCoonstructorTest(new InvocationHandler() {
104             public Object invoke(Object proxy, Method method, Object[] args)
105                     throws Throwable {
106                 return null;
107             }
108         }));
109     }
110 
111 
112 
113     /**
114      * java.lang.reflect.Proxy#newProxyInstance(java.lang.ClassLoader,
115      *        java.lang.Class[], java.lang.reflect.InvocationHandler)
116      */
test_newProxyInstanceLjava_lang_ClassLoader$Ljava_lang_ClassLjava_lang_reflect_InvocationHandler()117     public void test_newProxyInstanceLjava_lang_ClassLoader$Ljava_lang_ClassLjava_lang_reflect_InvocationHandler()
118             throws Exception {
119         Object p = Proxy.newProxyInstance(Support_Proxy_I1.class
120                 .getClassLoader(), new Class[] { Support_Proxy_I1.class,
121                 Support_Proxy_I2.class }, new InvocationHandler() {
122             public Object invoke(Object proxy, Method method, Object[] args)
123                     throws Throwable {
124                 if (method.getName().equals("equals"))
125                     return new Boolean(proxy == args[0]);
126                 if (method.getName().equals("array"))
127                     return new int[] { (int) ((long[]) args[0])[1], -1 };
128                 if (method.getName().equals("string")) {
129                     if ("".equals(args[0]))
130                         throw new Support_Proxy_SubException();
131                     if ("clone".equals(args[0]))
132                         throw new Support_Proxy_ParentException();
133                     if ("error".equals(args[0]))
134                         throw new ArrayStoreException();
135                     if ("any".equals(args[0]))
136                         throw new IllegalAccessException();
137                 }
138                 return null;
139             }
140         });
141 
142         Support_Proxy_I1 proxy = (Support_Proxy_I1) p;
143         assertTrue("Failed identity test ", proxy.equals(proxy));
144         assertTrue("Failed not equals test ", !proxy.equals(""));
145         int[] result = (int[]) proxy.array(new long[] { 100L, -200L });
146         assertEquals("Failed primitive type conversion test ", -200, result[0]);
147 
148         try {
149             proxy.string("");
150             fail("Problem converting exception");
151         } catch (Support_Proxy_SubException e) {
152         }
153 
154         try {
155             proxy.string("clone");
156             fail("Problem converting exception");
157         } catch (UndeclaredThrowableException e) {
158             assertSame(Support_Proxy_ParentException.class, e.getCause().getClass());
159         }
160 
161         try {
162             proxy.string("error");
163             fail("Problem converting exception");
164         } catch (ArrayStoreException e) {
165         }
166 
167         try {
168             proxy.string("any");
169             fail("Problem converting exception");
170         } catch (UndeclaredThrowableException e) {
171             assertSame(IllegalAccessException.class, e.getCause().getClass());
172         }
173 
174         Broken1 proxyObject = (Broken1) Proxy.newProxyInstance(Broken1.class
175                 .getClassLoader(), new Class[] { Broken1.class },
176                 new Broken1Invoke());
177 
178         float brokenResult = proxyObject.method(2.1f, 5.8f);
179         assertTrue("Invalid invoke result", brokenResult == 5.8f);
180     }
181 
182     /**
183      * java.lang.reflect.Proxy#isProxyClass(java.lang.Class)
184      */
test_isProxyClassLjava_lang_Class()185     public void test_isProxyClassLjava_lang_Class() {
186         Class proxy = Proxy.getProxyClass(Support_Proxy_I1.class
187                 .getClassLoader(), new Class[] { Support_Proxy_I1.class });
188 
189         class Fake extends Proxy {
190             Fake() {
191                 super(null);
192             }
193         }
194 
195         Proxy fake = new Proxy(new InvocationHandler() {
196             public Object invoke(Object proxy, Method method, Object[] args)
197                     throws Throwable {
198                 return null;
199             }
200         }) {
201         };
202 
203         assertTrue("Does not believe its a Proxy class ", Proxy
204                 .isProxyClass(proxy));
205         assertTrue("Proxy subclasses do not count ", !Proxy
206                 .isProxyClass(Fake.class));
207         assertTrue("Is not a runtime generated Proxy class ", !Proxy
208                 .isProxyClass(fake.getClass()));
209         try{
210              Proxy.isProxyClass(null);
211              fail("NPE was not thrown");
212         } catch (NullPointerException expected){
213         }
214     }
215 
216     /**
217      * java.lang.reflect.Proxy#getInvocationHandler(java.lang.Object)
218      */
test_getInvocationHandlerLjava_lang_Object()219     public void test_getInvocationHandlerLjava_lang_Object() {
220         InvocationHandler handler = new InvocationHandler() {
221             public Object invoke(Object proxy, Method method, Object[] args)
222                     throws Throwable {
223                 return null;
224             }
225         };
226 
227         Object p = Proxy.newProxyInstance(Support_Proxy_I1.class
228                 .getClassLoader(), new Class[] { Support_Proxy_I1.class },
229                 handler);
230 
231         assertTrue("Did not return invocation handler ", Proxy
232                 .getInvocationHandler(p) == handler);
233         try {
234             Proxy.getInvocationHandler("");
235             fail("Did not detect non proxy object");
236         } catch (IllegalArgumentException e) {
237         }
238     }
239 
240     //Regression Test for HARMONY-2355
test_newProxyInstance_withCompatibleReturnTypes()241     public void test_newProxyInstance_withCompatibleReturnTypes() {
242         Object o = Proxy
243                 .newProxyInstance(this.getClass().getClassLoader(),
244                         new Class[] { ITestReturnObject.class,
245                                 ITestReturnString.class },
246                         new TestProxyHandler(new TestProxyImpl()));
247         assertNotNull(o);
248     }
249 
test_newProxyInstance_withNonCompatibleReturnTypes()250     public void test_newProxyInstance_withNonCompatibleReturnTypes() {
251         try {
252             Proxy.newProxyInstance(this.getClass().getClassLoader(),
253                     new Class[] { ITestReturnInteger.class,
254                             ITestReturnString.class }, new TestProxyHandler(
255                             new TestProxyImpl()));
256             fail("should throw IllegalArgumentException");
257         } catch (IllegalArgumentException e) {
258             // expected
259         }
260 
261     }
262 
263     @SuppressWarnings("unchecked")
test_ProxyClass_withParentAndSubInThrowList()264     public void test_ProxyClass_withParentAndSubInThrowList() throws SecurityException, NoSuchMethodException {
265         TestParentIntf myImpl = new MyImplWithParentAndSubInThrowList();
266         Class<?> c = Proxy.getProxyClass(myImpl.getClass().getClassLoader(), myImpl.getClass().getInterfaces());
267         Method m = c.getMethod("test", (Class<?>[]) null);
268         Class<?>[] exceptions = m.getExceptionTypes();
269         ArrayList<Class> exps = new ArrayList<Class>();
270         for (Class<?> exp : exceptions) {
271             exps.add(exp);
272         }
273         assertTrue(exps.contains(Exception.class));
274     }
275 
276     public static interface ITestReturnObject {
f()277         Object f();
278     }
279 
280     public static interface ITestReturnString {
f()281         String f();
282     }
283 
284     public static interface ITestReturnInteger {
f()285         Integer f();
286     }
287 
288     public static class TestProxyImpl implements ITestReturnObject,
289             ITestReturnString {
f()290         public String f() {
291             // do nothing
292             return null;
293         }
294     }
295 
296     public static class TestProxyHandler implements InvocationHandler {
297         private Object proxied;
298 
TestProxyHandler(Object object)299         public TestProxyHandler(Object object) {
300             proxied = object;
301         }
302 
invoke(Object object, Method method, Object[] args)303         public Object invoke(Object object, Method method, Object[] args)
304                 throws Throwable {
305             // do nothing
306             return method.invoke(proxied, args);
307         }
308 
309     }
310 
311     class MyImplWithParentAndSubInThrowList implements TestSubIntf {
test()312         public void test() throws Exception {
313             throw new Exception();
314         }
315     }
316 
317 
setUp()318     protected void setUp() {
319     }
320 
tearDown()321     protected void tearDown() {
322     }
323 }
324 
325 interface PkgIntf {
326 }
327 
328 interface TestParentIntf {
329     //IOException is a subclass of Exception
test()330     public void test() throws IOException, Exception;
331 }
332 
333 interface TestSubIntf extends TestParentIntf {
334 }
335