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