1 /*
   2  * Copyright (c) 1999, 2010, 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 4227192 8004928
  26  * @summary This is a test of the restrictions on the parameters that may
  27  * be passed to the Proxy.getProxyClass method.
  28  * @author Peter Jones
  29  *
  30  * @build ClassRestrictions
  31  * @run main ClassRestrictions
  32  */
  33 
  34 import java.lang.reflect.Modifier;
  35 import java.lang.reflect.Proxy;
  36 import java.net.URLClassLoader;
  37 
  38 public class ClassRestrictions {
  39 
  40     public interface Bar {
  41         int foo();
  42     }
  43 
  44     public interface Baz {
  45         long foo();
  46     }
  47 
  48     interface Bashful {
  49         void foo();
  50     }
  51     
  52     public static final String nonPublicIntrfaceName = "java.util.zip.ZipConstants";
  53     
  54     public static void main(String[] args) {
  55 
  56         System.err.println(
  57             "\nTest of restrictions on parameters to Proxy.getProxyClass\n");
  58 
  59         try {
  60             ClassLoader loader = ClassRestrictions.class.getClassLoader();
  61             Class<?>[] interfaces;
  62             Class<?> proxyClass;
  63 
  64             /*
  65              * All of the Class objects in the interfaces array must represent
  66              * interfaces, not classes or primitive types.
  67              */
  68             try {
  69                 interfaces = new Class<?>[] { Object.class };
  70                 proxyClass = Proxy.getProxyClass(loader, interfaces);
  71                 throw new Error(
  72                     "proxy class created with java.lang.Object as interface");
  73             } catch (IllegalArgumentException e) {
  74                 e.printStackTrace();
  75                 System.err.println();
  76                 // assume exception is for intended failure
  77             }
  78             try {
  79                 interfaces = new Class<?>[] { Integer.TYPE };
  80                 proxyClass = Proxy.getProxyClass(loader, interfaces);
  81                 throw new Error(
  82                     "proxy class created with int.class as interface");
  83             } catch (IllegalArgumentException e) {
  84                 e.printStackTrace();
  85                 System.err.println();
  86                 // assume exception is for intended failure
  87             }
  88 
  89             /*
  90              * No two elements in the interfaces array may refer to identical
  91              * Class objects.
  92              */
  93             try {
  94                 interfaces = new Class<?>[] { Bar.class, Bar.class };
  95                 proxyClass = Proxy.getProxyClass(loader, interfaces);
  96                 throw new Error(
  97                     "proxy class created with repeated interfaces");
  98             } catch (IllegalArgumentException e) {
  99                 e.printStackTrace();
 100                 System.err.println();
 101                 // assume exception is for intended failure
 102             }
 103 
 104             /*
 105              * All of the interfaces types must be visible by name though the
 106              * specified class loader.
 107              */
 108             ClassLoader altLoader = new URLClassLoader(
 109                 ((URLClassLoader) loader).getURLs(), null);
 110             Class altBarClass;
 111             altBarClass = Class.forName(Bar.class.getName(), false, altLoader);
 112             try {
 113                 interfaces = new Class<?>[] { altBarClass };
 114                 proxyClass = Proxy.getProxyClass(loader, interfaces);
 115                 throw new Error(
 116                     "proxy class created with interface " +
 117                     "not visible to class loader");
 118             } catch (IllegalArgumentException e) {
 119                 e.printStackTrace();
 120                 System.err.println();
 121                 // assume exception is for intended failure
 122             }
 123 
 124             /*
 125              * All non-public interfaces must be in the same package.
 126              */
 127             Class<?> nonPublic1 = Bashful.class;
 128             Class<?> nonPublic2 = Class.forName(nonPublicIntrfaceName);
 129             if (Modifier.isPublic(nonPublic2.getModifiers())) {
 130                 throw new Error(
 131                     "Interface " + nonPublicIntrfaceName + 
 132                     " is public and need to be changed!");
 133             }
 134             try {
 135                 interfaces = new Class<?>[] { nonPublic1, nonPublic2 };
 136                 proxyClass = Proxy.getProxyClass(loader, interfaces);
 137                 throw new Error(
 138                     "proxy class created with two non-public interfaces " +
 139                     "in different packages");
 140             } catch (IllegalArgumentException e) {
 141                 e.printStackTrace();
 142                 System.err.println();
 143                 // assume exception is for intended failure
 144             }
 145 
 146             /*
 147              * No two interfaces may each have a method with the same name and
 148              * parameter signature but different return type.
 149              */
 150             try {
 151                 interfaces = new Class<?>[] { Bar.class, Baz.class };
 152                 proxyClass = Proxy.getProxyClass(loader, interfaces);
 153                 throw new Error(
 154                     "proxy class created with conflicting methods");
 155             } catch (IllegalArgumentException e) {
 156                 e.printStackTrace();
 157                 System.err.println();
 158                 // assume exception is for intended failure
 159             }
 160 
 161             /*
 162              * All components of this test have passed.
 163              */
 164             System.err.println("\nTEST PASSED");
 165 
 166         } catch (Throwable e) {
 167             System.err.println("\nTEST FAILED:");
 168             e.printStackTrace();
 169             throw new Error("TEST FAILED: ", e);
 170         }
 171     }
 172 }