1 /* 2 * Copyright (c) 1996, 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. 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 26 package java.rmi.server; 27 28 import java.net.MalformedURLException; 29 import java.net.URL; 30 import java.security.AccessController; 31 import java.security.PrivilegedAction; 32 import java.util.Iterator; 33 import java.util.ServiceLoader; 34 35 /** 36 * <code>RMIClassLoader</code> comprises static methods to support 37 * dynamic class loading with RMI. Included are methods for loading 38 * classes from a network location (one or more URLs) and obtaining 39 * the location from which an existing class should be loaded by 40 * remote parties. These methods are used by the RMI runtime when 41 * marshalling and unmarshalling classes contained in the arguments 42 * and return values of remote method calls, and they also may be 43 * invoked directly by applications in order to mimic RMI's dynamic 44 * class loading behavior. 45 * 46 * <p>The implementation of the following static methods 47 * 48 * <ul> 49 * 50 * <li>{@link #loadClass(URL,String)} 51 * <li>{@link #loadClass(String,String)} 52 * <li>{@link #loadClass(String,String,ClassLoader)} 53 * <li>{@link #loadProxyClass(String,String[],ClassLoader)} 54 * <li>{@link #getClassLoader(String)} 55 * <li>{@link #getClassAnnotation(Class)} 56 * 57 * </ul> 58 * 59 * is provided by an instance of {@link RMIClassLoaderSpi}, the 60 * service provider interface for those methods. When one of the 61 * methods is invoked, its behavior is to delegate to a corresponding 62 * method on the service provider instance. The details of how each 63 * method delegates to the provider instance is described in the 64 * documentation for each particular method. 65 * 66 * <p>The service provider instance is chosen as follows: 67 * 68 * <ul> 69 * 70 * <li>If the system property 71 * <code>java.rmi.server.RMIClassLoaderSpi</code> is defined, then if 72 * its value equals the string <code>"default"</code>, the provider 73 * instance will be the value returned by an invocation of the {@link 74 * #getDefaultProviderInstance()} method, and for any other value, if 75 * a class named with the value of the property can be loaded by the 76 * system class loader (see {@link ClassLoader#getSystemClassLoader}) 77 * and that class is assignable to {@link RMIClassLoaderSpi} and has a 78 * public no-argument constructor, then that constructor will be 79 * invoked to create the provider instance. If the property is 80 * defined but any other of those conditions are not true, then an 81 * unspecified <code>Error</code> will be thrown to code that attempts 82 * to use <code>RMIClassLoader</code>, indicating the failure to 83 * obtain a provider instance. 84 * 85 * <li>If a resource named 86 * <code>META-INF/services/java.rmi.server.RMIClassLoaderSpi</code> is 87 * visible to the system class loader, then the contents of that 88 * resource are interpreted as a provider-configuration file, and the 89 * first class name specified in that file is used as the provider 90 * class name. If a class with that name can be loaded by the system 91 * class loader and that class is assignable to {@link 92 * RMIClassLoaderSpi} and has a public no-argument constructor, then 93 * that constructor will be invoked to create the provider instance. 94 * If the resource is found but a provider cannot be instantiated as 95 * described, then an unspecified <code>Error</code> will be thrown to 96 * code that attempts to use <code>RMIClassLoader</code>, indicating 97 * the failure to obtain a provider instance. 98 * 99 * <li>Otherwise, the provider instance will be the value returned by 100 * an invocation of the {@link #getDefaultProviderInstance()} method. 101 * 102 * </ul> 103 * 104 * @author Ann Wollrath 105 * @author Peter Jones 106 * @author Laird Dornin 107 * @see RMIClassLoaderSpi 108 * @since 1.1 109 */ 110 public class RMIClassLoader { 111 112 /** "default" provider instance */ 113 private static final RMIClassLoaderSpi defaultProvider = 114 newDefaultProviderInstance(); 115 116 /** provider instance */ 117 private static final RMIClassLoaderSpi provider = 118 AccessController.doPrivileged( 119 new PrivilegedAction<RMIClassLoaderSpi>() { 120 public RMIClassLoaderSpi run() { return initializeProvider(); } 121 }); 122 123 /* 124 * Disallow anyone from creating one of these. 125 */ 126 private RMIClassLoader() {} 127 128 /** 129 * Loads the class with the specified <code>name</code>. 130 * 131 * <p>This method delegates to {@link #loadClass(String,String)}, 132 * passing <code>null</code> as the first argument and 133 * <code>name</code> as the second argument. 134 * 135 * @param name the name of the class to load 136 * 137 * @return the <code>Class</code> object representing the loaded class 138 * 139 * @throws MalformedURLException if a provider-specific URL used 140 * to load classes is invalid 141 * 142 * @throws ClassNotFoundException if a definition for the class 143 * could not be found at the codebase location 144 * 145 * @deprecated replaced by <code>loadClass(String,String)</code> method 146 * @see #loadClass(String,String) 147 */ 148 @Deprecated 149 public static Class<?> loadClass(String name) 150 throws MalformedURLException, ClassNotFoundException 151 { 152 return loadClass((String) null, name); 153 } 154 155 /** 156 * Loads a class from a codebase URL. 157 * 158 * If <code>codebase</code> is <code>null</code>, then this method 159 * will behave the same as {@link #loadClass(String,String)} with a 160 * <code>null</code> <code>codebase</code> and the given class name. 161 * 162 * <p>This method delegates to the 163 * {@link RMIClassLoaderSpi#loadClass(String,String,ClassLoader)} 164 * method of the provider instance, passing the result of invoking 165 * {@link URL#toString} on the given URL (or <code>null</code> if 166 * <code>codebase</code> is null) as the first argument, 167 * <code>name</code> as the second argument, 168 * and <code>null</code> as the third argument. 169 * 170 * @param codebase the URL to load the class from, or <code>null</code> 171 * 172 * @param name the name of the class to load 173 * 174 * @return the <code>Class</code> object representing the loaded class 175 * 176 * @throws MalformedURLException if <code>codebase</code> is 177 * <code>null</code> and a provider-specific URL used 178 * to load classes is invalid 179 * 180 * @throws ClassNotFoundException if a definition for the class 181 * could not be found at the specified URL 182 */ 183 public static Class<?> loadClass(URL codebase, String name) 184 throws MalformedURLException, ClassNotFoundException 185 { 186 return provider.loadClass( 187 codebase != null ? codebase.toString() : null, name, null); 188 } 189 190 /** 191 * Loads a class from a codebase URL path. 192 * 193 * <p>This method delegates to the 194 * {@link RMIClassLoaderSpi#loadClass(String,String,ClassLoader)} 195 * method of the provider instance, passing <code>codebase</code> 196 * as the first argument, <code>name</code> as the second argument, 197 * and <code>null</code> as the third argument. 198 * 199 * @param codebase the list of URLs (separated by spaces) to load 200 * the class from, or <code>null</code> 201 * 202 * @param name the name of the class to load 203 * 204 * @return the <code>Class</code> object representing the loaded class 205 * 206 * @throws MalformedURLException if <code>codebase</code> is 207 * non-<code>null</code> and contains an invalid URL, or if 208 * <code>codebase</code> is <code>null</code> and a provider-specific 209 * URL used to load classes is invalid 210 * 211 * @throws ClassNotFoundException if a definition for the class 212 * could not be found at the specified location 213 * 214 * @since 1.2 215 */ 216 public static Class<?> loadClass(String codebase, String name) 217 throws MalformedURLException, ClassNotFoundException 218 { 219 return provider.loadClass(codebase, name, null); 220 } 221 222 /** 223 * Loads a class from a codebase URL path, optionally using the 224 * supplied loader. 225 * 226 * This method should be used when the caller would like to make 227 * available to the provider implementation an additional contextual 228 * class loader to consider, such as the loader of a caller on the 229 * stack. Typically, a provider implementation will attempt to 230 * resolve the named class using the given <code>defaultLoader</code>, 231 * if specified, before attempting to resolve the class from the 232 * codebase URL path. 233 * 234 * <p>This method delegates to the 235 * {@link RMIClassLoaderSpi#loadClass(String,String,ClassLoader)} 236 * method of the provider instance, passing <code>codebase</code> 237 * as the first argument, <code>name</code> as the second argument, 238 * and <code>defaultLoader</code> as the third argument. 239 * 240 * @param codebase the list of URLs (separated by spaces) to load 241 * the class from, or <code>null</code> 242 * 243 * @param name the name of the class to load 244 * 245 * @param defaultLoader additional contextual class loader 246 * to use, or <code>null</code> 247 * 248 * @return the <code>Class</code> object representing the loaded class 249 * 250 * @throws MalformedURLException if <code>codebase</code> is 251 * non-<code>null</code> and contains an invalid URL, or if 252 * <code>codebase</code> is <code>null</code> and a provider-specific 253 * URL used to load classes is invalid 254 * 255 * @throws ClassNotFoundException if a definition for the class 256 * could not be found at the specified location 257 * 258 * @since 1.4 259 */ 260 public static Class<?> loadClass(String codebase, String name, 261 ClassLoader defaultLoader) 262 throws MalformedURLException, ClassNotFoundException 263 { 264 return provider.loadClass(codebase, name, defaultLoader); 265 } 266 267 /** 268 * Loads a dynamic proxy class (see {@link java.lang.reflect.Proxy}) 269 * that implements a set of interfaces with the given names 270 * from a codebase URL path. 271 * 272 * <p>The interfaces will be resolved similar to classes loaded via 273 * the {@link #loadClass(String,String)} method using the given 274 * <code>codebase</code>. 275 * 276 * <p>This method delegates to the 277 * {@link RMIClassLoaderSpi#loadProxyClass(String,String[],ClassLoader)} 278 * method of the provider instance, passing <code>codebase</code> 279 * as the first argument, <code>interfaces</code> as the second argument, 280 * and <code>defaultLoader</code> as the third argument. 281 * 282 * @param codebase the list of URLs (space-separated) to load 283 * classes from, or <code>null</code> 284 * 285 * @param interfaces the names of the interfaces for the proxy class 286 * to implement 287 * 288 * @param defaultLoader additional contextual class loader 289 * to use, or <code>null</code> 290 * 291 * @return a dynamic proxy class that implements the named interfaces 292 * 293 * @throws MalformedURLException if <code>codebase</code> is 294 * non-<code>null</code> and contains an invalid URL, or 295 * if <code>codebase</code> is <code>null</code> and a provider-specific 296 * URL used to load classes is invalid 297 * 298 * @throws ClassNotFoundException if a definition for one of 299 * the named interfaces could not be found at the specified location, 300 * or if creation of the dynamic proxy class failed (such as if 301 * {@link java.lang.reflect.Proxy#getProxyClass(ClassLoader,Class[])} 302 * would throw an <code>IllegalArgumentException</code> for the given 303 * interface list) 304 * 305 * @since 1.4 306 */ 307 public static Class<?> loadProxyClass(String codebase, String[] interfaces, 308 ClassLoader defaultLoader) 309 throws ClassNotFoundException, MalformedURLException 310 { 311 return provider.loadProxyClass(codebase, interfaces, defaultLoader); 312 } 313 314 /** 315 * Returns a class loader that loads classes from the given codebase 316 * URL path. 317 * 318 * <p>The class loader returned is the class loader that the 319 * {@link #loadClass(String,String)} method would use to load classes 320 * for the same <code>codebase</code> argument. 321 * 322 * <p>This method delegates to the 323 * {@link RMIClassLoaderSpi#getClassLoader(String)} method 324 * of the provider instance, passing <code>codebase</code> as the argument. 325 * 326 * <p>If there is a security manger, its <code>checkPermission</code> 327 * method will be invoked with a 328 * <code>RuntimePermission("getClassLoader")</code> permission; 329 * this could result in a <code>SecurityException</code>. 330 * The provider implementation of this method may also perform further 331 * security checks to verify that the calling context has permission to 332 * connect to all of the URLs in the codebase URL path. 333 * 334 * @param codebase the list of URLs (space-separated) from which 335 * the returned class loader will load classes from, or <code>null</code> 336 * 337 * @return a class loader that loads classes from the given codebase URL 338 * path 339 * 340 * @throws MalformedURLException if <code>codebase</code> is 341 * non-<code>null</code> and contains an invalid URL, or 342 * if <code>codebase</code> is <code>null</code> and a provider-specific 343 * URL used to identify the class loader is invalid 344 * 345 * @throws SecurityException if there is a security manager and the 346 * invocation of its <code>checkPermission</code> method fails, or 347 * if the caller does not have permission to connect to all of the 348 * URLs in the codebase URL path 349 * 350 * @since 1.3 351 */ 352 public static ClassLoader getClassLoader(String codebase) 353 throws MalformedURLException, SecurityException 354 { 355 return provider.getClassLoader(codebase); 356 } 357 358 /** 359 * Returns the annotation string (representing a location for 360 * the class definition) that RMI will use to annotate the class 361 * descriptor when marshalling objects of the given class. 362 * 363 * <p>This method delegates to the 364 * {@link RMIClassLoaderSpi#getClassAnnotation(Class)} method 365 * of the provider instance, passing <code>cl</code> as the argument. 366 * 367 * @param cl the class to obtain the annotation for 368 * 369 * @return a string to be used to annotate the given class when 370 * it gets marshalled, or <code>null</code> 371 * 372 * @throws NullPointerException if <code>cl</code> is <code>null</code> 373 * 374 * @since 1.2 375 */ 376 /* 377 * REMIND: Should we say that the returned class annotation will or 378 * should be a (space-separated) list of URLs? 379 */ 380 public static String getClassAnnotation(Class<?> cl) { 381 return provider.getClassAnnotation(cl); 382 } 383 384 /** 385 * Returns the canonical instance of the default provider 386 * for the service provider interface {@link RMIClassLoaderSpi}. 387 * If the system property <code>java.rmi.server.RMIClassLoaderSpi</code> 388 * is not defined, then the <code>RMIClassLoader</code> static 389 * methods 390 * 391 * <ul> 392 * 393 * <li>{@link #loadClass(URL,String)} 394 * <li>{@link #loadClass(String,String)} 395 * <li>{@link #loadClass(String,String,ClassLoader)} 396 * <li>{@link #loadProxyClass(String,String[],ClassLoader)} 397 * <li>{@link #getClassLoader(String)} 398 * <li>{@link #getClassAnnotation(Class)} 399 * 400 * </ul> 401 * 402 * will use the canonical instance of the default provider 403 * as the service provider instance. 404 * 405 * <p>If there is a security manager, its 406 * <code>checkPermission</code> method will be invoked with a 407 * <code>RuntimePermission("setFactory")</code> permission; this 408 * could result in a <code>SecurityException</code>. 409 * 410 * <p>The default service provider instance implements 411 * {@link RMIClassLoaderSpi} as follows: 412 * 413 * <blockquote> 414 * 415 * <p>The <b>{@link RMIClassLoaderSpi#getClassAnnotation(Class) 416 * getClassAnnotation}</b> method returns a <code>String</code> 417 * representing the codebase URL path that a remote party should 418 * use to download the definition for the specified class. The 419 * format of the returned string is a path of URLs separated by 420 * spaces. 421 * 422 * The codebase string returned depends on the defining class 423 * loader of the specified class: 424 * 425 * <ul> 426 * 427 * <li><p>If the class loader is the system class loader (see 428 * {@link ClassLoader#getSystemClassLoader}), a parent of the 429 * system class loader such as the loader used for installed 430 * extensions, or the bootstrap class loader (which may be 431 * represented by <code>null</code>), then the value of the 432 * <code>java.rmi.server.codebase</code> property (or possibly an 433 * earlier cached value) is returned, or 434 * <code>null</code> is returned if that property is not set. 435 * 436 * <li><p>Otherwise, if the class loader is an instance of 437 * <code>URLClassLoader</code>, then the returned string is a 438 * space-separated list of the external forms of the URLs returned 439 * by invoking the <code>getURLs</code> methods of the loader. If 440 * the <code>URLClassLoader</code> was created by this provider to 441 * service an invocation of its <code>loadClass</code> or 442 * <code>loadProxyClass</code> methods, then no permissions are 443 * required to get the associated codebase string. If it is an 444 * arbitrary other <code>URLClassLoader</code> instance, then if 445 * there is a security manager, its <code>checkPermission</code> 446 * method will be invoked once for each URL returned by the 447 * <code>getURLs</code> method, with the permission returned by 448 * invoking <code>openConnection().getPermission()</code> on each 449 * URL; if any of those invocations throws a 450 * <code>SecurityException</code> or an <code>IOException</code>, 451 * then the value of the <code>java.rmi.server.codebase</code> 452 * property (or possibly an earlier cached value) is returned, or 453 * <code>null</code> is returned if that property is not set. 454 * 455 * <li><p>Finally, if the class loader is not an instance of 456 * <code>URLClassLoader</code>, then the value of the 457 * <code>java.rmi.server.codebase</code> property (or possibly an 458 * earlier cached value) is returned, or 459 * <code>null</code> is returned if that property is not set. 460 * 461 * </ul> 462 * 463 * <p>For the implementations of the methods described below, 464 * which all take a <code>String</code> parameter named 465 * <code>codebase</code> that is a space-separated list of URLs, 466 * each invocation has an associated <i>codebase loader</i> that 467 * is identified using the <code>codebase</code> argument in 468 * conjunction with the current thread's context class loader (see 469 * {@link Thread#getContextClassLoader()}). When there is a 470 * security manager, this provider maintains an internal table of 471 * class loader instances (which are at least instances of {@link 472 * java.net.URLClassLoader}) keyed by the pair of their parent 473 * class loader and their codebase URL path (an ordered list of 474 * URLs). If the <code>codebase</code> argument is <code>null</code>, 475 * the codebase URL path is the value of the system property 476 * <code>java.rmi.server.codebase</code> or possibly an 477 * earlier cached value. For a given codebase URL path passed as the 478 * <code>codebase</code> argument to an invocation of one of the 479 * below methods in a given context, the codebase loader is the 480 * loader in the table with the specified codebase URL path and 481 * the current thread's context class loader as its parent. If no 482 * such loader exists, then one is created and added to the table. 483 * The table does not maintain strong references to its contained 484 * loaders, in order to allow them and their defined classes to be 485 * garbage collected when not otherwise reachable. In order to 486 * prevent arbitrary untrusted code from being implicitly loaded 487 * into a virtual machine with no security manager, if there is no 488 * security manager set, the codebase loader is just the current 489 * thread's context class loader (the supplied codebase URL path 490 * is ignored, so remote class loading is disabled). 491 * 492 * <p>The <b>{@link RMIClassLoaderSpi#getClassLoader(String) 493 * getClassLoader}</b> method returns the codebase loader for the 494 * specified codebase URL path. If there is a security manager, 495 * then if the calling context does not have permission to connect 496 * to all of the URLs in the codebase URL path, a 497 * <code>SecurityException</code> will be thrown. 498 * 499 * <p>The <b>{@link 500 * RMIClassLoaderSpi#loadClass(String,String,ClassLoader) 501 * loadClass}</b> method attempts to load the class with the 502 * specified name as follows: 503 * 504 * <blockquote> 505 * 506 * If the <code>defaultLoader</code> argument is 507 * non-<code>null</code>, it first attempts to load the class with the 508 * specified <code>name</code> using the 509 * <code>defaultLoader</code>, such as by evaluating 510 * 511 * <pre> 512 * Class.forName(name, false, defaultLoader) 513 * </pre> 514 * 515 * If the class is successfully loaded from the 516 * <code>defaultLoader</code>, that class is returned. If an 517 * exception other than <code>ClassNotFoundException</code> is 518 * thrown, that exception is thrown to the caller. 519 * 520 * <p>Next, the <code>loadClass</code> method attempts to load the 521 * class with the specified <code>name</code> using the codebase 522 * loader for the specified codebase URL path. 523 * If there is a security manager, then the calling context 524 * must have permission to connect to all of the URLs in the 525 * codebase URL path; otherwise, the current thread's context 526 * class loader will be used instead of the codebase loader. 527 * 528 * </blockquote> 529 * 530 * <p>The <b>{@link 531 * RMIClassLoaderSpi#loadProxyClass(String,String[],ClassLoader) 532 * loadProxyClass}</b> method attempts to return a dynamic proxy 533 * class with the named interface as follows: 534 * 535 * <blockquote> 536 * 537 * <p>If the <code>defaultLoader</code> argument is 538 * non-<code>null</code> and all of the named interfaces can be 539 * resolved through that loader, then, 540 * 541 * <ul> 542 * 543 * <li>if all of the resolved interfaces are <code>public</code>, 544 * then it first attempts to obtain a dynamic proxy class (using 545 * {@link 546 * java.lang.reflect.Proxy#getProxyClass(ClassLoader,Class[]) 547 * Proxy.getProxyClass}) for the resolved interfaces defined in 548 * the codebase loader; if that attempt throws an 549 * <code>IllegalArgumentException</code>, it then attempts to 550 * obtain a dynamic proxy class for the resolved interfaces 551 * defined in the <code>defaultLoader</code>. If both attempts 552 * throw <code>IllegalArgumentException</code>, then this method 553 * throws a <code>ClassNotFoundException</code>. If any other 554 * exception is thrown, that exception is thrown to the caller. 555 * 556 * <li>if all of the non-<code>public</code> resolved interfaces 557 * are defined in the same class loader, then it attempts to 558 * obtain a dynamic proxy class for the resolved interfaces 559 * defined in that loader. 560 * 561 * <li>otherwise, a <code>LinkageError</code> is thrown (because a 562 * class that implements all of the specified interfaces cannot be 563 * defined in any loader). 564 * 565 * </ul> 566 * 567 * <p>Otherwise, if all of the named interfaces can be resolved 568 * through the codebase loader, then, 569 * 570 * <ul> 571 * 572 * <li>if all of the resolved interfaces are <code>public</code>, 573 * then it attempts to obtain a dynamic proxy class for the 574 * resolved interfaces in the codebase loader. If the attempt 575 * throws an <code>IllegalArgumentException</code>, then this 576 * method throws a <code>ClassNotFoundException</code>. 577 * 578 * <li>if all of the non-<code>public</code> resolved interfaces 579 * are defined in the same class loader, then it attempts to 580 * obtain a dynamic proxy class for the resolved interfaces 581 * defined in that loader. 582 * 583 * <li>otherwise, a <code>LinkageError</code> is thrown (because a 584 * class that implements all of the specified interfaces cannot be 585 * defined in any loader). 586 * 587 * </ul> 588 * 589 * <p>Otherwise, a <code>ClassNotFoundException</code> is thrown 590 * for one of the named interfaces that could not be resolved. 591 * 592 * </blockquote> 593 * 594 * </blockquote> 595 * 596 * @return the canonical instance of the default service provider 597 * 598 * @throws SecurityException if there is a security manager and the 599 * invocation of its <code>checkPermission</code> method fails 600 * 601 * @since 1.4 602 */ 603 public static RMIClassLoaderSpi getDefaultProviderInstance() { 604 SecurityManager sm = System.getSecurityManager(); 605 if (sm != null) { 606 sm.checkPermission(new RuntimePermission("setFactory")); 607 } 608 return defaultProvider; 609 } 610 611 /** 612 * Returns the security context of the given class loader. 613 * 614 * @param loader a class loader from which to get the security context 615 * 616 * @return the security context 617 * 618 * @deprecated no replacement. As of the Java 2 platform v1.2, RMI no 619 * longer uses this method to obtain a class loader's security context. 620 * @see java.lang.SecurityManager#getSecurityContext() 621 */ 622 @Deprecated 623 public static Object getSecurityContext(ClassLoader loader) 624 { 625 return sun.rmi.server.LoaderHandler.getSecurityContext(loader); 626 } 627 628 /** 629 * Creates an instance of the default provider class. 630 */ 631 private static RMIClassLoaderSpi newDefaultProviderInstance() { 632 return new RMIClassLoaderSpi() { 633 public Class<?> loadClass(String codebase, String name, 634 ClassLoader defaultLoader) 635 throws MalformedURLException, ClassNotFoundException 636 { 637 return sun.rmi.server.LoaderHandler.loadClass( 638 codebase, name, defaultLoader); 639 } 640 641 public Class<?> loadProxyClass(String codebase, 642 String[] interfaces, 643 ClassLoader defaultLoader) 644 throws MalformedURLException, ClassNotFoundException 645 { 646 return sun.rmi.server.LoaderHandler.loadProxyClass( 647 codebase, interfaces, defaultLoader); 648 } 649 650 public ClassLoader getClassLoader(String codebase) 651 throws MalformedURLException 652 { 653 return sun.rmi.server.LoaderHandler.getClassLoader(codebase); 654 } 655 656 public String getClassAnnotation(Class<?> cl) { 657 return sun.rmi.server.LoaderHandler.getClassAnnotation(cl); 658 } 659 }; 660 } 661 662 /** 663 * Chooses provider instance, following above documentation. 664 * 665 * This method assumes that it has been invoked in a privileged block. 666 */ 667 private static RMIClassLoaderSpi initializeProvider() { 668 /* 669 * First check for the system property being set: 670 */ 671 String providerClassName = 672 System.getProperty("java.rmi.server.RMIClassLoaderSpi"); 673 674 if (providerClassName != null) { 675 if (providerClassName.equals("default")) { 676 return defaultProvider; 677 } 678 679 try { 680 Class<? extends RMIClassLoaderSpi> providerClass = 681 Class.forName(providerClassName, false, 682 ClassLoader.getSystemClassLoader()) 683 .asSubclass(RMIClassLoaderSpi.class); 684 return providerClass.newInstance(); 685 686 } catch (ClassNotFoundException e) { 687 throw new NoClassDefFoundError(e.getMessage()); 688 } catch (IllegalAccessException e) { 689 throw new IllegalAccessError(e.getMessage()); 690 } catch (InstantiationException e) { 691 throw new InstantiationError(e.getMessage()); 692 } catch (ClassCastException e) { 693 Error error = new LinkageError( 694 "provider class not assignable to RMIClassLoaderSpi"); 695 error.initCause(e); 696 throw error; 697 } 698 } 699 700 /* 701 * Next look for a provider configuration file installed: 702 */ 703 Iterator<RMIClassLoaderSpi> iter = 704 ServiceLoader.load(RMIClassLoaderSpi.class, 705 ClassLoader.getSystemClassLoader()).iterator(); 706 if (iter.hasNext()) { 707 try { 708 return iter.next(); 709 } catch (ClassCastException e) { 710 Error error = new LinkageError( 711 "provider class not assignable to RMIClassLoaderSpi"); 712 error.initCause(e); 713 throw error; 714 } 715 } 716 717 /* 718 * Finally, return the canonical instance of the default provider. 719 */ 720 return defaultProvider; 721 } 722 }