LoadProxyClasses.java revision 0
0N/A/*
0N/A * Copyright 2000-2001 Sun Microsystems, Inc. All Rights Reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
0N/A * published by the Free Software Foundation.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
0N/A * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0N/A * CA 95054 USA or visit www.sun.com if you need additional information or
0N/A * have any questions.
0N/A */
0N/A
0N/A/* @test
0N/A *
0N/A * @summary functional test for RMIClassLoader.loadProxyClass; test
0N/A * ensures that the default RMI class loader provider implements
0N/A * RMIClassLoader.loadProxyClass correctly.
0N/A *
0N/A * @author Laird Dornin
0N/A *
0N/A * @library ../../../testlibrary
0N/A * @build TestLibrary FnnClass FnnUnmarshal LoadProxyClasses NonpublicInterface
0N/A * @build NonpublicInterface1 PublicInterface PublicInterface1
0N/A * @run main/othervm/policy=security.policy LoadProxyClasses
0N/A */
0N/A
0N/Aimport java.rmi.server.RMIClassLoader;
0N/Aimport java.lang.reflect.InvocationHandler;
0N/Aimport java.lang.reflect.Method;
0N/Aimport java.lang.reflect.Proxy;
0N/Aimport java.rmi.MarshalledObject;
0N/Aimport java.net.URL;
0N/Aimport java.net.URLClassLoader;
0N/Aimport java.io.Serializable;
0N/Aimport java.io.IOException;
0N/A
0N/Aimport java.util.Arrays;
0N/Aimport java.util.zip.Checksum;
0N/A
0N/A/**
0N/A * Invokes RMIClassLoader.loadProxyClass() to load a proxy class with
0N/A * multiple interfaces using using RMI class unmarshalling. Test is
0N/A * composed of cases which each unmarshal a proxy class in a
0N/A * different environment. All of the cases create needed class
0N/A * loaders, load appropriate interfaces, create a proxy class that
0N/A * implements those interfaces, create a marshalled object from that
0N/A * proxy class, and finally call .get() on that object. Get of the
0N/A * object should pass in some cases and fail in others.
0N/A *
0N/A * 1. Nonpublic interface loaded from the parent of the First
0N/A * Non-Null class Loader on the execution stack (FNNL). Public
0N/A * interface loaded from grandparent of FNNL parent. Proxy class must
0N/A * be defined in non-null FNNL parent. Should succeed.
0N/A *
0N/A * 2. Nonpublic interface (java.util.zip.ZipConstants) and public
0N/A * interface (java.util.zip.CheckSum) loaded from bootclasspath,
0N/A * proxy class defined in null/boot class loader. Should succeed.
0N/A *
0N/A * 3. Public interface classes loaded in FNNL are also available in
0N/A * RMI loader parent. FNNL is grandparent of RMI loader. Proxy class
0N/A * must be defined in RMI class loader. Should succeed. public
0N/A * interface must be defined in FNNL.
0N/A *
0N/A * 4. Non-public interfaces have multiple class loaders. Should fail
0N/A * with a LinkageError.
0N/A *
0N/A * 5. Interface classes loaded from RMI class loader. Proxy class
0N/A * defined in RMI class loader.
0N/A *
0N/A * 6. Not all interfaces classes can be loaded from a single class
0N/A * loader; should fail with ClassNotFoundException. All interface
0N/A * classes will exist (but not all interfaces will be available from
0N/A * one class loader).
0N/A *
0N/A * 7. prove that proxy loader has correct annotation.
0N/A *
0N/A * 8. REMIND: may want to add a case where the FNNL is null (This
0N/A * would be for class unmarshalling in the implemntation of a remote
0N/A * method invocation).
0N/A */
0N/Apublic class LoadProxyClasses {
0N/A
0N/A private static URL publicUrl = null;
0N/A
0N/A public static boolean boomerangSemantics = false;
0N/A
0N/A public static void main(String[] args) {
0N/A try {
0N/A System.err.println("\nFunctional test to verify that RMI " +
0N/A "loads proxy classes correctly\n");
0N/A
0N/A /* install proxy interfaces */
0N/A publicUrl =
0N/A TestLibrary.installClassInCodebase("PublicInterface",
0N/A "public");
0N/A URL publicUrl1 =
0N/A TestLibrary.installClassInCodebase("PublicInterface1",
0N/A "public1");
0N/A URL nonpublicUrl =
0N/A TestLibrary.installClassInCodebase("NonpublicInterface",
0N/A "nonpublic", false);
0N/A URL nonpublicUrl1 =
0N/A TestLibrary.installClassInCodebase("NonpublicInterface1",
0N/A "nonpublic1", false);
0N/A URL bothNonpublicUrl =
0N/A TestLibrary.installClassInCodebase("NonpublicInterface",
0N/A "bothNonpublic");
0N/A TestLibrary.installClassInCodebase("NonpublicInterface1",
0N/A "bothNonpublic");
0N/A URL fnnUrl =
0N/A TestLibrary.installClassInCodebase("FnnClass", "fnn");
0N/A
0N/A TestLibrary.suggestSecurityManager(null);
0N/A
0N/A
0N/A /* Case 1 */
0N/A ClassLoader grandParentPublic =
0N/A new URLClassLoader(new URL[] {publicUrl});
0N/A ClassLoader parentNonpublic =
0N/A new URLClassLoader(new URL[] {nonpublicUrl},
0N/A grandParentPublic);
0N/A URLClassLoader fnnLoader1 =
0N/A new URLClassLoader(new URL[] {fnnUrl}, parentNonpublic);
0N/A
0N/A Class nonpublicInterface =
0N/A fnnLoader1.loadClass("NonpublicInterface");
0N/A Class publicInterface =
0N/A fnnLoader1.loadClass("PublicInterface");
0N/A
0N/A Proxy proxy1 = (Proxy) Proxy.newProxyInstance(parentNonpublic,
0N/A new Class[] {nonpublicInterface, publicInterface},
0N/A new TestInvocationHandler());
0N/A unmarshalProxyClass(proxy1, fnnLoader1, parentNonpublic, 1, null);
0N/A
0N/A
0N/A
0N/A /* Case 2 */
0N/A Class zipConstantsClass =
0N/A Class.forName("java.util.zip.ZipConstants");
0N/A URLClassLoader fnnLoader2 =
0N/A new URLClassLoader(new URL[] {fnnUrl});
0N/A Proxy proxy2 = (Proxy) Proxy.newProxyInstance(null,
0N/A new Class[] {zipConstantsClass, Checksum.class},
0N/A new TestInvocationHandler());
0N/A unmarshalProxyClass(proxy2, fnnLoader2,
0N/A (ClassLoader) null, 2, null);
0N/A
0N/A
0N/A
0N/A /* Case 3 */
0N/A Thread currentThread = Thread.currentThread();
0N/A ClassLoader fnnLoader3 = new URLClassLoader(
0N/A new URL[] {publicUrl, fnnUrl});
0N/A ClassLoader newCtxLoader =
0N/A new URLClassLoader(new URL[] {publicUrl}, fnnLoader3);
0N/A Class publicInterface3 =
0N/A fnnLoader3.loadClass("PublicInterface");
0N/A ClassLoader currentCtxLoader =
0N/A currentThread.getContextClassLoader();
0N/A currentThread.setContextClassLoader(newCtxLoader);
0N/A
0N/A Proxy proxy3 = (Proxy) Proxy.newProxyInstance(newCtxLoader,
0N/A new Class[] {publicInterface3},
0N/A new TestInvocationHandler());
0N/A
0N/A unmarshalProxyClass(proxy3, fnnLoader3, fnnLoader3,
0N/A 3, new Case3Checker());
0N/A
0N/A currentThread.setContextClassLoader(currentCtxLoader);
0N/A
0N/A
0N/A
0N/A /* Case 4 */
0N/A ClassLoader bothNonpublicLoader =
0N/A new URLClassLoader(new URL[] {bothNonpublicUrl});
0N/A Class nonpublicInterface4a =
0N/A bothNonpublicLoader.loadClass("NonpublicInterface");
0N/A Class nonpublicInterface4b =
0N/A bothNonpublicLoader.loadClass("NonpublicInterface1");
0N/A Proxy proxy4 = (Proxy) Proxy.newProxyInstance(bothNonpublicLoader,
0N/A new Class[] {nonpublicInterface4a, nonpublicInterface4b},
0N/A new TestInvocationHandler());
0N/A
0N/A ClassLoader nonpublicLoaderA =
0N/A new URLClassLoader(new URL[] {nonpublicUrl});
0N/A ClassLoader nonpublicLoaderB =
0N/A new URLClassLoader(new URL[] {nonpublicUrl1}, nonpublicLoaderA);
0N/A currentCtxLoader =
0N/A currentThread.getContextClassLoader();
0N/A currentThread.setContextClassLoader(nonpublicLoaderB);
0N/A
0N/A IllegalAccessError illegal = null;
0N/A try {
0N/A unmarshalProxyClass(proxy4, fnnLoader2, nonpublicLoaderB,
0N/A 4, null);
0N/A } catch (IllegalAccessError e) {
0N/A illegal = e;
0N/A }
0N/A
0N/A if (illegal == null) {
0N/A TestLibrary.bomb("case4: IllegalAccessError not thrown " +
0N/A "when multiple nonpublic interfaces have \n" +
0N/A "different class loaders");
0N/A } else {
0N/A System.err.println("\ncase4: IllegalAccessError correctly " +
0N/A "thrown \n when trying to load proxy " +
0N/A "with multiple nonpublic interfaces in \n" +
0N/A " different class loaders");
0N/A }
0N/A currentThread.setContextClassLoader(currentCtxLoader);
0N/A
0N/A
0N/A
0N/A /* Case 5*/
0N/A ClassLoader publicLoader =
0N/A new URLClassLoader(new URL[] {publicUrl});
0N/A Class publicInterface5 =
0N/A publicLoader.loadClass("PublicInterface");
0N/A Proxy proxy5 = (Proxy) Proxy.newProxyInstance(publicLoader,
0N/A new Class[] {publicInterface5},
0N/A new TestInvocationHandler());
0N/A
0N/A currentCtxLoader =
0N/A currentThread.getContextClassLoader();
0N/A currentThread.setContextClassLoader(publicLoader);
0N/A unmarshalProxyClass(proxy5, fnnLoader2, publicLoader, 5,
0N/A new Case5Checker());
0N/A currentThread.setContextClassLoader(currentCtxLoader);
0N/A
0N/A
0N/A
0N/A /* Case 6 */
0N/A ClassLoader fnnLoader6 =
0N/A new URLClassLoader(new URL[] {fnnUrl, publicUrl});
0N/A ClassLoader publicLoader6 =
0N/A new URLClassLoader(new URL[] {publicUrl1}, fnnLoader6);
0N/A
0N/A Class publicInterface6a =
0N/A publicLoader6.loadClass("PublicInterface1");
0N/A Class publicInterface6b =
0N/A fnnLoader6.loadClass("PublicInterface");
0N/A Proxy proxy6 = (Proxy) Proxy.newProxyInstance(publicLoader6,
0N/A new Class[] {publicInterface6a, publicInterface6b},
0N/A new TestInvocationHandler());
0N/A ClassNotFoundException cnfe = null;
0N/A try {
0N/A unmarshalProxyClass(proxy6, fnnLoader6, publicLoader6, 6,
0N/A null);
0N/A } catch (ClassNotFoundException e) {
0N/A cnfe = e;
0N/A }
0N/A if (cnfe == null) {
0N/A TestLibrary.bomb("ClassNotFoundException not thrown " +
0N/A "when not all proxy interfaces could " +
0N/A " be found in a single class loader ");
0N/A } else {
0N/A System.err.println("Case6: ClassNotFoundException " +
0N/A "correctly thrown when not all proxy" +
0N/A " interfaces could be found in a " +
0N/A "single class loader");
0N/A cnfe.printStackTrace();
0N/A }
0N/A
0N/A System.err.println("TEST PASSED");
0N/A
0N/A } catch (Exception e) {
0N/A if (e instanceof RuntimeException) {
0N/A throw (RuntimeException) e;
0N/A }
0N/A TestLibrary.bomb(e);
0N/A }
0N/A }
0N/A
0N/A
0N/A private interface LoadChecker {
0N/A void checkLoad(Proxy proxy, ClassLoader expectedLoader);
0N/A }
0N/A
0N/A private static Proxy unmarshalProxyClass(Proxy proxy,
0N/A ClassLoader fnnLoader,
0N/A ClassLoader expectedLoader,
0N/A int n,
0N/A LoadChecker checker)
0N/A throws ClassNotFoundException, IOException,
0N/A InstantiationException, IllegalAccessException
0N/A {
0N/A FnnUnmarshal fnnUnmarshal = (FnnUnmarshal)
0N/A fnnLoader.loadClass("FnnClass").newInstance();
0N/A Proxy unmarshalled = (Proxy)
0N/A fnnUnmarshal.unmarshal(new MarshalledObject(proxy));
0N/A ClassLoader unmarshalledLoader =
0N/A unmarshalled.getClass().getClassLoader();
0N/A
0N/A if (checker != null) {
0N/A checker.checkLoad(unmarshalled, expectedLoader);
0N/A } else {
0N/A if (unmarshalledLoader != expectedLoader) {
0N/A TestLibrary.bomb("case" + n + ": proxy class not " +
0N/A "placed into incorrect loader: " +
0N/A unmarshalledLoader);
0N/A } else {
0N/A System.err.println("\ncase" + n + ": proxy class correctly" +
0N/A " placed into expected loader: " +
0N/A expectedLoader);
0N/A }
0N/A }
0N/A return proxy;
0N/A }
0N/A
0N/A private static class Case3Checker implements LoadChecker {
0N/A public void checkLoad(Proxy proxy, ClassLoader expectedLoader) {
0N/A ClassLoader ifaceLoader =
0N/A proxy.getClass().getInterfaces()[0].getClassLoader();
0N/A ClassLoader proxyLoader = proxy.getClass().getClassLoader();
0N/A
0N/A boolean proxyOk = false;
0N/A
0N/A if (boomerangSemantics) {
0N/A ClassLoader ctxLoader =
0N/A Thread.currentThread().getContextClassLoader();
0N/A if (proxyLoader == ctxLoader) {
0N/A proxyOk = true;
0N/A }
0N/A } else if (proxyLoader.getClass().
0N/A getName().indexOf("sun.rmi") >= 0)
0N/A {
0N/A proxyOk = true;
0N/A }
0N/A
0N/A if (proxyOk) {
0N/A System.err.println("\ncase3: proxy loaded in" +
0N/A " correct loader: " + proxyLoader +
0N/A Arrays.asList(((URLClassLoader)
0N/A proxyLoader).getURLs()));
0N/A } else {
0N/A TestLibrary.bomb("case3: proxy class loaded in " +
0N/A "incorrect loader: " + proxyLoader +
0N/A Arrays.asList(((URLClassLoader)
0N/A proxyLoader).getURLs()));
0N/A }
0N/A
0N/A if (ifaceLoader == expectedLoader) {
0N/A System.err.println("case3: proxy interface loaded in" +
0N/A " correct loader: " + ifaceLoader);
0N/A } else {
0N/A TestLibrary.bomb("public proxy interface loaded in " +
0N/A "incorrect loader: " + ifaceLoader);
0N/A }
0N/A }
0N/A }
0N/A
0N/A private static class Case5Checker implements LoadChecker {
0N/A public void checkLoad(Proxy proxy, ClassLoader expectedLoader) {
0N/A ClassLoader proxyLoader = proxy.getClass().getClassLoader();
0N/A
0N/A String proxyAnnotation =
0N/A RMIClassLoader.getClassAnnotation(proxy.getClass());
0N/A
0N/A if ((proxyAnnotation == null) ||
0N/A !proxyAnnotation.equals(publicUrl.toString()))
0N/A {
0N/A TestLibrary.bomb("proxy class had incorrect annotation: " +
0N/A proxyAnnotation);
0N/A } else {
0N/A System.err.println("proxy class had correct annotation: " +
0N/A proxyAnnotation);
0N/A }
0N/A
0N/A boolean proxyOk = false;
0N/A
0N/A if (boomerangSemantics) {
0N/A ClassLoader ctxLoader =
0N/A Thread.currentThread().getContextClassLoader();
0N/A if (proxyLoader == ctxLoader) {
0N/A proxyOk = true;
0N/A }
0N/A } else if (proxyLoader.getClass().
0N/A getName().indexOf("sun.rmi") >= 0)
0N/A {
0N/A proxyOk = true;
0N/A }
0N/A
0N/A if (proxyOk) {
0N/A System.err.println("\ncase5: proxy loaded from" +
0N/A " correct loader: " + proxyLoader);
0N/A } else {
0N/A TestLibrary.bomb("case5: proxy interface loaded from " +
0N/A "incorrect loader: " + proxyLoader);
0N/A }
0N/A }
0N/A }
0N/A
0N/A private static class TestInvocationHandler
0N/A implements InvocationHandler, Serializable
0N/A {
0N/A public Object invoke(Object proxy, Method method, Object[] args)
0N/A throws Throwable {return null;}
0N/A }
0N/A}