summaryrefslogtreecommitdiffstats
path: root/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/reflect/ProxyTest.java
blob: 86383bde29bb0cbdf72799bd7a1d7550bdba09d3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package org.apache.harmony.tests.java.lang.reflect;

import tests.support.Support_Proxy_I1;
import tests.support.Support_Proxy_I2;
import tests.support.Support_Proxy_ParentException;
import tests.support.Support_Proxy_SubException;
import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
import java.security.AllPermission;
import java.security.ProtectionDomain;
import java.util.ArrayList;

public class ProxyTest extends junit.framework.TestCase {

    /*
     * When multiple interfaces define the same method, the list of thrown
     * exceptions are those which can be mapped to another exception in the
     * other method:
     *
     * String foo(String s) throws SubException, LinkageError;
     *
     * UndeclaredThrowableException wrappers any checked exception which is not
     * in the merged list. So ParentException would be wrapped, BUT LinkageError
     * would not be since its not an Error/RuntimeException.
     *
     * interface I1 { String foo(String s) throws ParentException, LinkageError; }
     * interface I2 { String foo(String s) throws SubException, Error; }
     */

    interface Broken1 {
        public float method(float _number0, float _number1);
    }

    class Broken1Invoke implements InvocationHandler {
        public Object invoke(Object proxy, Method method, Object[] args)
                throws Throwable {
            return args[1];
        }
    }

    class ProxyCoonstructorTest extends Proxy {
        protected ProxyCoonstructorTest(InvocationHandler h) {
            super(h);
        }
    }

    /**
     * java.lang.reflect.Proxy#getProxyClass(java.lang.ClassLoader,
     *        java.lang.Class[])
     */
    public void test_getProxyClassLjava_lang_ClassLoader$Ljava_lang_Class() {
        Class proxy = Proxy.getProxyClass(Support_Proxy_I1.class
                .getClassLoader(), new Class[] { Support_Proxy_I1.class });

        assertTrue("Did not create a Proxy subclass ",
                proxy.getSuperclass() == Proxy.class);
        assertTrue("Does not believe its a Proxy class ", Proxy
                .isProxyClass(proxy));

        assertTrue("Does not believe it's a Proxy class ", Proxy
                .isProxyClass(Proxy.getProxyClass(null,
                        new Class[] { Comparable.class })));

        try {
            Proxy.getProxyClass(Support_Proxy_I1.class.getClassLoader(),
                    (Class<?>[]) null);
            fail("NPE expected");
        } catch (NullPointerException expected) {
        }

        try {
            Proxy.getProxyClass(Support_Proxy_I1.class.getClassLoader(),
                    new Class<?>[] {Support_Proxy_I1.class, null});
            fail("NPE expected");
        } catch (NullPointerException expected) {
        }
    }

    /**
     * java.lang.reflect.Proxy#Proxy(java.lang.reflect.InvocationHandler)
     */
    public void test_ProxyLjava_lang_reflect_InvocationHandler() {
        assertNotNull(new ProxyCoonstructorTest(new InvocationHandler() {
            public Object invoke(Object proxy, Method method, Object[] args)
                    throws Throwable {
                return null;
            }
        }));
    }



    /**
     * java.lang.reflect.Proxy#newProxyInstance(java.lang.ClassLoader,
     *        java.lang.Class[], java.lang.reflect.InvocationHandler)
     */
    public void test_newProxyInstanceLjava_lang_ClassLoader$Ljava_lang_ClassLjava_lang_reflect_InvocationHandler()
            throws Exception {
        Object p = Proxy.newProxyInstance(Support_Proxy_I1.class
                .getClassLoader(), new Class[] { Support_Proxy_I1.class,
                Support_Proxy_I2.class }, new InvocationHandler() {
            public Object invoke(Object proxy, Method method, Object[] args)
                    throws Throwable {
                if (method.getName().equals("equals"))
                    return new Boolean(proxy == args[0]);
                if (method.getName().equals("array"))
                    return new int[] { (int) ((long[]) args[0])[1], -1 };
                if (method.getName().equals("string")) {
                    if ("".equals(args[0]))
                        throw new Support_Proxy_SubException();
                    if ("clone".equals(args[0]))
                        throw new Support_Proxy_ParentException();
                    if ("error".equals(args[0]))
                        throw new ArrayStoreException();
                    if ("any".equals(args[0]))
                        throw new IllegalAccessException();
                }
                return null;
            }
        });

        Support_Proxy_I1 proxy = (Support_Proxy_I1) p;
        assertTrue("Failed identity test ", proxy.equals(proxy));
        assertTrue("Failed not equals test ", !proxy.equals(""));
        int[] result = (int[]) proxy.array(new long[] { 100L, -200L });
        assertEquals("Failed primitive type conversion test ", -200, result[0]);

        try {
            proxy.string("");
            fail("Problem converting exception");
        } catch (Support_Proxy_SubException e) {
        }

        try {
            proxy.string("clone");
            fail("Problem converting exception");
        } catch (UndeclaredThrowableException e) {
            assertSame(Support_Proxy_ParentException.class, e.getCause().getClass());
        }

        try {
            proxy.string("error");
            fail("Problem converting exception");
        } catch (ArrayStoreException e) {
        }

        try {
            proxy.string("any");
            fail("Problem converting exception");
        } catch (UndeclaredThrowableException e) {
            assertSame(IllegalAccessException.class, e.getCause().getClass());
        }

        Broken1 proxyObject = (Broken1) Proxy.newProxyInstance(Broken1.class
                .getClassLoader(), new Class[] { Broken1.class },
                new Broken1Invoke());

        float brokenResult = proxyObject.method(2.1f, 5.8f);
        assertTrue("Invalid invoke result", brokenResult == 5.8f);
    }

