1 /*
   2  * Copyright (c) 1999, 2013, 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 4211906
  26  * @summary If the type of a parameter or return value in an RMI call can be
  27  * successfully downloaded by the receiving endpoint, then an array class with
  28  * that type as its element type should likewise be able to be successfully
  29  * downloaded.  This should be true regardless of how many dimensions the
  30  * array has.
  31  * @author Peter Jones
  32  *
  33  * @library ../../../testlibrary
  34  * @modules java.rmi/sun.rmi.registry
  35  *          java.rmi/sun.rmi.server
  36  *          java.rmi/sun.rmi.transport
  37  *          java.rmi/sun.rmi.transport.tcp
  38  * @build TestLibrary Receiver DownloadArrayClass_Stub Foo
  39  * @run main/othervm/policy=security.policy DownloadArrayClass
  40  */
  41 
  42 import java.lang.reflect.Array;
  43 import java.net.*;
  44 import java.rmi.*;
  45 import java.rmi.server.*;
  46 
  47 public class DownloadArrayClass
  48     extends UnicastRemoteObject
  49     implements Receiver
  50 {
  51 
  52     public DownloadArrayClass() throws RemoteException {
  53     }
  54 
  55     public void receive(Object obj) {
  56         System.err.println("+ receive(): received object " + obj);
  57     }
  58 
  59     public static void main(String[] args) {
  60 
  61         System.err.println("\nRegression test for bug 4082868\n");
  62 
  63         URL remoteCodebase = null;
  64         try {
  65             remoteCodebase =
  66                 TestLibrary.installClassInCodebase("Foo", "remote_codebase");
  67         } catch (MalformedURLException e) {
  68             TestLibrary.bomb(e);
  69         }
  70 
  71         System.err.println("Setting codebase property to: " + remoteCodebase);
  72         System.setProperty("java.rmi.server.codebase",
  73             remoteCodebase.toString());
  74 
  75         /*
  76          * Load Foo from a non-RMI class loader so that it won't be already
  77          * loaded by an RMI class loader in this VM (for whatever that's
  78          * worth), but with URLClassLoader so that they will be annotated
  79          * properly.
  80          */
  81         System.err.println("Creating class loader for remote codebase " +
  82             remoteCodebase);
  83         ClassLoader remoteCodebaseLoader =
  84             URLClassLoader.newInstance(new URL[] { remoteCodebase });
  85 
  86         TestLibrary.suggestSecurityManager(null);
  87 
  88         System.err.println("Creating remote object.");
  89         DownloadArrayClass obj = null;
  90         try {
  91             obj = new DownloadArrayClass();
  92         } catch (RemoteException e) {
  93             TestLibrary.bomb(e);
  94         }
  95 
  96         try {
  97             Receiver stub = (Receiver) RemoteObject.toStub(obj);
  98 
  99             /*
 100              * Load the downloadable class "Foo" to marshal over RMI calls
 101              * in various forms.
 102              */
 103             Class fooClass = remoteCodebaseLoader.loadClass("Foo");
 104             Object arg;
 105 
 106             /*
 107              * First, to establish that simple class downloading is working
 108              * properly, try marshalling a simple instance of Foo.
 109              */
 110             arg = fooClass.newInstance();
 111             System.err.println("Passing object of type " + arg.getClass());
 112             stub.receive(arg);
 113 
 114             /*
 115              * Second, try marshalling a one-dimensional array of element
 116              * type Foo.
 117              */
 118             arg = Array.newInstance(fooClass, 26);
 119             System.err.println("Passing object of type " + arg.getClass());
 120             stub.receive(arg);
 121 
 122             /*
 123              * Finally, try marshalling a multi-dimensional array with
 124              * Foo as the eventual element type.
 125              */
 126             arg = Array.newInstance(fooClass, new int[] { 1, 42, 0 });
 127             System.err.println("Passing object of type " + arg.getClass());
 128             stub.receive(arg);
 129 
 130             System.err.println("TEST PASSED: " +
 131                 "arrays of downloaded classes successfully passed");
 132 
 133         } catch (Exception e) {
 134             System.err.println("TEST FAILED: ");
 135             e.printStackTrace();
 136             throw new RuntimeException("TEST FAILED: " + e.toString());
 137         } finally {
 138             try {
 139                 UnicastRemoteObject.unexportObject(obj, true);
 140             } catch (Throwable e) {
 141             }
 142         }
 143     }
 144 }