/*
 * Copyright (c) 1999, 2024, 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
 * @bug 4242317
 * @summary When a class that can be found in the CLASSPATH of the rmiregistry
 * tool is marshalled via RMI, it should be annotated with the value of the
 * java.rmi.server.codebase property, not the list of "file:" URLs for the
 * actual elements of the CLASSPATH.
 * @author Peter Jones
 *
 * @library ../../testlibrary
 * @modules java.rmi/sun.rmi.registry
 *          java.rmi/sun.rmi.server
 *          java.rmi/sun.rmi.transport
 *          java.rmi/sun.rmi.transport.tcp
 * @build TestLibrary Dummy RegistryVM RMIRegistryRunner TestLoaderHandler
 * @run main/othervm
 *     -Djava.rmi.server.useCodebaseOnly=false ClassPathCodebase
 */

import java.io.*;
import java.net.*;
import java.rmi.*;
import java.rmi.server.*;
import java.rmi.registry.*;
import java.util.Arrays;

public class ClassPathCodebase {

    /** wait dozens of seconds for the registry process to be ready to call */
    private static final long REGISTRY_WAIT =
            (long)(10000 * TestLibrary.getTimeoutFactor());

    private final static String dummyClassName = "Dummy";

    private final static String dummyBinding = "DummyObject";

    private final static String importCodebase = "codebase_IMPORT_";
    private final static String exportCodebase = "codebase_EXPORT_";

    public static void main(String[] args) {

        System.err.println("\nRegression test for bug 4242317\n");

        System.setProperty("java.rmi.server.RMIClassLoaderSpi", "TestLoaderHandler");
        RegistryVM rmiregistry = null;

        try {
            /*
             * Install a dummy class in two codebases: one that will be in
             * the rmiregistry's CLASSPATH (the "import" codebase) and one
             * that will be in the rmiregistry's "java.rmi.server.codebase"
             * property (the "export" codebase).
             */
            URL importCodebaseURL = TestLibrary.installClassInCodebase(
                dummyClassName, importCodebase, false);
            URL exportCodebaseURL = TestLibrary.installClassInCodebase(
                dummyClassName, exportCodebase, true);

            /*
             * Spawn an rmiregistry in the "import" codebase directory.
             */
            File rmiregistryDir =
                  new File(System.getProperty("user.dir", "."), importCodebase);
            rmiregistry = RegistryVM.createRegistryVMWithRunner("RMIRegistryRunner",
                            " -Denv.class.path=."
                            + " -Djava.rmi.server.codebase=" + exportCodebaseURL
                            + " -Duser.dir=" + rmiregistryDir.getAbsolutePath());
            rmiregistry.start();
            int port = rmiregistry.getPort();

            /*
             * Wait for the registry to initialize and be ready to call.
             */
            Thread.sleep(REGISTRY_WAIT);
            System.err.println();

            /*
             * Create an instance of the dummy class, finding it from the
             * "import" codebase.
             */
            ClassLoader loader = URLClassLoader.newInstance(
                new URL[] { importCodebaseURL });
            Class dummyClass = Class.forName(dummyClassName, false, loader);
            Remote dummyObject = (Remote) dummyClass.newInstance();

            /*
             * Find the registry that we created and bind the
             * dummy object to it.
             */
            Registry registry = LocateRegistry.getRegistry(
                "localhost", port);

            try {
                registry.bind(dummyBinding, dummyObject);
                System.err.println("Bound dummy object in registry");
            } catch (java.rmi.ConnectException e) {
                System.err.println("Error: rmiregistry not started in time");
                throw e;
            } catch (ServerException e) {
                if (e.detail instanceof UnmarshalException &&
                    ((UnmarshalException) e.detail).detail instanceof
                        ClassNotFoundException)
                {
                    System.err.println(
                        "Error: another registry running on port " +
                        port + "?");
                }
                throw e;
            }

            /*
             * Look up the dummy object from our registry and make sure
             * that its class was annotated with the "export" codebase.
             */
            Remote dummyLookup = registry.lookup(dummyBinding);
            System.err.println(
                "Looked up dummy object from registry: " + dummyLookup);
            Class dummyLookupClass = dummyLookup.getClass();
            String dummyLookupAnnotation =
                RMIClassLoader.getClassAnnotation(dummyLookupClass);
            System.err.println(
                "Class annotation from registry: " + dummyLookupAnnotation);

            System.err.println();
            if (dummyLookupAnnotation.indexOf(exportCodebase) >= 0) {
                System.err.println("TEST PASSED");
            } else if (dummyLookupAnnotation.indexOf(importCodebase) >= 0) {
                throw new RuntimeException(
                    "rmiregistry annotated with CLASSPATH element URL");
            } else {
                throw new RuntimeException(
                    "rmiregistry used unexpected annotation: \"" +
                    dummyLookupAnnotation + "\"");
            }

        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("TEST FAILED: " + e.toString());
        } finally {
            if (rmiregistry != null) {
                rmiregistry.cleanup();
            }
        }
    }
}