    /**
     * java.lang.reflect.Proxy#isProxyClass(java.lang.Class)
     */
    public void test_isProxyClassLjava_lang_Class() {
        Class proxy = Proxy.getProxyClass(Support_Proxy_I1.class
                .getClassLoader(), new Class[] { Support_Proxy_I1.class });

        class Fake extends Proxy {
            Fake() {
                super(null);
            }
        }

        Proxy fake = new Proxy(new InvocationHandler() {
            public Object invoke(Object proxy, Method method, Object[] args)
                    throws Throwable {
                return null;
            }
        }) {
        };

        assertTrue("Does not believe its a Proxy class ", Proxy
                .isProxyClass(proxy));
        assertTrue("Proxy subclasses do not count ", !Proxy
                .isProxyClass(Fake.class));
        assertTrue("Is not a runtime generated Proxy class ", !Proxy
                .isProxyClass(fake.getClass()));
        try{
             Proxy.isProxyClass(null);
             fail("NPE was not thrown");
        } catch (NullPointerException expected){
        }
    }

    /**
     * java.lang.reflect.Proxy#getInvocationHandler(java.lang.Object)
     */
    public void test_getInvocationHandlerLjava_lang_Object() {
        InvocationHandler handler = new InvocationHandler() {
            public Object invoke(Object proxy, Method method, Object[] args)
                    throws Throwable {
                return null;
            }
        };

        Object p = Proxy.newProxyInstance(Support_Proxy_I1.class
                .getClassLoader(), new Class[] { Support_Proxy_I1.class },
                handler);

        assertTrue("Did not return invocation handler ", Proxy
                .getInvocationHandler(p) == handler);
        try {
            Proxy.getInvocationHandler("");
            fail("Did not detect non proxy object");
        } catch (IllegalArgumentException e) {
        }
    }

    //Regression Test for HARMONY-2355
    public void test_newProxyInstance_withCompatibleReturnTypes() {
        Object o = Proxy
                .newProxyInstance(this.getClass().getClassLoader(),
                        new Class[] { ITestReturnObject.class,
                                ITestReturnString.class },
                        new TestProxyHandler(new TestProxyImpl()));
        assertNotNull(o);
    }

    public void test_newProxyInstance_withNonCompatibleReturnTypes() {
        try {
            Proxy.newProxyInstance(this.getClass().getClassLoader(),
                    new Class[] { ITestReturnInteger.class,
                            ITestReturnString.class }, new TestProxyHandler(
                            new TestProxyImpl()));
            fail("should throw IllegalArgumentException");
        } catch (IllegalArgumentException e) {
            // expected
        }

    }

    @SuppressWarnings("unchecked")
    public void test_ProxyClass_withParentAndSubInThrowList() throws SecurityException, NoSuchMethodException {
        TestParentIntf myImpl = new MyImplWithParentAndSubInThrowList();
        Class<?> c = Proxy.getProxyClass(myImpl.getClass().getClassLoader(), myImpl.getClass().getInterfaces());
        Method m = c.getMethod("test", (Class<?>[]) null);
        Class<?>[] exceptions = m.getExceptionTypes();
        ArrayList<Class> exps = new ArrayList<Class>();
        for (Class<?> exp : exceptions) {
            exps.add(exp);
        }
        assertTrue(exps.contains(Exception.class));
    }

    public static interface ITestReturnObject {
        Object f();
    }

    public static interface ITestReturnString {
        String f();
    }

    public static interface ITestReturnInteger {
        Integer f();
    }

    public static class TestProxyImpl implements ITestReturnObject,
            ITestReturnString {
        public String f() {
            // do nothing
            return null;
        }
    }

    public static class TestProxyHandler implements InvocationHandler {
        private Object proxied;

        public TestProxyHandler(Object object) {
            proxied = object;
        }

        public Object invoke(Object object, Method method, Object[] args)
                throws Throwable {
            // do nothing
            return method.invoke(proxied, args);
        }

    }

    class MyImplWithParentAndSubInThrowList implements TestSubIntf {
        public void test() throws Exception {
            throw new Exception();
        }
    }


    protected void setUp() {
    }

    protected void tearDown() {
    }
}

interface PkgIntf {
}

interface TestParentIntf {
    //IOException is a subclass of Exception
    public void test() throws IOException, Exception;
}

interface TestSubIntf extends TestParentIntf {
}