blob: c0fa02a50f04e9d9a3f8415f34e09ad0316a6239 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2000-2001 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any questions.
22 */
23
24/* @test
25 *
26 * @summary functional test for RMIClassLoader.loadProxyClass; test
27 * ensures that the default RMI class loader provider implements
28 * RMIClassLoader.loadProxyClass correctly.
29 *
30 * @author Laird Dornin
31 *
32 * @library ../../../testlibrary
33 * @build TestLibrary FnnClass FnnUnmarshal LoadProxyClasses NonpublicInterface
34 * @build NonpublicInterface1 PublicInterface PublicInterface1
35 * @run main/othervm/policy=security.policy LoadProxyClasses
36 */
37
38import java.rmi.server.RMIClassLoader;
39import java.lang.reflect.InvocationHandler;
40import java.lang.reflect.Method;
41import java.lang.reflect.Proxy;
42import java.rmi.MarshalledObject;
43import java.net.URL;
44import java.net.URLClassLoader;
45import java.io.Serializable;
46import java.io.IOException;
47
48import java.util.Arrays;
49import java.util.zip.Checksum;
50
51/**
52 * Invokes RMIClassLoader.loadProxyClass() to load a proxy class with
53 * multiple interfaces using using RMI class unmarshalling. Test is
54 * composed of cases which each unmarshal a proxy class in a
55 * different environment. All of the cases create needed class
56 * loaders, load appropriate interfaces, create a proxy class that
57 * implements those interfaces, create a marshalled object from that
58 * proxy class, and finally call .get() on that object. Get of the
59 * object should pass in some cases and fail in others.
60 *
61 * 1. Nonpublic interface loaded from the parent of the First
62 * Non-Null class Loader on the execution stack (FNNL). Public
63 * interface loaded from grandparent of FNNL parent. Proxy class must
64 * be defined in non-null FNNL parent. Should succeed.
65 *
66 * 2. Nonpublic interface (java.util.zip.ZipConstants) and public
67 * interface (java.util.zip.CheckSum) loaded from bootclasspath,
68 * proxy class defined in null/boot class loader. Should succeed.
69 *
70 * 3. Public interface classes loaded in FNNL are also available in
71 * RMI loader parent. FNNL is grandparent of RMI loader. Proxy class
72 * must be defined in RMI class loader. Should succeed. public
73 * interface must be defined in FNNL.
74 *
75 * 4. Non-public interfaces have multiple class loaders. Should fail
76 * with a LinkageError.
77 *
78 * 5. Interface classes loaded from RMI class loader. Proxy class
79 * defined in RMI class loader.
80 *
81 * 6. Not all interfaces classes can be loaded from a single class
82 * loader; should fail with ClassNotFoundException. All interface
83 * classes will exist (but not all interfaces will be available from
84 * one class loader).
85 *
86 * 7. prove that proxy loader has correct annotation.
87 *
88 * 8. REMIND: may want to add a case where the FNNL is null (This
89 * would be for class unmarshalling in the implemntation of a remote
90 * method invocation).
91 */
92public class LoadProxyClasses {
93
94 private static URL publicUrl = null;
95
96 public static boolean boomerangSemantics = false;
97
98 public static void main(String[] args) {
99 try {
100 System.err.println("\nFunctional test to verify that RMI " +
101 "loads proxy classes correctly\n");
102
103 /* install proxy interfaces */
104 publicUrl =
105 TestLibrary.installClassInCodebase("PublicInterface",
106 "public");
107 URL publicUrl1 =
108 TestLibrary.installClassInCodebase("PublicInterface1",
109 "public1");
110 URL nonpublicUrl =
111 TestLibrary.installClassInCodebase("NonpublicInterface",
112 "nonpublic", false);
113 URL nonpublicUrl1 =
114 TestLibrary.installClassInCodebase("NonpublicInterface1",
115 "nonpublic1", false);
116 URL bothNonpublicUrl =
117 TestLibrary.installClassInCodebase("NonpublicInterface",
118 "bothNonpublic");
119 TestLibrary.installClassInCodebase("NonpublicInterface1",
120 "bothNonpublic");
121 URL fnnUrl =
122 TestLibrary.installClassInCodebase("FnnClass", "fnn");
123
124 TestLibrary.suggestSecurityManager(null);
125
126
127 /* Case 1 */
128 ClassLoader grandParentPublic =
129 new URLClassLoader(new URL[] {publicUrl});
130 ClassLoader parentNonpublic =
131 new URLClassLoader(new URL[] {nonpublicUrl},
132 grandParentPublic);
133 URLClassLoader fnnLoader1 =
134 new URLClassLoader(new URL[] {fnnUrl}, parentNonpublic);
135
136 Class nonpublicInterface =
137 fnnLoader1.loadClass("NonpublicInterface");
138 Class publicInterface =
139 fnnLoader1.loadClass("PublicInterface");
140
141 Proxy proxy1 = (Proxy) Proxy.newProxyInstance(parentNonpublic,
142 new Class[] {nonpublicInterface, publicInterface},
143 new TestInvocationHandler());
144 unmarshalProxyClass(proxy1, fnnLoader1, parentNonpublic, 1, null);
145
146
147
148 /* Case 2 */
149 Class zipConstantsClass =
150 Class.forName("java.util.zip.ZipConstants");
151 URLClassLoader fnnLoader2 =
152 new URLClassLoader(new URL[] {fnnUrl});
153 Proxy proxy2 = (Proxy) Proxy.newProxyInstance(null,
154 new Class[] {zipConstantsClass, Checksum.class},
155 new TestInvocationHandler());
156 unmarshalProxyClass(proxy2, fnnLoader2,
157 (ClassLoader) null, 2, null);
158
159
160
161 /* Case 3 */
162 Thread currentThread = Thread.currentThread();
163 ClassLoader fnnLoader3 = new URLClassLoader(
164 new URL[] {publicUrl, fnnUrl});
165 ClassLoader newCtxLoader =
166 new URLClassLoader(new URL[] {publicUrl}, fnnLoader3);
167 Class publicInterface3 =
168 fnnLoader3.loadClass("PublicInterface");
169 ClassLoader currentCtxLoader =
170 currentThread.getContextClassLoader();
171 currentThread.setContextClassLoader(newCtxLoader);
172
173 Proxy proxy3 = (Proxy) Proxy.newProxyInstance(newCtxLoader,
174 new Class[] {publicInterface3},
175 new TestInvocationHandler());
176
177 unmarshalProxyClass(proxy3, fnnLoader3, fnnLoader3,
178 3, new Case3Checker());
179
180 currentThread.setContextClassLoader(currentCtxLoader);
181
182
183
184 /* Case 4 */
185 ClassLoader bothNonpublicLoader =
186 new URLClassLoader(new URL[] {bothNonpublicUrl});
187 Class nonpublicInterface4a =
188 bothNonpublicLoader.loadClass("NonpublicInterface");
189 Class nonpublicInterface4b =
190 bothNonpublicLoader.loadClass("NonpublicInterface1");
191 Proxy proxy4 = (Proxy) Proxy.newProxyInstance(bothNonpublicLoader,
192 new Class[] {nonpublicInterface4a, nonpublicInterface4b},
193 new TestInvocationHandler());
194
195 ClassLoader nonpublicLoaderA =
196 new URLClassLoader(new URL[] {nonpublicUrl});
197 ClassLoader nonpublicLoaderB =
198 new URLClassLoader(new URL[] {nonpublicUrl1}, nonpublicLoaderA);
199 currentCtxLoader =
200 currentThread.getContextClassLoader();
201 currentThread.setContextClassLoader(nonpublicLoaderB);
202
203 IllegalAccessError illegal = null;
204 try {
205 unmarshalProxyClass(proxy4, fnnLoader2, nonpublicLoaderB,
206 4, null);
207 } catch (IllegalAccessError e) {
208 illegal = e;
209 }
210
211 if (illegal == null) {
212 TestLibrary.bomb("case4: IllegalAccessError not thrown " +
213 "when multiple nonpublic interfaces have \n" +
214 "different class loaders");
215 } else {
216 System.err.println("\ncase4: IllegalAccessError correctly " +
217 "thrown \n when trying to load proxy " +
218 "with multiple nonpublic interfaces in \n" +
219 " different class loaders");
220 }
221 currentThread.setContextClassLoader(currentCtxLoader);
222
223
224
225 /* Case 5*/
226 ClassLoader publicLoader =
227 new URLClassLoader(new URL[] {publicUrl});
228 Class publicInterface5 =
229 publicLoader.loadClass("PublicInterface");
230 Proxy proxy5 = (Proxy) Proxy.newProxyInstance(publicLoader,
231 new Class[] {publicInterface5},
232 new TestInvocationHandler());
233
234 currentCtxLoader =
235 currentThread.getContextClassLoader();
236 currentThread.setContextClassLoader(publicLoader);
237 unmarshalProxyClass(proxy5, fnnLoader2, publicLoader, 5,
238 new Case5Checker());
239 currentThread.setContextClassLoader(currentCtxLoader);
240
241
242
243 /* Case 6 */
244 ClassLoader fnnLoader6 =
245 new URLClassLoader(new URL[] {fnnUrl, publicUrl});
246 ClassLoader publicLoader6 =
247 new URLClassLoader(new URL[] {publicUrl1}, fnnLoader6);
248
249 Class publicInterface6a =
250 publicLoader6.loadClass("PublicInterface1");
251 Class publicInterface6b =
252 fnnLoader6.loadClass("PublicInterface");
253 Proxy proxy6 = (Proxy) Proxy.newProxyInstance(publicLoader6,
254 new Class[] {publicInterface6a, publicInterface6b},
255 new TestInvocationHandler());
256 ClassNotFoundException cnfe = null;
257 try {
258 unmarshalProxyClass(proxy6, fnnLoader6, publicLoader6, 6,
259 null);
260 } catch (ClassNotFoundException e) {
261 cnfe = e;
262 }
263 if (cnfe == null) {
264 TestLibrary.bomb("ClassNotFoundException not thrown " +
265 "when not all proxy interfaces could " +
266 " be found in a single class loader ");
267 } else {
268 System.err.println("Case6: ClassNotFoundException " +
269 "correctly thrown when not all proxy" +
270 " interfaces could be found in a " +
271 "single class loader");
272 cnfe.printStackTrace();
273 }
274
275 System.err.println("TEST PASSED");
276
277 } catch (Exception e) {
278 if (e instanceof RuntimeException) {
279 throw (RuntimeException) e;
280 }
281 TestLibrary.bomb(e);
282 }
283 }
284
285
286 private interface LoadChecker {
287 void checkLoad(Proxy proxy, ClassLoader expectedLoader);
288 }
289
290 private static Proxy unmarshalProxyClass(Proxy proxy,
291 ClassLoader fnnLoader,
292 ClassLoader expectedLoader,
293 int n,
294 LoadChecker checker)
295 throws ClassNotFoundException, IOException,
296 InstantiationException, IllegalAccessException
297 {
298 FnnUnmarshal fnnUnmarshal = (FnnUnmarshal)
299 fnnLoader.loadClass("FnnClass").newInstance();
300 Proxy unmarshalled = (Proxy)
301 fnnUnmarshal.unmarshal(new MarshalledObject(proxy));
302 ClassLoader unmarshalledLoader =
303 unmarshalled.getClass().getClassLoader();
304
305 if (checker != null) {
306 checker.checkLoad(unmarshalled, expectedLoader);
307 } else {
308 if (unmarshalledLoader != expectedLoader) {
309 TestLibrary.bomb("case" + n + ": proxy class not " +
310 "placed into incorrect loader: " +
311 unmarshalledLoader);
312 } else {
313 System.err.println("\ncase" + n + ": proxy class correctly" +
314 " placed into expected loader: " +
315 expectedLoader);
316 }
317 }
318 return proxy;
319 }
320
321 private static class Case3Checker implements LoadChecker {
322 public void checkLoad(Proxy proxy, ClassLoader expectedLoader) {
323 ClassLoader ifaceLoader =
324 proxy.getClass().getInterfaces()[0].getClassLoader();
325 ClassLoader proxyLoader = proxy.getClass().getClassLoader();
326
327 boolean proxyOk = false;
328
329 if (boomerangSemantics) {
330 ClassLoader ctxLoader =
331 Thread.currentThread().getContextClassLoader();
332 if (proxyLoader == ctxLoader) {
333 proxyOk = true;
334 }
335 } else if (proxyLoader.getClass().
336 getName().indexOf("sun.rmi") >= 0)
337 {
338 proxyOk = true;
339 }
340
341 if (proxyOk) {
342 System.err.println("\ncase3: proxy loaded in" +
343 " correct loader: " + proxyLoader +
344 Arrays.asList(((URLClassLoader)
345 proxyLoader).getURLs()));
346 } else {
347 TestLibrary.bomb("case3: proxy class loaded in " +
348 "incorrect loader: " + proxyLoader +
349 Arrays.asList(((URLClassLoader)
350 proxyLoader).getURLs()));
351 }
352
353 if (ifaceLoader == expectedLoader) {
354 System.err.println("case3: proxy interface loaded in" +
355 " correct loader: " + ifaceLoader);
356 } else {
357 TestLibrary.bomb("public proxy interface loaded in " +
358 "incorrect loader: " + ifaceLoader);
359 }
360 }
361 }
362
363 private static class Case5Checker implements LoadChecker {
364 public void checkLoad(Proxy proxy, ClassLoader expectedLoader) {
365 ClassLoader proxyLoader = proxy.getClass().getClassLoader();
366
367 String proxyAnnotation =
368 RMIClassLoader.getClassAnnotation(proxy.getClass());
369
370 if ((proxyAnnotation == null) ||
371 !proxyAnnotation.equals(publicUrl.toString()))
372 {
373 TestLibrary.bomb("proxy class had incorrect annotation: " +
374 proxyAnnotation);
375 } else {
376 System.err.println("proxy class had correct annotation: " +
377 proxyAnnotation);
378 }
379
380 boolean proxyOk = false;
381
382 if (boomerangSemantics) {
383 ClassLoader ctxLoader =
384 Thread.currentThread().getContextClassLoader();
385 if (proxyLoader == ctxLoader) {
386 proxyOk = true;
387 }
388 } else if (proxyLoader.getClass().
389 getName().indexOf("sun.rmi") >= 0)
390 {
391 proxyOk = true;
392 }
393
394 if (proxyOk) {
395 System.err.println("\ncase5: proxy loaded from" +
396 " correct loader: " + proxyLoader);
397 } else {
398 TestLibrary.bomb("case5: proxy interface loaded from " +
399 "incorrect loader: " + proxyLoader);
400 }
401 }
402 }
403
404 private static class TestInvocationHandler
405 implements InvocationHandler, Serializable
406 {
407 public Object invoke(Object proxy, Method method, Object[] args)
408 throws Throwable {return null;}
409 }
410}