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
  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.Proxy;
  35 import java.net.URLClassLoader;
  36 
  37 public class ClassRestrictions {
  38 
  39     public interface Bar {
  40         int foo();
  41     }
  42 
  43     public interface Baz {
  44         long foo();
  45     }
  46 
  47     interface Bashful {
  48         void foo();
  49     }
  50 
  51     public static void main(String[] args) {
  52 
  53         System.err.println(
  54             "\nTest of restrictions on parameters to Proxy.getProxyClass\n");
  55 
  56         try {
  57             ClassLoader loader = ClassRestrictions.class.getClassLoader();
  58             Class<?>[] interfaces;
  59             Class<?> proxyClass;
  60 
  61             /*
  62              * All of the Class objects in the interfaces array must represent
  63              * interfaces, not classes or primitive types.
  64              */
  65             try {
  66                 interfaces = new Class<?>[] { Object.class };
  67                 proxyClass = Proxy.getProxyClass(loader, interfaces);
  68                 throw new RuntimeException(
  69                     "proxy class created with java.lang.Object as interface");
  70             } catch (IllegalArgumentException e) {
  71                 e.printStackTrace();
  72                 System.err.println();
  73                 // assume exception is for intended failure
  74             }
  75             try {
  76                 interfaces = new Class<?>[] { Integer.TYPE };
  77                 proxyClass = Proxy.getProxyClass(loader, interfaces);
  78                 throw new RuntimeException(
  79                     "proxy class created with int.class as interface");
  80             } catch (IllegalArgumentException e) {
  81                 e.printStackTrace();
  82                 System.err.println();
  83                 // assume exception is for intended failure
  84             }
  85 
  86             /*
  87              * No two elements in the interfaces array may refer to identical
  88              * Class objects.
  89              */
  90             try {
  91                 interfaces = new Class<?>[] { Bar.class, Bar.class };
  92                 proxyClass = Proxy.getProxyClass(loader, interfaces);
  93                 throw new RuntimeException(
  94                     "proxy class created with repeated interfaces");
  95             } catch (IllegalArgumentException e) {
  96                 e.printStackTrace();
  97                 System.err.println();
  98                 // assume exception is for intended failure
  99             }
 100 
 101             /*
 102              * All of the interfaces types must be visible by name though the
 103              * specified class loader.
 104              */
 105             ClassLoader altLoader = new URLClassLoader(
 106                 ((URLClassLoader) loader).getURLs(), null);
 107             Class altBarClass;
 108             altBarClass = Class.forName(Bar.class.getName(), false, altLoader);
 109             try {
 110                 interfaces = new Class<?>[] { altBarClass };
 111                 proxyClass = Proxy.getProxyClass(loader, interfaces);
 112                 throw new RuntimeException(
 113                     "proxy class created with interface " +
 114                     "not visible to class loader");
 115             } catch (IllegalArgumentException e) {
 116                 e.printStackTrace();
 117                 System.err.println();
 118                 // assume exception is for intended failure
 119             }
 120 
 121             /*
 122              * All non-public interfaces must be in the same package.
 123              */
 124             Class<?> nonPublic1 = Bashful.class;
 125             Class<?> nonPublic2 = null;
 126             String[] nonPublicInterfaces = new String[] {
 127                 "java.awt.Conditional",
 128                 "java.util.zip.ZipConstants",
 129                 "javax.swing.GraphicsWrapper",
 130                 "javax.swing.JPopupMenu$Popup",
 131                 "javax.swing.JTable$Resizable2",
 132                 "javax.swing.JTable$Resizable3",
 133                 "javax.swing.ToolTipManager$Popup",
 134                 "sun.audio.Format",
 135                 "sun.audio.HaePlayable",
 136                 "sun.tools.agent.StepConstants",
 137             };
 138             for (int i = 0; i < nonPublicInterfaces.length; i++) {
 139                 try {
 140                     nonPublic2 = Class.forName(nonPublicInterfaces[i]);
 141                     break;
 142                 } catch (ClassNotFoundException e) {
 143                 }
 144             }
 145             if (nonPublic2 == null) {
 146                 throw new RuntimeException(
 147                     "no second non-public interface found for test");
 148             }
 149             try {
 150                 interfaces = new Class<?>[] { nonPublic1, nonPublic2 };
 151                 proxyClass = Proxy.getProxyClass(loader, interfaces);
 152                 throw new RuntimeException(
 153                     "proxy class created with two non-public interfaces " +
 154                     "in different packages");
 155             } catch (IllegalArgumentException e) {
 156                 e.printStackTrace();
 157                 System.err.println();
 158                 // assume exception is for intended failure
 159             }
 160 
 161             /*
 162              * No two interfaces may each have a method with the same name and
 163              * parameter signature but different return type.
 164              */
 165             try {
 166                 interfaces = new Class<?>[] { Bar.class, Baz.class };
 167                 proxyClass = Proxy.getProxyClass(loader, interfaces);
 168                 throw new RuntimeException(
 169                     "proxy class created with conflicting methods");
 170             } catch (IllegalArgumentException e) {
 171                 e.printStackTrace();
 172                 System.err.println();
 173                 // assume exception is for intended failure
 174             }
 175 
 176             /*
 177              * All components of this test have passed.
 178              */
 179             System.err.println("\nTEST PASSED");
 180 
 181         } catch (Exception e) {
 182             System.err.println("\nTEST FAILED:");
 183             e.printStackTrace();
 184             throw new RuntimeException("TEST FAILED: " + e.toString());
 185         }
 186     }
 187 }