< prev index next >

test/javax/management/remote/mandatory/loading/MethodResultTest.java

Print this page
rev 11832 : 8078896: Add @modules as needed to the jdk_svc tests
Reviewed-by: alanb, mchung
   1 /*
   2  * Copyright (c) 2003, 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 /*
  25  * @test
  26  * @bug 4898478
  27  * @summary Tests client default class loader used before JSR 160 loader
  28  * @author Eamonn McManus

  29  * @run clean MethodResultTest
  30  * @run build MethodResultTest
  31  * @run main MethodResultTest
  32  */
  33 
  34 import java.io.*;

  35 import java.net.*;
  36 import java.util.*;
  37 import javax.management.*;
  38 import javax.management.remote.*;
  39 
  40 /*
  41    This test checks that the class loader that is used to deserialize
  42    the return values from remote MBean server operations is indeed the
  43    one specified by the user.  The only MBean server operations that
  44    matter are those than can return an arbitrary Object.  We don't
  45    care about getMBeanCount or queryNames or whatever because their
  46    return values are always of classes loaded by the bootstrap loader.
  47    But for the operations getAttribute, getAttributes, setAttributes,
  48    and invoke, the return value can include any Java class.  This is
  49    also true of getMBeanInfo, since the return value can be an exotic
  50    subclass of MBeanInfo, or a ModelMBeanInfo that refers to an
  51    arbitrary Object.  The JMX Remote API spec requires that these
  52    return values be deserialized using the class loader supplied by
  53    the user (default is context class loader).  In particular it must
  54    not be deserialized using the system class loader, which it will be
  55    with RMI unless special precautions are taken.
  56  */
  57 public class MethodResultTest {
  58     public static void main(String[] args) throws Exception {
  59         Class thisClass = MethodResultTest.class;
  60         Class exoticClass = Exotic.class;
  61         String exoticClassName = Exotic.class.getName();
  62         ClassLoader testClassLoader = thisClass.getClassLoader();
  63         if (!(testClassLoader instanceof URLClassLoader)) {
  64             System.out.println("TEST INVALID: Not loaded by a " +
  65                                "URLClassLoader: " + testClassLoader);
  66             System.exit(1);

  67         }
  68 
  69         URLClassLoader tcl = (URLClassLoader) testClassLoader;
  70         URL[] urls = tcl.getURLs();
  71         ClassLoader shadowLoader =
  72             new ShadowLoader(urls, testClassLoader,
  73                              new String[] {exoticClassName,
  74                                            ExoticMBeanInfo.class.getName(),
  75                                            ExoticException.class.getName()});
  76         Class cl = shadowLoader.loadClass(exoticClassName);
  77         if (cl == exoticClass) {
  78             System.out.println("TEST INVALID: Shadow class loader loaded " +
  79                                "same class as test class loader");
  80             System.exit(1);
  81         }
  82         Thread.currentThread().setContextClassLoader(shadowLoader);
  83 
  84         ObjectName on = new ObjectName("a:b=c");
  85         MBeanServer mbs = MBeanServerFactory.newMBeanServer();
  86         mbs.createMBean(Thing.class.getName(), on);
  87 
  88         final String[] protos = {"rmi", "iiop", "jmxmp"};
  89 
  90         boolean ok = true;
  91         for (int i = 0; i < protos.length; i++) {
  92             try {
  93                 ok &= test(protos[i], mbs, on);
  94                 System.out.println();
  95             } catch (Exception e) {
  96                 System.out.println("TEST FAILED WITH EXCEPTION:");


 180                                  ExoticException.class);
 181         ok &= checkExceptionType("invoke", invokeException,
 182                                  ExoticException.class);
 183 
 184         if (ok)
 185             System.out.println("Test passes for protocol " + proto);
 186         return ok;
 187     }
 188 
 189     private static Exception noException(String what) {
 190         final String msg =
 191             "Operation " + what + " returned when exception expected";
 192         return new IllegalStateException(msg);
 193     }
 194 
 195     private static Object attrValue(AttributeList attrs) {
 196         return ((Attribute) attrs.get(0)).getValue();
 197     }
 198 
 199     private static boolean checkType(String what, Object object,
 200                                      Class wrongClass) {
 201         return checkType(what, object, wrongClass, false);
 202     }
 203 
 204     private static boolean checkType(String what, Object object,
 205                                      Class wrongClass, boolean isException) {
 206         final String type = isException ? "exception" : "object";
 207         final String rendered = isException ? "thrown" : "returned";
 208         System.out.println("For " + type + " " + rendered + " by " + what +
 209                            ":");
 210         if (wrongClass.isInstance(object)) {
 211             System.out.println("TEST FAILS: " + type + " loaded by test " +
 212                                "classloader");
 213             return false;
 214         }
 215         String className = object.getClass().getName();
 216         if (!className.equals(wrongClass.getName())) {
 217             System.out.println("TEST FAILS: " + rendered + " " + type +
 218                                " has wrong class name: " + className);
 219             return false;
 220         }
 221         System.out.println("Test passes: " + rendered + " " + type +
 222                            " has same class name but is not same class");
 223         return true;
 224     }
 225 
 226     private static boolean checkExceptionType(String what, Exception exception,
 227                                               Class wrongClass) {
 228         if (!(exception instanceof MBeanException)) {
 229             System.out.println("Exception thrown by " + what + " is not an " +
 230                                MBeanException.class.getName() +
 231                                ":");
 232             exception.printStackTrace(System.out);
 233             return false;
 234         }
 235 
 236         exception = ((MBeanException) exception).getTargetException();
 237 
 238         return checkType(what, exception, wrongClass, true);
 239     }
 240 
 241     private static boolean checkAttrs(String what, AttributeList attrs) {
 242         if (attrs.size() != 1) {
 243             System.out.println("TEST FAILS: list returned by " + what +
 244                                " does not have size 1: " + attrs);
 245             return false;
 246         }
 247         Attribute attr = (Attribute) attrs.get(0);


 303 
 304     public static class ExoticMBeanInfo extends MBeanInfo {
 305         public ExoticMBeanInfo(MBeanInfo mbi) {
 306             super(mbi.getClassName(),
 307                   mbi.getDescription(),
 308                   mbi.getAttributes(),
 309                   mbi.getConstructors(),
 310                   mbi.getOperations(),
 311                   mbi.getNotifications());
 312         }
 313     }
 314 
 315     private static class ShadowLoader extends URLClassLoader {
 316         ShadowLoader(URL[] urls, ClassLoader realLoader,
 317                      String[] shadowClassNames) {
 318             super(urls, null);
 319             this.realLoader = realLoader;
 320             this.shadowClassNames = Arrays.asList(shadowClassNames);
 321         }
 322 
 323         protected Class findClass(String name) throws ClassNotFoundException {
 324             if (shadowClassNames.contains(name))
 325                 return super.findClass(name);
 326             else
 327                 return realLoader.loadClass(name);
 328         }
 329 
 330         private final ClassLoader realLoader;
 331         private final List shadowClassNames;
 332     }
 333 }
   1 /*
   2  * Copyright (c) 2003, 2015, 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 /*
  25  * @test
  26  * @bug 4898478
  27  * @summary Tests client default class loader used before JSR 160 loader
  28  * @author Eamonn McManus
  29  * @modules java.management
  30  * @run clean MethodResultTest
  31  * @run build MethodResultTest
  32  * @run main MethodResultTest
  33  */
  34 
  35 import java.io.*;
  36 import java.nio.file.Paths;
  37 import java.net.*;
  38 import java.util.*;
  39 import javax.management.*;
  40 import javax.management.remote.*;
  41 
  42 /*
  43    This test checks that the class loader that is used to deserialize
  44    the return values from remote MBean server operations is indeed the
  45    one specified by the user.  The only MBean server operations that
  46    matter are those than can return an arbitrary Object.  We don't
  47    care about getMBeanCount or queryNames or whatever because their
  48    return values are always of classes loaded by the bootstrap loader.
  49    But for the operations getAttribute, getAttributes, setAttributes,
  50    and invoke, the return value can include any Java class.  This is
  51    also true of getMBeanInfo, since the return value can be an exotic
  52    subclass of MBeanInfo, or a ModelMBeanInfo that refers to an
  53    arbitrary Object.  The JMX Remote API spec requires that these
  54    return values be deserialized using the class loader supplied by
  55    the user (default is context class loader).  In particular it must
  56    not be deserialized using the system class loader, which it will be
  57    with RMI unless special precautions are taken.
  58  */
  59 public class MethodResultTest {
  60     public static void main(String[] args) throws Exception {
  61         Class<?> thisClass = MethodResultTest.class;
  62         Class<?> exoticClass = Exotic.class;
  63         String exoticClassName = Exotic.class.getName();
  64 
  65         String[] cpaths = System.getProperty("test.classes", ".")
  66                                 .split(File.pathSeparator);
  67         URL[] urls = new URL[cpaths.length];
  68         for (int i=0; i < cpaths.length; i++) {
  69             urls[i] = Paths.get(cpaths[i]).toUri().toURL();
  70         }
  71 


  72         ClassLoader shadowLoader =
  73             new ShadowLoader(urls, thisClass.getClassLoader(),
  74                              new String[] {exoticClassName,
  75                                            ExoticMBeanInfo.class.getName(),
  76                                            ExoticException.class.getName()});
  77         Class<?> cl = shadowLoader.loadClass(exoticClassName);
  78         if (cl == exoticClass) {
  79             System.out.println("TEST INVALID: Shadow class loader loaded " +
  80                                "same class as test class loader");
  81             System.exit(1);
  82         }
  83         Thread.currentThread().setContextClassLoader(shadowLoader);
  84 
  85         ObjectName on = new ObjectName("a:b=c");
  86         MBeanServer mbs = MBeanServerFactory.newMBeanServer();
  87         mbs.createMBean(Thing.class.getName(), on);
  88 
  89         final String[] protos = {"rmi", "iiop", "jmxmp"};
  90 
  91         boolean ok = true;
  92         for (int i = 0; i < protos.length; i++) {
  93             try {
  94                 ok &= test(protos[i], mbs, on);
  95                 System.out.println();
  96             } catch (Exception e) {
  97                 System.out.println("TEST FAILED WITH EXCEPTION:");


 181                                  ExoticException.class);
 182         ok &= checkExceptionType("invoke", invokeException,
 183                                  ExoticException.class);
 184 
 185         if (ok)
 186             System.out.println("Test passes for protocol " + proto);
 187         return ok;
 188     }
 189 
 190     private static Exception noException(String what) {
 191         final String msg =
 192             "Operation " + what + " returned when exception expected";
 193         return new IllegalStateException(msg);
 194     }
 195 
 196     private static Object attrValue(AttributeList attrs) {
 197         return ((Attribute) attrs.get(0)).getValue();
 198     }
 199 
 200     private static boolean checkType(String what, Object object,
 201                                      Class<?> wrongClass) {
 202         return checkType(what, object, wrongClass, false);
 203     }
 204 
 205     private static boolean checkType(String what, Object object,
 206                                      Class<?> wrongClass, boolean isException) {
 207         final String type = isException ? "exception" : "object";
 208         final String rendered = isException ? "thrown" : "returned";
 209         System.out.println("For " + type + " " + rendered + " by " + what +
 210                            ":");
 211         if (wrongClass.isInstance(object)) {
 212             System.out.println("TEST FAILS: " + type + " loaded by test " +
 213                                "classloader");
 214             return false;
 215         }
 216         String className = object.getClass().getName();
 217         if (!className.equals(wrongClass.getName())) {
 218             System.out.println("TEST FAILS: " + rendered + " " + type +
 219                                " has wrong class name: " + className);
 220             return false;
 221         }
 222         System.out.println("Test passes: " + rendered + " " + type +
 223                            " has same class name but is not same class");
 224         return true;
 225     }
 226 
 227     private static boolean checkExceptionType(String what, Exception exception,
 228                                               Class<?> wrongClass) {
 229         if (!(exception instanceof MBeanException)) {
 230             System.out.println("Exception thrown by " + what + " is not an " +
 231                                MBeanException.class.getName() +
 232                                ":");
 233             exception.printStackTrace(System.out);
 234             return false;
 235         }
 236 
 237         exception = ((MBeanException) exception).getTargetException();
 238 
 239         return checkType(what, exception, wrongClass, true);
 240     }
 241 
 242     private static boolean checkAttrs(String what, AttributeList attrs) {
 243         if (attrs.size() != 1) {
 244             System.out.println("TEST FAILS: list returned by " + what +
 245                                " does not have size 1: " + attrs);
 246             return false;
 247         }
 248         Attribute attr = (Attribute) attrs.get(0);


 304 
 305     public static class ExoticMBeanInfo extends MBeanInfo {
 306         public ExoticMBeanInfo(MBeanInfo mbi) {
 307             super(mbi.getClassName(),
 308                   mbi.getDescription(),
 309                   mbi.getAttributes(),
 310                   mbi.getConstructors(),
 311                   mbi.getOperations(),
 312                   mbi.getNotifications());
 313         }
 314     }
 315 
 316     private static class ShadowLoader extends URLClassLoader {
 317         ShadowLoader(URL[] urls, ClassLoader realLoader,
 318                      String[] shadowClassNames) {
 319             super(urls, null);
 320             this.realLoader = realLoader;
 321             this.shadowClassNames = Arrays.asList(shadowClassNames);
 322         }
 323 
 324         protected Class<?> findClass(String name) throws ClassNotFoundException {
 325             if (shadowClassNames.contains(name))
 326                 return super.findClass(name);
 327             else
 328                 return realLoader.loadClass(name);
 329         }
 330 
 331         private final ClassLoader realLoader;
 332         private final List shadowClassNames;
 333     }
 334 }
< prev index next >