1 /*
2  * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 /* @test
25  * @bug 4227192 8004928
26  * @summary This is a test of the restrictions on the parameters that may
27  * be passed to the Proxy.getProxyClass method.
28  * @author Peter Jones
29  *
30  * @build ClassRestrictions
31  * @run main ClassRestrictions
32  */
33 
34 import java.lang.reflect.Modifier;
35 import java.lang.reflect.Proxy;
36 import java.net.URLClassLoader;
37 
38 public class ClassRestrictions {
39 
40     public interface Bar {
foo()41         int foo();
42     }
43 
44     public interface Baz {
foo()45         long foo();
46     }
47 
48     interface Bashful {
foo()49         void foo();
50     }
51 
52     public static final String nonPublicIntrfaceName = "java.util.zip.ZipConstants";
53 
main(String[] args)54     public static void main(String[] args) {
55 
56         System.err.println(
57             "\nTest of restrictions on parameters to Proxy.getProxyClass\n");
58 
59         try {
60             ClassLoader loader = ClassRestrictions.class.getClassLoader();
61             Class<?>[] interfaces;
62             Class<?> proxyClass;
63 
64             /*
65              * All of the Class objects in the interfaces array must represent
66              * interfaces, not classes or primitive types.
67              */
68             try {
69                 interfaces = new Class<?>[] { Object.class };
70                 proxyClass = Proxy.getProxyClass(loader, interfaces);
71                 throw new Error(
72                     "proxy class created with java.lang.Object as interface");
73             } catch (IllegalArgumentException e) {
74                 e.printStackTrace();
75                 System.err.println();
76                 // assume exception is for intended failure
77             }
78             try {
79                 interfaces = new Class<?>[] { Integer.TYPE };
80                 proxyClass = Proxy.getProxyClass(loader, interfaces);
81                 throw new Error(
82                     "proxy class created with int.class as interface");
83             } catch (IllegalArgumentException e) {
84                 e.printStackTrace();
85                 System.err.println();
86                 // assume exception is for intended failure
87             }
88 
89             /*
90              * No two elements in the interfaces array may refer to identical
91              * Class objects.
92              */
93             try {
94                 interfaces = new Class<?>[] { Bar.class, Bar.class };
95                 proxyClass = Proxy.getProxyClass(loader, interfaces);
96                 throw new Error(
97                     "proxy class created with repeated interfaces");
98             } catch (IllegalArgumentException e) {
99                 e.printStackTrace();
100                 System.err.println();
101                 // assume exception is for intended failure
102             }
103 
104             /*
105              * All of the interfaces types must be visible by name though the
106              * specified class loader.
107              */
108             ClassLoader altLoader = new URLClassLoader(
109                 ((URLClassLoader) loader).getURLs(), null);
110             Class altBarClass;
111             altBarClass = Class.forName(Bar.class.getName(), false, altLoader);
112             try {
113                 interfaces = new Class<?>[] { altBarClass };
114                 proxyClass = Proxy.getProxyClass(loader, interfaces);
115                 throw new Error(
116                     "proxy class created with interface " +
117                     "not visible to class loader");
118             } catch (IllegalArgumentException e) {
119                 e.printStackTrace();
120                 System.err.println();
121                 // assume exception is for intended failure
122             }
123 
124             /*
125              * All non-public interfaces must be in the same package.
126              */
127             Class<?> nonPublic1 = Bashful.class;
128             Class<?> nonPublic2 = Class.forName(nonPublicIntrfaceName);
129             if (Modifier.isPublic(nonPublic2.getModifiers())) {
130                 throw new Error(
131                     "Interface " + nonPublicIntrfaceName +
132                     " is public and need to be changed!");
133             }
134             try {
135                 interfaces = new Class<?>[] { nonPublic1, nonPublic2 };
136                 proxyClass = Proxy.getProxyClass(loader, interfaces);
137                 throw new Error(
138                     "proxy class created with two non-public interfaces " +
139                     "in different packages");
140             } catch (IllegalArgumentException e) {
141                 e.printStackTrace();
142                 System.err.println();
143                 // assume exception is for intended failure
144             }
145 
146             /*
147              * No two interfaces may each have a method with the same name and
148              * parameter signature but different return type.
149              */
150             try {
151                 interfaces = new Class<?>[] { Bar.class, Baz.class };
152                 proxyClass = Proxy.getProxyClass(loader, interfaces);
153                 throw new Error(
154                     "proxy class created with conflicting methods");
155             } catch (IllegalArgumentException e) {
156                 e.printStackTrace();
157                 System.err.println();
158                 // assume exception is for intended failure
159             }
160 
161             /*
162              * All components of this test have passed.
163              */
164             System.err.println("\nTEST PASSED");
165 
166         } catch (Throwable e) {
167             System.err.println("\nTEST FAILED:");
168             e.printStackTrace();
169             throw new Error("TEST FAILED: ", e);
170         }
171     }
172 }
173