ProxyTest.java revision 2ad60cfc28e14ee8f0bb038720836a4696c478ad
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
18package tests.api.java.lang.reflect;
19
20import java.lang.reflect.InvocationHandler;
21import java.lang.reflect.Method;
22import java.lang.reflect.Proxy;
23import java.lang.reflect.UndeclaredThrowableException;
24
25import tests.support.Support_Proxy_I1;
26import tests.support.Support_Proxy_I2;
27import tests.support.Support_Proxy_ParentException;
28import tests.support.Support_Proxy_SubException;
29
30public class ProxyTest extends junit.framework.TestCase {
31
32    /*
33     * When multiple interfaces define the same method, the list of thrown
34     * exceptions are those which can be mapped to another exception in the
35     * other method:
36     *
37     * String foo(String s) throws SubException, LinkageError;
38     *
39     * UndeclaredThrowableException wrappers any checked exception which is not
40     * in the merged list. So ParentException would be wrapped, BUT LinkageError
41     * would not be since its not an Error/RuntimeException.
42     *
43     * interface I1 { String foo(String s) throws ParentException, LinkageError; }
44     * interface I2 { String foo(String s) throws SubException, Error; }
45     */
46
47    interface Broken1 {
48        public float method(float _number0, float _number1);
49    }
50
51    class Broken1Invoke implements InvocationHandler {
52        public Object invoke(Object proxy, Method method, Object[] args)
53                throws Throwable {
54            return args[1];
55        }
56    }
57
58    /**
59     * @tests java.lang.reflect.Proxy#getProxyClass(java.lang.ClassLoader,
60     *        java.lang.Class[])
61     */
62    public void test_getProxyClassLjava_lang_ClassLoader$Ljava_lang_Class() {
63        Class proxy = Proxy.getProxyClass(Support_Proxy_I1.class
64                .getClassLoader(), new Class[] { Support_Proxy_I1.class });
65
66        assertTrue("Did not create a Proxy subclass ",
67                proxy.getSuperclass() == Proxy.class);
68        assertTrue("Does not believe its a Proxy class ", Proxy
69                .isProxyClass(proxy));
70
71        assertTrue("Does not believe it's a Proxy class ", Proxy
72                .isProxyClass(Proxy.getProxyClass(null,
73                        new Class[] { Comparable.class })));
74
75        boolean aborted = false;
76        try {
77            Proxy.getProxyClass(null, new Class[] { Support_Proxy_I1.class,
78                    Support_Proxy_I2.class });
79        } catch (IllegalArgumentException e) {
80            aborted = true;
81        }
82        assertTrue("Default classLoader should not see app class ", aborted);
83    }
84
85    /**
86     * @tests java.lang.reflect.Proxy#newProxyInstance(java.lang.ClassLoader,
87     *        java.lang.Class[], java.lang.reflect.InvocationHandler)
88     */
89    public void test_newProxyInstanceLjava_lang_ClassLoader$Ljava_lang_ClassLjava_lang_reflect_InvocationHandler() {
90        Object p = Proxy.newProxyInstance(Support_Proxy_I1.class
91                .getClassLoader(), new Class[] { Support_Proxy_I1.class,
92                Support_Proxy_I2.class }, new InvocationHandler() {
93            public Object invoke(Object proxy, Method method, Object[] args)
94                    throws Throwable {
95                if (method.getName().equals("equals"))
96                    return new Boolean(proxy == args[0]);
97                if (method.getName().equals("array"))
98                    return new int[] { (int) ((long[]) args[0])[1], -1 };
99                if (method.getName().equals("string")) {
100                    if ("".equals(args[0]))
101                        throw new Support_Proxy_SubException();
102                    if ("clone".equals(args[0]))
103                        throw new Support_Proxy_ParentException();
104                    if ("error".equals(args[0]))
105                        throw new ArrayStoreException();
106                    if ("any".equals(args[0]))
107                        throw new IllegalAccessException();
108                }
109                return null;
110            }
111        });
112
113        Support_Proxy_I1 proxy = (Support_Proxy_I1) p;
114        assertTrue("Failed identity test ", proxy.equals(proxy));
115        assertTrue("Failed not equals test ", !proxy.equals(""));
116        int[] result = (int[]) proxy.array(new long[] { 100L, -200L });
117        assertEquals("Failed base type conversion test ", -200, result[0]);
118
119        boolean worked = false;
120        try {
121            proxy.string("");
122        } catch (Support_Proxy_SubException e) {
123            worked = true;
124        } catch (Support_Proxy_ParentException e) { // is never thrown
125        }
126        assertTrue("Problem converting exception ", worked);
127
128        worked = false;
129        try {
130            proxy.string("clone");
131        } catch (Support_Proxy_ParentException e) { // is never thrown
132        } catch (UndeclaredThrowableException e) {
133            worked = true;
134        }
135        assertTrue("Problem converting exception ", worked);
136
137        worked = false;
138        try {
139            proxy.string("error");
140        } catch (Support_Proxy_ParentException e) { // is never thrown
141        } catch (UndeclaredThrowableException e) {
142        } catch (RuntimeException e) {
143            worked = e.getClass() == ArrayStoreException.class;
144        }
145        assertTrue("Problem converting exception ", worked);
146
147        worked = false;
148        try {
149            proxy.string("any");
150        } catch (Support_Proxy_ParentException e) { // is never thrown
151        } catch (UndeclaredThrowableException e) {
152            worked = true;
153        }
154        assertTrue("Problem converting exception ", worked);
155
156        Broken1 proxyObject = null;
157        try {
158            proxyObject = (Broken1) Proxy.newProxyInstance(Broken1.class
159                    .getClassLoader(), new Class[] { Broken1.class },
160                    new Broken1Invoke());
161        } catch (Throwable e) {
162            fail("Failed to create proxy for class: " + Broken1.class + " - "
163                    + e);
164        }
165        float brokenResult = proxyObject.method(2.1f, 5.8f);
166        assertTrue("Invalid invoke result", brokenResult == 5.8f);
167    }
168
169    /**
170     * @tests java.lang.reflect.Proxy#isProxyClass(java.lang.Class)
171     */
172    public void test_isProxyClassLjava_lang_Class() {
173        Class proxy = Proxy.getProxyClass(Support_Proxy_I1.class
174                .getClassLoader(), new Class[] { Support_Proxy_I1.class });
175
176        class Fake extends Proxy {
177            Fake() {
178                super(null);
179            }
180        }
181
182        Proxy fake = new Proxy(new InvocationHandler() {
183            public Object invoke(Object proxy, Method method, Object[] args)
184                    throws Throwable {
185                return null;
186            }
187        }) {
188        };
189
190        assertTrue("Does not believe its a Proxy class ", Proxy
191                .isProxyClass(proxy));
192        assertTrue("Proxy subclasses do not count ", !Proxy
193                .isProxyClass(Fake.class));
194        assertTrue("Is not a runtime generated Proxy class ", !Proxy
195                .isProxyClass(fake.getClass()));
196    }
197
198    /**
199     * @tests java.lang.reflect.Proxy#getInvocationHandler(java.lang.Object)
200     */
201    public void test_getInvocationHandlerLjava_lang_Object() {
202        InvocationHandler handler = new InvocationHandler() {
203            public Object invoke(Object proxy, Method method, Object[] args)
204                    throws Throwable {
205                return null;
206            }
207        };
208
209        Object p = Proxy.newProxyInstance(Support_Proxy_I1.class
210                .getClassLoader(), new Class[] { Support_Proxy_I1.class },
211                handler);
212
213        assertTrue("Did not return invocation handler ", Proxy
214                .getInvocationHandler(p) == handler);
215        boolean aborted = false;
216        try {
217            Proxy.getInvocationHandler("");
218        } catch (IllegalArgumentException e) {
219            aborted = true;
220        }
221        assertTrue("Did not detect non proxy object ", aborted);
222    }
223
224    //Regression Test for HARMONY-2355
225    public void test_newProxyInstance_withCompatibleReturnTypes() {
226        Object o = Proxy
227                .newProxyInstance(this.getClass().getClassLoader(),
228                        new Class[] { ITestReturnObject.class,
229                                ITestReturnString.class },
230                        new TestProxyHandler(new TestProxyImpl()));
231        assertNotNull(o);
232    }
233
234    public void test_newProxyInstance_withNonCompatibleReturnTypes() {
235        try {
236            Proxy.newProxyInstance(this.getClass().getClassLoader(),
237                    new Class[] { ITestReturnInteger.class,
238                            ITestReturnString.class }, new TestProxyHandler(
239                            new TestProxyImpl()));
240            fail("should throw IllegalArgumentException");
241        } catch (IllegalArgumentException e) {
242            // expected
243        }
244
245    }
246
247    public static interface ITestReturnObject {
248        Object f();
249    }
250
251    public static interface ITestReturnString {
252        String f();
253    }
254
255    public static interface ITestReturnInteger {
256        Integer f();
257    }
258
259    public static class TestProxyImpl implements ITestReturnObject,
260            ITestReturnString {
261        public String f() {
262            // do nothing
263            return null;
264        }
265    }
266
267    public static class TestProxyHandler implements InvocationHandler {
268        private Object proxied;
269
270        public TestProxyHandler(Object object) {
271            proxied = object;
272        }
273
274        public Object invoke(Object object, Method method, Object[] args)
275                throws Throwable {
276            // do nothing
277            return method.invoke(proxied, args);
278        }
279
280    }
281
282    protected void setUp() {
283    }
284
285    protected void tearDown() {
286    }
287}
288