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 4174006
  26  * @summary If the "java.rmi.server.useCodebaseOnly" property has a boolean
  27  * value of true, then when the RMI runtime is unmarshalling a class
  28  * descriptor, it should not attempt to download the associate Class object
  29  * from the annotated codebase, but only from the codebase specified in the
  30  * "java.rmi.server.codebase" property and the context class loader.
  31  * @author Peter Jones
  32  *
  33  * @library ../../../testlibrary
  34  * @build TestLibrary Receiver UseCodebaseOnly_Stub Foo Bar
  35  * @run main/othervm/policy=security.policy UseCodebaseOnly
  36  */
  37 
  38 import java.net.*;
  39 import java.rmi.*;
  40 import java.rmi.server.*;
  41 
  42 public class UseCodebaseOnly
  43     extends UnicastRemoteObject
  44     implements Receiver
  45 {
  46 
  47     public UseCodebaseOnly() throws RemoteException {
  48     }
  49 
  50     public void receive(Object obj) {
  51         System.err.println("+ receive(): received object " + obj);
  52     }
  53 
  54     public static void main(String[] args) {
  55 
  56         System.err.println("\nRegression test for bug 4174006\n");
  57 
  58         URL localCodebase = null, remoteCodebase = null;
  59         try {
  60             remoteCodebase =
  61                 TestLibrary.installClassInCodebase("Foo", "remote_codebase");
  62             localCodebase =
  63                 TestLibrary.installClassInCodebase("Bar", "local_codebase");
  64         } catch (MalformedURLException e) {
  65             TestLibrary.bomb(e);
  66         }
  67 
  68         TestLibrary.setProperty("java.rmi.server.useCodebaseOnly", "true");
  69         TestLibrary.setProperty(        // set local codebase property
  70             "java.rmi.server.codebase", localCodebase.toString());
  71 
  72         /*
  73          * Load Foo and Bar from non-RMI class loaders so that they won't be
  74          * already loaded by RMI class loaders in this VM (for whatever that's
  75          * worth), but with URLClassLoader so that they will be annotated
  76          * properly.
  77          */
  78         System.err.println("Creating class loader for remote codebase " +
  79             remoteCodebase);
  80         ClassLoader remoteCodebaseLoader =
  81             URLClassLoader.newInstance(new URL[] { remoteCodebase });
  82         System.err.println("Creating class loader for local codebase " +
  83             localCodebase);
  84         ClassLoader localCodebaseLoader =
  85             URLClassLoader.newInstance(new URL[] { localCodebase });
  86 
  87         TestLibrary.suggestSecurityManager(null);
  88 
  89         System.err.println("Creating remote object.");
  90         UseCodebaseOnly obj = null;
  91         try {
  92             obj = new UseCodebaseOnly();
  93         } catch (RemoteException e) {
  94             TestLibrary.bomb(e);
  95         }
  96 
  97         try {
  98             Receiver stub = (Receiver) RemoteObject.toStub(obj);
  99 
 100             /*
 101              * Pass an instance of Bar, the class in the local codebase.
 102              * This should succeed, because the server is allow to load
 103              * classes from the local codebase.
 104              */
 105             System.err.println(
 106                 "Passing class from local codebase (should succeed).");
 107             Class barClass = localCodebaseLoader.loadClass("Bar");
 108             Object barObj = barClass.newInstance();
 109             stub.receive(barObj);
 110 
 111             /*
 112              * Pass an instance of Foo, the class in the remote codebase.
 113              * This should fail, because the server is not allowed to load
 114              * classes from other codebases besides the local codebase.
 115              */
 116             System.err.println(
 117                 "Passing class from remote codebase (should fail).");
 118             Class fooClass = remoteCodebaseLoader.loadClass("Foo");
 119             Object fooObj = fooClass.newInstance();
 120             try {
 121                 stub.receive(fooObj);
 122                 throw new RuntimeException("TEST FAILED: " +
 123                     "class from remote codebase sucesssfully unmarshalled");
 124             } catch (RemoteException e) {
 125                 /*
 126                  * Verify that the failure was that the server couldn't
 127                  * unmarshal the Foo class.
 128                  */
 129                 if ((e instanceof ServerException) &&
 130                     (e.detail instanceof UnmarshalException) &&
 131                     (((RemoteException) e.detail).detail instanceof
 132                         ClassNotFoundException) &&
 133                     (((RemoteException) e.detail).detail.getMessage().equals(
 134                         "Foo")))
 135                 {
 136                     System.err.println("TEST PASSED: ");
 137                     e.printStackTrace();
 138                 } else {
 139                     throw e;
 140                 }
 141             }
 142         } catch (Exception e) {
 143             System.err.println("TEST FAILED: ");
 144             e.printStackTrace();
 145             throw new RuntimeException("TEST FAILED: " + e.toString());
 146         } finally {
 147             try {
 148                 UnicastRemoteObject.unexportObject(obj, true);
 149             } catch (Throwable e) {
 150             }
 151         }
 152     }
 153 }