alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (LoadProxyClasses.java)

This example Java source code file (LoadProxyClasses.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

class, classloader, classnotfoundexception, fnnclass, fnnunmarshal, illegalaccesserror, loadchecker, net, network, nonpublicinterface, nonpublicinterface1, proxy, publicinterface, reflection, rmi, testinvocationhandler, url, urlclassloader, util, zip

The LoadProxyClasses.java Java example source code

/*
 * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/* @test
 *
 * @summary functional test for RMIClassLoader.loadProxyClass; test
 * ensures that the default RMI class loader provider implements
 * RMIClassLoader.loadProxyClass correctly.
 *
 * @author Laird Dornin
 *
 * @library ../../../testlibrary
 * @build TestLibrary FnnClass FnnUnmarshal NonpublicInterface
 *     NonpublicInterface1 PublicInterface PublicInterface1
 * @run main/othervm/policy=security.policy
 *     -Djava.rmi.server.useCodebaseOnly=false LoadProxyClasses
 */

import java.rmi.server.RMIClassLoader;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.rmi.MarshalledObject;
import java.net.URL;
import java.net.URLClassLoader;
import java.io.Serializable;
import java.io.IOException;

import java.util.Arrays;
import java.util.zip.Checksum;

/**
 *  Invokes RMIClassLoader.loadProxyClass() to load a proxy class with
 *  multiple interfaces using using RMI class unmarshalling.  Test is
 *  composed of cases which each unmarshal a proxy class in a
 *  different environment.  All of the cases create needed class
 *  loaders, load appropriate interfaces, create a proxy class that
 *  implements those interfaces, create a marshalled object from that
 *  proxy class, and finally call .get() on that object.  Get of the
 *  object should pass in some cases and fail in others.
 *
 *  1. Nonpublic interface loaded from the parent of the First
 *  Non-Null class Loader on the execution stack (FNNL).  Public
 *  interface loaded from grandparent of FNNL parent. Proxy class must
 *  be defined in non-null FNNL parent. Should succeed.
 *
 *  2. Nonpublic interface (java.util.zip.ZipConstants) and public
 *  interface (java.util.zip.CheckSum) loaded from bootclasspath,
 *  proxy class defined in null/boot class loader.  Should succeed.
 *
 *  3. Public interface classes loaded in FNNL are also available in
 *  RMI loader parent.  FNNL is grandparent of RMI loader. Proxy class
 *  must be defined in RMI class loader. Should succeed. public
 *  interface must be defined in FNNL.
 *
 *  4. Non-public interfaces have multiple class loaders. Should fail
 *  with a LinkageError.
 *
 *  5. Interface classes loaded from RMI class loader. Proxy class
 *  defined in RMI class loader.
 *
 *  6. Not all interfaces classes can be loaded from a single class
 *  loader; should fail with ClassNotFoundException.  All interface
 *  classes will exist (but not all interfaces will be available from
 *  one class loader).
 *
 *  7. prove that proxy loader has correct annotation.
 *
 *  8. REMIND: may want to add a case where the FNNL is null (This
 *  would be for class unmarshalling in the implemntation of a remote
 *  method invocation).
 */
public class LoadProxyClasses {

    private static URL publicUrl = null;

    public static boolean boomerangSemantics = false;

    public static void main(String[] args) {
        try {
            System.err.println("\nFunctional test to verify that RMI " +
                               "loads proxy classes correctly\n");

            /* install proxy interfaces */
            publicUrl =
                TestLibrary.installClassInCodebase("PublicInterface",
                                                   "public");
            URL publicUrl1 =
                TestLibrary.installClassInCodebase("PublicInterface1",
                                                   "public1");
            URL nonpublicUrl =
                TestLibrary.installClassInCodebase("NonpublicInterface",
                                                   "nonpublic", false);
            URL nonpublicUrl1 =
                TestLibrary.installClassInCodebase("NonpublicInterface1",
                                                   "nonpublic1", false);
            URL bothNonpublicUrl =
                TestLibrary.installClassInCodebase("NonpublicInterface",
                                                   "bothNonpublic");
            TestLibrary.installClassInCodebase("NonpublicInterface1",
                                               "bothNonpublic");
            URL fnnUrl =
                TestLibrary.installClassInCodebase("FnnClass", "fnn");

            TestLibrary.suggestSecurityManager(null);


            /* Case 1 */
            ClassLoader grandParentPublic =
                new URLClassLoader(new URL[] {publicUrl});
            ClassLoader parentNonpublic =
                new URLClassLoader(new URL[] {nonpublicUrl},
                                   grandParentPublic);
            URLClassLoader fnnLoader1 =
                new URLClassLoader(new URL[] {fnnUrl}, parentNonpublic);

            Class nonpublicInterface =
                fnnLoader1.loadClass("NonpublicInterface");
            Class publicInterface =
                fnnLoader1.loadClass("PublicInterface");

            Proxy proxy1 = (Proxy) Proxy.newProxyInstance(parentNonpublic,
                new Class[] {nonpublicInterface, publicInterface},
                new TestInvocationHandler());
            unmarshalProxyClass(proxy1, fnnLoader1, parentNonpublic, 1, null);



            /* Case 2 */
            Class zipConstantsClass =
                Class.forName("java.util.zip.ZipConstants");
            URLClassLoader fnnLoader2 =
                new URLClassLoader(new URL[] {fnnUrl});
            Proxy proxy2 = (Proxy) Proxy.newProxyInstance(null,
                new Class[] {zipConstantsClass, Checksum.class},
                new TestInvocationHandler());
            unmarshalProxyClass(proxy2, fnnLoader2,
                                (ClassLoader) null, 2, null);



            /* Case 3 */
            Thread currentThread = Thread.currentThread();
            ClassLoader fnnLoader3 = new URLClassLoader(
                new URL[] {publicUrl, fnnUrl});
            ClassLoader newCtxLoader =
                new URLClassLoader(new URL[] {publicUrl}, fnnLoader3);
            Class publicInterface3 =
                fnnLoader3.loadClass("PublicInterface");
            ClassLoader currentCtxLoader =
                currentThread.getContextClassLoader();
            currentThread.setContextClassLoader(newCtxLoader);

            Proxy proxy3 = (Proxy) Proxy.newProxyInstance(newCtxLoader,
                new Class[] {publicInterface3},
                new TestInvocationHandler());

            unmarshalProxyClass(proxy3, fnnLoader3, fnnLoader3,
                3, new Case3Checker());

            currentThread.setContextClassLoader(currentCtxLoader);



            /* Case 4 */
            ClassLoader bothNonpublicLoader =
                new URLClassLoader(new URL[] {bothNonpublicUrl});
            Class nonpublicInterface4a =
                bothNonpublicLoader.loadClass("NonpublicInterface");
            Class nonpublicInterface4b =
                bothNonpublicLoader.loadClass("NonpublicInterface1");
            Proxy proxy4 = (Proxy) Proxy.newProxyInstance(bothNonpublicLoader,
                new Class[] {nonpublicInterface4a, nonpublicInterface4b},
                new TestInvocationHandler());

            ClassLoader nonpublicLoaderA =
                new URLClassLoader(new URL[] {nonpublicUrl});
            ClassLoader nonpublicLoaderB =
                new URLClassLoader(new URL[] {nonpublicUrl1}, nonpublicLoaderA);
            currentCtxLoader =
                currentThread.getContextClassLoader();
            currentThread.setContextClassLoader(nonpublicLoaderB);

            IllegalAccessError illegal = null;
            try {
                unmarshalProxyClass(proxy4, fnnLoader2, nonpublicLoaderB,
                                    4, null);
            } catch (IllegalAccessError e) {
                illegal = e;
            }

            if (illegal == null) {
                TestLibrary.bomb("case4: IllegalAccessError not thrown " +
                                 "when multiple nonpublic interfaces have \n" +
                                 "different class loaders");
            } else {
                System.err.println("\ncase4: IllegalAccessError correctly " +
                                   "thrown \n when trying to load proxy " +
                                   "with multiple nonpublic interfaces in \n" +
                                   "  different class loaders");
            }
            currentThread.setContextClassLoader(currentCtxLoader);



            /* Case 5*/
            ClassLoader publicLoader =
                new URLClassLoader(new URL[] {publicUrl});
            Class publicInterface5 =
                publicLoader.loadClass("PublicInterface");
            Proxy proxy5 = (Proxy) Proxy.newProxyInstance(publicLoader,
                new Class[] {publicInterface5},
                new TestInvocationHandler());

            currentCtxLoader =
                currentThread.getContextClassLoader();
            currentThread.setContextClassLoader(publicLoader);
            unmarshalProxyClass(proxy5, fnnLoader2, publicLoader, 5,
                                new Case5Checker());
            currentThread.setContextClassLoader(currentCtxLoader);



            /* Case 6 */
            ClassLoader fnnLoader6 =
                new URLClassLoader(new URL[] {fnnUrl, publicUrl});
            ClassLoader publicLoader6 =
                new URLClassLoader(new URL[] {publicUrl1}, fnnLoader6);

            Class publicInterface6a =
                publicLoader6.loadClass("PublicInterface1");
            Class publicInterface6b =
                fnnLoader6.loadClass("PublicInterface");
            Proxy proxy6 = (Proxy) Proxy.newProxyInstance(publicLoader6,
                new Class[] {publicInterface6a, publicInterface6b},
                new TestInvocationHandler());
            ClassNotFoundException cnfe = null;
            try {
                unmarshalProxyClass(proxy6, fnnLoader6, publicLoader6, 6,
                                    null);
            } catch (ClassNotFoundException e) {
                cnfe = e;
            }
            if (cnfe == null) {
                TestLibrary.bomb("ClassNotFoundException not thrown " +
                                 "when not all proxy interfaces could " +
                                 " be found in a single class loader ");
            } else {
                System.err.println("Case6: ClassNotFoundException " +
                                   "correctly thrown when not all proxy" +
                                   " interfaces could be found in a " +
                                   "single class loader");
                cnfe.printStackTrace();
            }

            System.err.println("TEST PASSED");

        } catch (Exception e) {
            if (e instanceof RuntimeException) {
                throw (RuntimeException) e;
            }
            TestLibrary.bomb(e);
        }
    }


    private interface LoadChecker {
        void checkLoad(Proxy proxy, ClassLoader expectedLoader);
    }

    private static Proxy unmarshalProxyClass(Proxy proxy,
                                             ClassLoader fnnLoader,
                                             ClassLoader expectedLoader,
                                             int n,
                                             LoadChecker checker)
        throws ClassNotFoundException, IOException,
               InstantiationException, IllegalAccessException
    {
        FnnUnmarshal fnnUnmarshal = (FnnUnmarshal)
                fnnLoader.loadClass("FnnClass").newInstance();
        Proxy unmarshalled = (Proxy)
            fnnUnmarshal.unmarshal(new MarshalledObject(proxy));
        ClassLoader unmarshalledLoader =
            unmarshalled.getClass().getClassLoader();

        if (checker != null) {
            checker.checkLoad(unmarshalled, expectedLoader);
        } else {
            if (unmarshalledLoader != expectedLoader) {
                TestLibrary.bomb("case" + n + ": proxy class not " +
                                 "placed into incorrect loader: " +
                                 unmarshalledLoader);
            } else {
                System.err.println("\ncase" + n + ": proxy class correctly" +
                                   " placed into expected loader: " +
                                   expectedLoader);
            }
        }
        return proxy;
    }

    private static class Case3Checker implements LoadChecker {
        public void checkLoad(Proxy proxy, ClassLoader expectedLoader) {
            ClassLoader ifaceLoader =
                proxy.getClass().getInterfaces()[0].getClassLoader();
            ClassLoader proxyLoader = proxy.getClass().getClassLoader();

            boolean proxyOk = false;

            if (boomerangSemantics) {
                ClassLoader ctxLoader =
                    Thread.currentThread().getContextClassLoader();
                if (proxyLoader == ctxLoader) {
                    proxyOk = true;
                }
            } else if (proxyLoader.getClass().
                       getName().indexOf("sun.rmi") >= 0)
            {
                proxyOk = true;
            }

            if (proxyOk) {
                System.err.println("\ncase3: proxy loaded in" +
                                   " correct loader: " + proxyLoader +
                                   Arrays.asList(((URLClassLoader)
                                                 proxyLoader).getURLs()));
            } else {
                TestLibrary.bomb("case3: proxy class loaded in " +
                                 "incorrect loader: " + proxyLoader +
                                   Arrays.asList(((URLClassLoader)
                                                  proxyLoader).getURLs()));
            }

            if (ifaceLoader == expectedLoader) {
                System.err.println("case3: proxy interface loaded in" +
                                   " correct loader: " + ifaceLoader);
            } else {
                TestLibrary.bomb("public proxy interface loaded in " +
                                 "incorrect loader: " + ifaceLoader);
            }
        }
    }

    private static class Case5Checker implements LoadChecker {
        public void checkLoad(Proxy proxy, ClassLoader expectedLoader) {
            ClassLoader proxyLoader = proxy.getClass().getClassLoader();

            String proxyAnnotation =
                RMIClassLoader.getClassAnnotation(proxy.getClass());

            if ((proxyAnnotation == null) ||
                !proxyAnnotation.equals(publicUrl.toString()))
            {
                TestLibrary.bomb("proxy class had incorrect annotation: " +
                                 proxyAnnotation);
            } else {
                System.err.println("proxy class had correct annotation: " +
                                   proxyAnnotation);
            }

            boolean proxyOk = false;

            if (boomerangSemantics) {
                ClassLoader ctxLoader =
                    Thread.currentThread().getContextClassLoader();
                if (proxyLoader == ctxLoader) {
                    proxyOk = true;
                }
            } else if (proxyLoader.getClass().
                       getName().indexOf("sun.rmi") >= 0)
            {
                proxyOk = true;
            }

            if (proxyOk) {
                System.err.println("\ncase5: proxy loaded from" +
                                   " correct loader: " + proxyLoader);
            } else {
                TestLibrary.bomb("case5: proxy interface loaded from " +
                                 "incorrect loader: " + proxyLoader);
            }
        }
    }

    private static class TestInvocationHandler
        implements InvocationHandler, Serializable
    {
        public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {return null;}
    }
}

Other Java examples (source code examples)

Here is a short list of links related to this Java LoadProxyClasses.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.