1/* 2 * Copyright (c) 2000, 2017, 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26package com.sun.jmx.mbeanserver; 27 28 29import static com.sun.jmx.defaults.JmxProperties.MBEANSERVER_LOGGER; 30import java.io.ByteArrayInputStream; 31import java.io.IOException; 32import java.io.ObjectInputStream; 33import java.lang.reflect.Constructor; 34import java.lang.reflect.InvocationTargetException; 35import java.lang.reflect.Modifier; 36import java.security.AccessControlContext; 37import java.security.AccessController; 38import java.security.Permission; 39import java.security.Permissions; 40import java.security.PrivilegedAction; 41import java.security.ProtectionDomain; 42import java.util.Map; 43import java.lang.System.Logger.Level; 44 45import javax.management.InstanceNotFoundException; 46import javax.management.MBeanException; 47import javax.management.MBeanPermission; 48import javax.management.NotCompliantMBeanException; 49import javax.management.ObjectName; 50import javax.management.OperationsException; 51import javax.management.ReflectionException; 52import javax.management.RuntimeErrorException; 53import javax.management.RuntimeMBeanException; 54import javax.management.RuntimeOperationsException; 55import sun.reflect.misc.ConstructorUtil; 56import sun.reflect.misc.ReflectUtil; 57 58/** 59 * Implements the MBeanInstantiator interface. Provides methods for 60 * instantiating objects, finding the class given its name and using 61 * different class loaders, deserializing objects in the context of a 62 * given class loader. 63 * 64 * @since 1.5 65 */ 66public class MBeanInstantiator { 67 private final ModifiableClassLoaderRepository clr; 68 // private MetaData meta = null; 69 70 MBeanInstantiator(ModifiableClassLoaderRepository clr) { 71 this.clr = clr; 72 } 73 74 75 /** 76 * This methods tests if the MBean class makes it possible to 77 * instantiate an MBean of this class in the MBeanServer. 78 * e.g. it must have a public constructor, be a concrete class... 79 */ 80 public void testCreation(Class<?> c) throws NotCompliantMBeanException { 81 Introspector.testCreation(c); 82 } 83 84 /** 85 * Loads the class with the specified name using this object's 86 * Default Loader Repository. 87 **/ 88 public Class<?> findClassWithDefaultLoaderRepository(String className) 89 throws ReflectionException { 90 91 Class<?> theClass; 92 if (className == null) { 93 throw new RuntimeOperationsException(new 94 IllegalArgumentException("The class name cannot be null"), 95 "Exception occurred during object instantiation"); 96 } 97 98 ReflectUtil.checkPackageAccess(className); 99 try { 100 if (clr == null) throw new ClassNotFoundException(className); 101 theClass = clr.loadClass(className); 102 } 103 catch (ClassNotFoundException ee) { 104 throw new ReflectionException(ee, 105 "The MBean class could not be loaded by the default loader repository"); 106 } 107 108 return theClass; 109 } 110 111 112 /** 113 * Gets the class for the specified class name using the MBean 114 * Interceptor's classloader 115 */ 116 public Class<?> findClass(String className, ClassLoader loader) 117 throws ReflectionException { 118 119 return loadClass(className,loader); 120 } 121 122 /** 123 * Gets the class for the specified class name using the specified 124 * class loader 125 */ 126 public Class<?> findClass(String className, ObjectName aLoader) 127 throws ReflectionException, InstanceNotFoundException { 128 129 if (aLoader == null) 130 throw new RuntimeOperationsException(new 131 IllegalArgumentException(), "Null loader passed in parameter"); 132 133 // Retrieve the class loader from the repository 134 ClassLoader loader = null; 135 synchronized (this) { 136 loader = getClassLoader(aLoader); 137 } 138 if (loader == null) { 139 throw new InstanceNotFoundException("The loader named " + 140 aLoader + " is not registered in the MBeanServer"); 141 } 142 return findClass(className,loader); 143 } 144 145 146 /** 147 * Return an array of Class corresponding to the given signature, using 148 * the specified class loader. 149 */ 150 public Class<?>[] findSignatureClasses(String signature[], 151 ClassLoader loader) 152 throws ReflectionException { 153 154 if (signature == null) return null; 155 final ClassLoader aLoader = loader; 156 final int length= signature.length; 157 final Class<?> tab[]=new Class<?>[length]; 158 159 if (length == 0) return tab; 160 try { 161 for (int i= 0; i < length; i++) { 162 // Start handling primitive types (int. boolean and so 163 // forth) 164 // 165 166 final Class<?> primCla = primitiveClasses.get(signature[i]); 167 if (primCla != null) { 168 tab[i] = primCla; 169 continue; 170 } 171 172 ReflectUtil.checkPackageAccess(signature[i]); 173 // Ok we do not have a primitive type ! We need to build 174 // the signature of the method 175 // 176 if (aLoader != null) { 177 // We need to load the class through the class 178 // loader of the target object. 179 // 180 tab[i] = Class.forName(signature[i], false, aLoader); 181 } else { 182 // Load through the default class loader 183 // 184 tab[i] = findClass(signature[i], 185 this.getClass().getClassLoader()); 186 } 187 } 188 } catch (ClassNotFoundException e) { 189 if (MBEANSERVER_LOGGER.isLoggable(Level.DEBUG)) { 190 MBEANSERVER_LOGGER.log(Level.DEBUG, 191 "The parameter class could not be found", e); 192 } 193 throw new ReflectionException(e, 194 "The parameter class could not be found"); 195 } catch (RuntimeException e) { 196 if (MBEANSERVER_LOGGER.isLoggable(Level.DEBUG)) { 197 MBEANSERVER_LOGGER.log(Level.DEBUG, 198 "Unexpected exception", e); 199 } 200 throw e; 201 } 202 return tab; 203 } 204 205 206 /** 207 * Instantiates an object given its class, using its empty constructor. 208 * The call returns a reference to the newly created object. 209 */ 210 public Object instantiate(Class<?> theClass) 211 throws ReflectionException, MBeanException { 212 213 checkMBeanPermission(theClass, null, null, "instantiate"); 214 215 Object moi; 216 217 // ------------------------------ 218 // ------------------------------ 219 Constructor<?> cons = findConstructor(theClass, null); 220 if (cons == null) { 221 throw new ReflectionException(new 222 NoSuchMethodException("No such constructor")); 223 } 224 // Instantiate the new object 225 try { 226 ReflectUtil.checkPackageAccess(theClass); 227 ensureClassAccess(theClass); 228 moi= cons.newInstance(); 229 } catch (InvocationTargetException e) { 230 // Wrap the exception. 231 Throwable t = e.getTargetException(); 232 if (t instanceof RuntimeException) { 233 throw new RuntimeMBeanException((RuntimeException)t, 234 "RuntimeException thrown in the MBean's empty constructor"); 235 } else if (t instanceof Error) { 236 throw new RuntimeErrorException((Error) t, 237 "Error thrown in the MBean's empty constructor"); 238 } else { 239 throw new MBeanException((Exception) t, 240 "Exception thrown in the MBean's empty constructor"); 241 } 242 } catch (NoSuchMethodError error) { 243 throw new ReflectionException(new 244 NoSuchMethodException("No constructor"), 245 "No such constructor"); 246 } catch (InstantiationException e) { 247 throw new ReflectionException(e, 248 "Exception thrown trying to invoke the MBean's empty constructor"); 249 } catch (IllegalAccessException e) { 250 throw new ReflectionException(e, 251 "Exception thrown trying to invoke the MBean's empty constructor"); 252 } catch (IllegalArgumentException e) { 253 throw new ReflectionException(e, 254 "Exception thrown trying to invoke the MBean's empty constructor"); 255 } 256 return moi; 257 258 } 259 260 261 262 /** 263 * Instantiates an object given its class, the parameters and 264 * signature of its constructor The call returns a reference to 265 * the newly created object. 266 */ 267 public Object instantiate(Class<?> theClass, Object params[], 268 String signature[], ClassLoader loader) 269 throws ReflectionException, MBeanException { 270 271 checkMBeanPermission(theClass, null, null, "instantiate"); 272 273 // Instantiate the new object 274 // ------------------------------ 275 // ------------------------------ 276 final Class<?>[] tab; 277 Object moi; 278 try { 279 // Build the signature of the method 280 // 281 ClassLoader aLoader= theClass.getClassLoader(); 282 // Build the signature of the method 283 // 284 tab = 285 ((signature == null)?null: 286 findSignatureClasses(signature,aLoader)); 287 } 288 // Exception IllegalArgumentException raised in Jdk1.1.8 289 catch (IllegalArgumentException e) { 290 throw new ReflectionException(e, 291 "The constructor parameter classes could not be loaded"); 292 } 293 294 // Query the metadata service to get the right constructor 295 Constructor<?> cons = findConstructor(theClass, tab); 296 297 if (cons == null) { 298 throw new ReflectionException(new 299 NoSuchMethodException("No such constructor")); 300 } 301 try { 302 ReflectUtil.checkPackageAccess(theClass); 303 ensureClassAccess(theClass); 304 moi = cons.newInstance(params); 305 } 306 catch (NoSuchMethodError error) { 307 throw new ReflectionException(new 308 NoSuchMethodException("No such constructor found"), 309 "No such constructor" ); 310 } 311 catch (InstantiationException e) { 312 throw new ReflectionException(e, 313 "Exception thrown trying to invoke the MBean's constructor"); 314 } 315 catch (IllegalAccessException e) { 316 throw new ReflectionException(e, 317 "Exception thrown trying to invoke the MBean's constructor"); 318 } 319 catch (InvocationTargetException e) { 320 // Wrap the exception. 321 Throwable th = e.getTargetException(); 322 if (th instanceof RuntimeException) { 323 throw new RuntimeMBeanException((RuntimeException)th, 324 "RuntimeException thrown in the MBean's constructor"); 325 } else if (th instanceof Error) { 326 throw new RuntimeErrorException((Error) th, 327 "Error thrown in the MBean's constructor"); 328 } else { 329 throw new MBeanException((Exception) th, 330 "Exception thrown in the MBean's constructor"); 331 } 332 } 333 return moi; 334 } 335 336 /** 337 * De-serializes a byte array in the context of a classloader. 338 * 339 * @param loader the classloader to use for de-serialization 340 * @param data The byte array to be de-sererialized. 341 * 342 * @return The de-serialized object stream. 343 * 344 * @exception OperationsException Any of the usual Input/Output related 345 * exceptions. 346 */ 347 public ObjectInputStream deserialize(ClassLoader loader, byte[] data) 348 throws OperationsException { 349 350 // Check parameter validity 351 if (data == null) { 352 throw new RuntimeOperationsException(new 353 IllegalArgumentException(), "Null data passed in parameter"); 354 } 355 if (data.length == 0) { 356 throw new RuntimeOperationsException(new 357 IllegalArgumentException(), "Empty data passed in parameter"); 358 } 359 360 // Object deserialization 361 ByteArrayInputStream bIn; 362 ObjectInputStream objIn; 363 364 bIn = new ByteArrayInputStream(data); 365 try { 366 objIn = new ObjectInputStreamWithLoader(bIn,loader); 367 } catch (IOException e) { 368 throw new OperationsException( 369 "An IOException occurred trying to de-serialize the data"); 370 } 371 372 return objIn; 373 } 374 375 /** 376 * De-serializes a byte array in the context of a given MBean class loader. 377 * <P>The class loader is the one that loaded the class with name 378 * "className". 379 * <P>The name of the class loader to be used for loading the specified 380 * class is specified. If null, a default one has to be provided (for a 381 * MBean Server, its own class loader will be used). 382 * 383 * @param className The name of the class whose class loader should 384 * be used for the de-serialization. 385 * @param data The byte array to be de-sererialized. 386 * @param loaderName The name of the class loader to be used for loading 387 * the specified class. If null, a default one has to be provided (for a 388 * MBean Server, its own class loader will be used). 389 * 390 * @return The de-serialized object stream. 391 * 392 * @exception InstanceNotFoundException The specified class loader MBean is 393 * not found. 394 * @exception OperationsException Any of the usual Input/Output related 395 * exceptions. 396 * @exception ReflectionException The specified class could not be loaded 397 * by the specified class loader. 398 */ 399 public ObjectInputStream deserialize(String className, 400 ObjectName loaderName, 401 byte[] data, 402 ClassLoader loader) 403 throws InstanceNotFoundException, 404 OperationsException, 405 ReflectionException { 406 407 // Check parameter validity 408 if (data == null) { 409 throw new RuntimeOperationsException(new 410 IllegalArgumentException(), "Null data passed in parameter"); 411 } 412 if (data.length == 0) { 413 throw new RuntimeOperationsException(new 414 IllegalArgumentException(), "Empty data passed in parameter"); 415 } 416 if (className == null) { 417 throw new RuntimeOperationsException(new 418 IllegalArgumentException(), "Null className passed in parameter"); 419 } 420 421 ReflectUtil.checkPackageAccess(className); 422 Class<?> theClass; 423 if (loaderName == null) { 424 // Load the class using the agent class loader 425 theClass = findClass(className, loader); 426 427 } else { 428 // Get the class loader MBean 429 try { 430 ClassLoader instance = null; 431 432 instance = getClassLoader(loaderName); 433 if (instance == null) 434 throw new ClassNotFoundException(className); 435 theClass = Class.forName(className, false, instance); 436 } 437 catch (ClassNotFoundException e) { 438 throw new ReflectionException(e, 439 "The MBean class could not be loaded by the " + 440 loaderName.toString() + " class loader"); 441 } 442 } 443 444 // Object deserialization 445 ByteArrayInputStream bIn; 446 ObjectInputStream objIn; 447 448 bIn = new ByteArrayInputStream(data); 449 try { 450 objIn = new ObjectInputStreamWithLoader(bIn, 451 theClass.getClassLoader()); 452 } catch (IOException e) { 453 throw new OperationsException( 454 "An IOException occurred trying to de-serialize the data"); 455 } 456 457 return objIn; 458 } 459 460 461 /** 462 * Instantiates an object using the list of all class loaders registered 463 * in the MBean Interceptor 464 * (using its {@link javax.management.loading.ClassLoaderRepository}). 465 * <P>The object's class should have a public constructor. 466 * <P>It returns a reference to the newly created object. 467 * <P>The newly created object is not registered in the MBean Interceptor. 468 * 469 * @param className The class name of the object to be instantiated. 470 * 471 * @return The newly instantiated object. 472 * 473 * @exception ReflectionException Wraps a 474 * <CODE>java.lang.ClassNotFoundException</CODE> or the 475 * <CODE>java.lang.Exception</CODE> that occurred when trying to invoke the 476 * object's constructor. 477 * @exception MBeanException The constructor of the object has thrown an 478 * exception 479 * @exception RuntimeOperationsException Wraps a 480 * <CODE>java.lang.IllegalArgumentException</CODE>: the className passed in 481 * parameter is null. 482 */ 483 public Object instantiate(String className) 484 throws ReflectionException, 485 MBeanException { 486 487 return instantiate(className, (Object[]) null, (String[]) null, null); 488 } 489 490 491 492 /** 493 * Instantiates an object using the class Loader specified by its 494 * <CODE>ObjectName</CODE>. 495 * <P>If the loader name is null, a default one has to be provided (for a 496 * MBean Server, the ClassLoader that loaded it will be used). 497 * <P>The object's class should have a public constructor. 498 * <P>It returns a reference to the newly created object. 499 * <P>The newly created object is not registered in the MBean Interceptor. 500 * 501 * @param className The class name of the MBean to be instantiated. 502 * @param loaderName The object name of the class loader to be used. 503 * 504 * @return The newly instantiated object. 505 * 506 * @exception ReflectionException Wraps a 507 * <CODE>java.lang.ClassNotFoundException</CODE> or the 508 * <CODE>java.lang.Exception</CODE> that occurred when trying to invoke the 509 * object's constructor. 510 * @exception MBeanException The constructor of the object has thrown an 511 * exception. 512 * @exception InstanceNotFoundException The specified class loader is not 513 * registered in the MBeanServerInterceptor. 514 * @exception RuntimeOperationsException Wraps a 515 * <CODE>java.lang.IllegalArgumentException</CODE>: the className passed in 516 * parameter is null. 517 */ 518 public Object instantiate(String className, ObjectName loaderName, 519 ClassLoader loader) 520 throws ReflectionException, MBeanException, 521 InstanceNotFoundException { 522 523 return instantiate(className, loaderName, (Object[]) null, 524 (String[]) null, loader); 525 } 526 527 528 /** 529 * Instantiates an object using the list of all class loaders registered 530 * in the MBean server 531 * (using its {@link javax.management.loading.ClassLoaderRepository}). 532 * <P>The object's class should have a public constructor. 533 * <P>The call returns a reference to the newly created object. 534 * <P>The newly created object is not registered in the MBean Interceptor. 535 * 536 * @param className The class name of the object to be instantiated. 537 * @param params An array containing the parameters of the constructor to 538 * be invoked. 539 * @param signature An array containing the signature of the constructor to 540 * be invoked. 541 * 542 * @return The newly instantiated object. 543 * 544 * @exception ReflectionException Wraps a 545 * <CODE>java.lang.ClassNotFoundException</CODE> or the 546 * <CODE>java.lang.Exception</CODE> that occurred when trying to invoke the 547 * object's constructor. 548 * @exception MBeanException The constructor of the object has thrown an 549 * exception 550 * @exception RuntimeOperationsException Wraps a 551 * <CODE>java.lang.IllegalArgumentException</CODE>: the className passed in 552 * parameter is null. 553 */ 554 public Object instantiate(String className, 555 Object params[], 556 String signature[], 557 ClassLoader loader) 558 throws ReflectionException, 559 MBeanException { 560 561 Class<?> theClass = findClassWithDefaultLoaderRepository(className); 562 return instantiate(theClass, params, signature, loader); 563 } 564 565 566 567 /** 568 * Instantiates an object. The class loader to be used is identified by its 569 * object name. 570 * <P>If the object name of the loader is null, a default has to be 571 * provided (for example, for a MBean Server, the ClassLoader that loaded 572 * it will be used). 573 * <P>The object's class should have a public constructor. 574 * <P>The call returns a reference to the newly created object. 575 * <P>The newly created object is not registered in the MBean server. 576 * 577 * @param className The class name of the object to be instantiated. 578 * @param params An array containing the parameters of the constructor to 579 * be invoked. 580 * @param signature An array containing the signature of the constructor to 581 * be invoked. 582 * @param loaderName The object name of the class loader to be used. 583 * 584 * @return The newly instantiated object. 585 * 586 * @exception ReflectionException Wraps a 587 * <CODE>java.lang.ClassNotFoundException</CODE> or the 588 * <CODE>java.lang.Exception</CODE> that occurred when trying to invoke the 589 * object's constructor. 590 * @exception MBeanException The constructor of the object has thrown an 591 * exception 592 * @exception InstanceNotFoundException The specified class loader is not 593 * registered in the MBean Interceptor. 594 * @exception RuntimeOperationsException Wraps a 595 * <CODE>java.lang.IllegalArgumentException</CODE>: the className passed in 596 * parameter is null. 597 */ 598 public Object instantiate(String className, 599 ObjectName loaderName, 600 Object params[], 601 String signature[], 602 ClassLoader loader) 603 throws ReflectionException, 604 MBeanException, 605 InstanceNotFoundException { 606 607 // ------------------------------ 608 // ------------------------------ 609 Class<?> theClass; 610 611 if (loaderName == null) { 612 theClass = findClass(className, loader); 613 } else { 614 theClass = findClass(className, loaderName); 615 } 616 return instantiate(theClass, params, signature, loader); 617 } 618 619 620 /** 621 * Return the Default Loader Repository used by this instantiator object. 622 **/ 623 public ModifiableClassLoaderRepository getClassLoaderRepository() { 624 checkMBeanPermission((String)null, null, null, "getClassLoaderRepository"); 625 return clr; 626 } 627 628 /** 629 * Load a class with the specified loader, or with this object 630 * class loader if the specified loader is null. 631 **/ 632 static Class<?> loadClass(String className, ClassLoader loader) 633 throws ReflectionException { 634 Class<?> theClass; 635 if (className == null) { 636 throw new RuntimeOperationsException(new 637 IllegalArgumentException("The class name cannot be null"), 638 "Exception occurred during object instantiation"); 639 } 640 ReflectUtil.checkPackageAccess(className); 641 try { 642 if (loader == null) 643 loader = MBeanInstantiator.class.getClassLoader(); 644 if (loader != null) { 645 theClass = Class.forName(className, false, loader); 646 } else { 647 theClass = Class.forName(className); 648 } 649 } catch (ClassNotFoundException e) { 650 throw new ReflectionException(e, 651 "The MBean class could not be loaded"); 652 } 653 return theClass; 654 } 655 656 657 658 /** 659 * Load the classes specified in the signature with the given loader, 660 * or with this object class loader. 661 **/ 662 static Class<?>[] loadSignatureClasses(String signature[], 663 ClassLoader loader) 664 throws ReflectionException { 665 666 if (signature == null) return null; 667 final ClassLoader aLoader = 668 (loader==null?MBeanInstantiator.class.getClassLoader():loader); 669 final int length= signature.length; 670 final Class<?> tab[]=new Class<?>[length]; 671 672 if (length == 0) return tab; 673 try { 674 for (int i= 0; i < length; i++) { 675 // Start handling primitive types (int. boolean and so 676 // forth) 677 // 678 679 final Class<?> primCla = primitiveClasses.get(signature[i]); 680 if (primCla != null) { 681 tab[i] = primCla; 682 continue; 683 } 684 685 // Ok we do not have a primitive type ! We need to build 686 // the signature of the method 687 // 688 // We need to load the class through the class 689 // loader of the target object. 690 // 691 ReflectUtil.checkPackageAccess(signature[i]); 692 tab[i] = Class.forName(signature[i], false, aLoader); 693 } 694 } catch (ClassNotFoundException e) { 695 if (MBEANSERVER_LOGGER.isLoggable(Level.DEBUG)) { 696 MBEANSERVER_LOGGER.log(Level.DEBUG, 697 "The parameter class could not be found", e); 698 } 699 throw new ReflectionException(e, 700 "The parameter class could not be found"); 701 } catch (RuntimeException e) { 702 if (MBEANSERVER_LOGGER.isLoggable(Level.DEBUG)) { 703 MBEANSERVER_LOGGER.log(Level.DEBUG, 704 "Unexpected exception", e); 705 } 706 throw e; 707 } 708 return tab; 709 } 710 711 private Constructor<?> findConstructor(Class<?> c, Class<?>[] params) { 712 try { 713 return ConstructorUtil.getConstructor(c, params); 714 } catch (Exception e) { 715 return null; 716 } 717 } 718 719 720 private static final Map<String, Class<?>> primitiveClasses = Util.newMap(); 721 static { 722 for (Class<?> c : new Class<?>[] {byte.class, short.class, int.class, 723 long.class, float.class, double.class, 724 char.class, boolean.class}) 725 primitiveClasses.put(c.getName(), c); 726 } 727 728 private static void checkMBeanPermission(Class<?> clazz, 729 String member, 730 ObjectName objectName, 731 String actions) { 732 if (clazz != null) { 733 checkMBeanPermission(clazz.getName(), member, objectName, actions); 734 } 735 } 736 737 private static void checkMBeanPermission(String classname, 738 String member, 739 ObjectName objectName, 740 String actions) 741 throws SecurityException { 742 SecurityManager sm = System.getSecurityManager(); 743 if (sm != null) { 744 Permission perm = new MBeanPermission(classname, 745 member, 746 objectName, 747 actions); 748 sm.checkPermission(perm); 749 } 750 } 751 752 private static void ensureClassAccess(Class<?> clazz) 753 throws IllegalAccessException 754 { 755 int mod = clazz.getModifiers(); 756 if (!Modifier.isPublic(mod)) { 757 throw new IllegalAccessException("Class is not public and can't be instantiated"); 758 } 759 } 760 761 private ClassLoader getClassLoader(final ObjectName name) { 762 if(clr == null){ 763 return null; 764 } 765 // Restrict to getClassLoader permission only 766 Permissions permissions = new Permissions(); 767 permissions.add(new MBeanPermission("*", null, name, "getClassLoader")); 768 ProtectionDomain protectionDomain = new ProtectionDomain(null, permissions); 769 ProtectionDomain[] domains = {protectionDomain}; 770 AccessControlContext ctx = new AccessControlContext(domains); 771 ClassLoader loader = AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() { 772 public ClassLoader run() { 773 return clr.getClassLoader(name); 774 } 775 }, ctx); 776 return loader; 777 } 778} 779