1. /*
  2. * @(#)RMIClassLoader.java 1.40 04/05/18
  3. *
  4. * Copyright 2004 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.40, 04/05/18
  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 the class with the specified <code>name</code>.
  104. *
  105. * <p>This method delegates to {@link #loadClass(String,String)},
  106. * passing <code>null</code> as the first argument and
  107. * <code>name</code> as the second argument.
  108. *
  109. * @param name the name of the class to load
  110. *
  111. * @return the <code>Class</code> object representing the loaded class
  112. *
  113. * @throws MalformedURLException if a provider-specific URL used
  114. * to load classes is invalid
  115. *
  116. * @throws ClassNotFoundException if a definition for the class
  117. * could not be found at the codebase location
  118. *
  119. * @deprecated replaced by <code>loadClass(String,String)</code> method
  120. * @see #loadClass(String,String)
  121. */
  122. @Deprecated
  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 a provider-specific URL used
  151. * to load classes is invalid
  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. * <p>This method delegates to the
  166. * {@link RMIClassLoaderSpi#loadClass(String,String,ClassLoader)}
  167. * method of the provider instance, passing <code>codebase</code>
  168. * as the first argument, <code>name</code> as the second argument,
  169. * and <code>null</code> as the third argument.
  170. *
  171. * @param codebase the list of URLs (separated by spaces) to load
  172. * the class from, or <code>null</code>
  173. *
  174. * @param name the name of the class to load
  175. *
  176. * @return the <code>Class</code> object representing the loaded class
  177. *
  178. * @throws MalformedURLException if <code>codebase</code> is
  179. * non-<code>null</code> and contains an invalid URL, or if
  180. * <code>codebase</code> is <code>null</code> and a provider-specific
  181. * URL used to load classes is invalid
  182. *
  183. * @throws ClassNotFoundException if a definition for the class
  184. * could not be found at the specified location
  185. *
  186. * @since 1.2
  187. */
  188. public static Class<?> loadClass(String codebase, String name)
  189. throws MalformedURLException, ClassNotFoundException
  190. {
  191. return provider.loadClass(codebase, name, null);
  192. }
  193. /**
  194. * Loads a class from a codebase URL path, optionally using the
  195. * supplied loader.
  196. *
  197. * This method should be used when the caller would like to make
  198. * available to the provider implementation an additional contextual
  199. * class loader to consider, such as the loader of a caller on the
  200. * stack. Typically, a provider implementation will attempt to
  201. * resolve the named class using the given <code>defaultLoader</code>,
  202. * if specified, before attempting to resolve the class from the
  203. * codebase URL path.
  204. *
  205. * <p>This method delegates to the
  206. * {@link RMIClassLoaderSpi#loadClass(String,String,ClassLoader)}
  207. * method of the provider instance, passing <code>codebase</code>
  208. * as the first argument, <code>name</code> as the second argument,
  209. * and <code>defaultLoader</code> as the third argument.
  210. *
  211. * @param codebase the list of URLs (separated by spaces) to load
  212. * the class from, or <code>null</code>
  213. *
  214. * @param name the name of the class to load
  215. *
  216. * @param defaultLoader additional contextual class loader
  217. * to use, or <code>null</code>
  218. *
  219. * @return the <code>Class</code> object representing the loaded class
  220. *
  221. * @throws MalformedURLException if <code>codebase</code> is
  222. * non-<code>null</code> and contains an invalid URL, or if
  223. * <code>codebase</code> is <code>null</code> and a provider-specific
  224. * URL used to load classes is invalid
  225. *
  226. * @throws ClassNotFoundException if a definition for the class
  227. * could not be found at the specified location
  228. *
  229. * @since 1.4
  230. */
  231. public static Class<?> loadClass(String codebase, String name,
  232. ClassLoader defaultLoader)
  233. throws MalformedURLException, ClassNotFoundException
  234. {
  235. return provider.loadClass(codebase, name, defaultLoader);
  236. }
  237. /**
  238. * Loads a dynamic proxy class (see {@link java.lang.reflect.Proxy})
  239. * that implements a set of interfaces with the given names
  240. * from a codebase URL path.
  241. *
  242. * <p>The interfaces will be resolved similar to classes loaded via
  243. * the {@link #loadClass(String,String)} method using the given
  244. * <code>codebase</code>.
  245. *
  246. * <p>This method delegates to the
  247. * {@link RMIClassLoaderSpi#loadProxyClass(String,String[],ClassLoader)}
  248. * method of the provider instance, passing <code>codebase</code>
  249. * as the first argument, <code>interfaces</code> as the second argument,
  250. * and <code>defaultLoader</code> as the third argument.
  251. *
  252. * @param codebase the list of URLs (space-separated) to load
  253. * classes from, or <code>null</code>
  254. *
  255. * @param interfaces the names of the interfaces for the proxy class
  256. * to implement
  257. *
  258. * @param defaultLoader additional contextual class loader
  259. * to use, or <code>null</code>
  260. *
  261. * @return a dynamic proxy class that implements the named interfaces
  262. *
  263. * @throws MalformedURLException if <code>codebase</code> is
  264. * non-<code>null</code> and contains an invalid URL, or
  265. * if <code>codebase</code> is <code>null</code> and a provider-specific
  266. * URL used to load classes is invalid
  267. *
  268. * @throws ClassNotFoundException if a definition for one of
  269. * the named interfaces could not be found at the specified location,
  270. * or if creation of the dynamic proxy class failed (such as if
  271. * {@link java.lang.reflect.Proxy#getProxyClass(ClassLoader,Class[])}
  272. * would throw an <code>IllegalArgumentException</code> for the given
  273. * interface list)
  274. *
  275. * @since 1.4
  276. */
  277. public static Class<?> loadProxyClass(String codebase, String[] interfaces,
  278. ClassLoader defaultLoader)
  279. throws ClassNotFoundException, MalformedURLException
  280. {
  281. return provider.loadProxyClass(codebase, interfaces, defaultLoader);
  282. }
  283. /**
  284. * Returns a class loader that loads classes from the given codebase
  285. * URL path.
  286. *
  287. * <p>The class loader returned is the class loader that the
  288. * {@link #loadClass(String,String)} method would use to load classes
  289. * for the same <code>codebase</code> argument.
  290. *
  291. * <p>This method delegates to the
  292. * {@link RMIClassLoaderSpi#getClassLoader(String)} method
  293. * of the provider instance, passing <code>codebase</code> as the argument.
  294. *
  295. * <p>If there is a security manger, its <code>checkPermission</code>
  296. * method will be invoked with a
  297. * <code>RuntimePermission("getClassLoader")</code> permission;
  298. * this could result in a <code>SecurityException</code>.
  299. * The provider implementation of this method may also perform further
  300. * security checks to verify that the calling context has permission to
  301. * connect to all of the URLs in the codebase URL path.
  302. *
  303. * @param codebase the list of URLs (space-separated) from which
  304. * the returned class loader will load classes from, or <code>null</code>
  305. *
  306. * @return a class loader that loads classes from the given codebase URL
  307. * path
  308. *
  309. * @throws MalformedURLException if <code>codebase</code> is
  310. * non-<code>null</code> and contains an invalid URL, or
  311. * if <code>codebase</code> is <code>null</code> and a provider-specific
  312. * URL used to identify the class loader is invalid
  313. *
  314. * @throws SecurityException if there is a security manager and the
  315. * invocation of its <code>checkPermission</code> method fails, or
  316. * if the caller does not have permission to connect to all of the
  317. * URLs in the codebase URL path
  318. *
  319. * @since 1.3
  320. */
  321. public static ClassLoader getClassLoader(String codebase)
  322. throws MalformedURLException, SecurityException
  323. {
  324. return provider.getClassLoader(codebase);
  325. }
  326. /**
  327. * Returns the annotation string (representing a location for
  328. * the class definition) that RMI will use to annotate the class
  329. * descriptor when marshalling objects of the given class.
  330. *
  331. * <p>This method delegates to the
  332. * {@link RMIClassLoaderSpi#getClassAnnotation(Class)} method
  333. * of the provider instance, passing <code>cl</code> as the argument.
  334. *
  335. * @param cl the class to obtain the annotation for
  336. *
  337. * @return a string to be used to annotate the given class when
  338. * it gets marshalled, or <code>null</code>
  339. *
  340. * @throws NullPointerException if <code>cl</code> is <code>null</code>
  341. *
  342. * @since 1.2
  343. */
  344. /*
  345. * REMIND: Should we say that the returned class annotation will or
  346. * should be a (space-separated) list of URLs?
  347. */
  348. public static String getClassAnnotation(Class<?> cl) {
  349. return provider.getClassAnnotation(cl);
  350. }
  351. /**
  352. * Returns the canonical instance of the default provider
  353. * for the service provider interface {@link RMIClassLoaderSpi}.
  354. * If the system property <code>java.rmi.server.RMIClassLoaderSpi</code>
  355. * is not defined, then the <code>RMIClassLoader</code> static
  356. * methods
  357. *
  358. * <ul>
  359. *
  360. * <li>{@link #loadClass(URL,String)}
  361. * <li>{@link #loadClass(String,String)}
  362. * <li>{@link #loadClass(String,String,ClassLoader)}
  363. * <li>{@link #loadProxyClass(String,String[],ClassLoader)}
  364. * <li>{@link #getClassLoader(String)}
  365. * <li>{@link #getClassAnnotation(Class)}
  366. *
  367. * </ul>
  368. *
  369. * will use the canonical instance of the default provider
  370. * as the service provider instance.
  371. *
  372. * <p>If there is a security manager, its
  373. * <code>checkPermission</code> method will be invoked with a
  374. * <code>RuntimePermission("setFactory")</code> permission; this
  375. * could result in a <code>SecurityException</code>.
  376. *
  377. * <p>The default service provider instance implements
  378. * {@link RMIClassLoaderSpi} as follows:
  379. *
  380. * <blockquote>
  381. *
  382. * <p>The <b>{@link RMIClassLoaderSpi#getClassAnnotation(Class)
  383. * getClassAnnotation}</b> method returns a <code>String</code>
  384. * representing the codebase URL path that a remote party should
  385. * use to download the definition for the specified class. The
  386. * format of the returned string is a path of URLs separated by
  387. * spaces.
  388. *
  389. * The codebase string returned depends on the defining class
  390. * loader of the specified class:
  391. *
  392. * <ul>
  393. *
  394. * <p><li>If the class loader is the system class loader (see
  395. * {@link ClassLoader#getSystemClassLoader}), a parent of the
  396. * system class loader such as the loader used for installed
  397. * extensions, or the bootstrap class loader (which may be
  398. * represented by <code>null</code>), then the value of the
  399. * <code>java.rmi.server.codebase</code> property (or possibly an
  400. * earlier cached value) is returned, or
  401. * <code>null</code> is returned if that property is not set.
  402. *
  403. * <p><li>Otherwise, if the class loader is an instance of
  404. * <code>URLClassLoader</code>, then the returned string is a
  405. * space-separated list of the external forms of the URLs returned
  406. * by invoking the <code>getURLs</code> methods of the loader. If
  407. * the <code>URLClassLoader</code> was created by this provider to
  408. * service an invocation of its <code>loadClass</code> or
  409. * <code>loadProxyClass</code> methods, then no permissions are
  410. * required to get the associated codebase string. If it is an
  411. * arbitrary other <code>URLClassLoader</code> instance, then if
  412. * there is a security manager, its <code>checkPermission</code>
  413. * method will be invoked once for each URL returned by the
  414. * <code>getURLs</code> method, with the permission returned by
  415. * invoking <code>openConnection().getPermission()</code> on each
  416. * URL; if any of those invocations throws a
  417. * <code>SecurityException</code> or an <code>IOException</code>,
  418. * then the value of the <code>java.rmi.server.codebase</code>
  419. * property (or possibly an earlier cached value) is returned, or
  420. * <code>null</code> is returned if that property is not set.
  421. *
  422. * <p><li>Finally, if the class loader is not an instance of
  423. * <code>URLClassLoader</code>, then the value of the
  424. * <code>java.rmi.server.codebase</code> property (or possibly an
  425. * earlier cached value) is returned, or
  426. * <code>null</code> is returned if that property is not set.
  427. *
  428. * </ul>
  429. *
  430. * <p>For the implementations of the methods described below,
  431. * which all take a <code>String</code> parameter named
  432. * <code>codebase</code> that is a space-separated list of URLs,
  433. * each invocation has an associated <i>codebase loader</i> that
  434. * is identified using the <code>codebase</code> argument in
  435. * conjunction with the current thread's context class loader (see
  436. * {@link Thread#getContextClassLoader()}). When there is a
  437. * security manager, this provider maintains an internal table of
  438. * class loader instances (which are at least instances of {@link
  439. * java.net.URLClassLoader}) keyed by the pair of their parent
  440. * class loader and their codebase URL path (an ordered list of
  441. * URLs). If the <code>codebase</code> argument is <code>null</code>,
  442. * the codebase URL path is the value of the system property
  443. * <code>java.rmi.server.codebase</code> or possibly an
  444. * earlier cached value. For a given codebase URL path passed as the
  445. * <code>codebase</code> argument to an invocation of one of the
  446. * below methods in a given context, the codebase loader is the
  447. * loader in the table with the specified codebase URL path and
  448. * the current thread's context class loader as its parent. If no
  449. * such loader exists, then one is created and added to the table.
  450. * The table does not maintain strong references to its contained
  451. * loaders, in order to allow them and their defined classes to be
  452. * garbage collected when not otherwise reachable. In order to
  453. * prevent arbitrary untrusted code from being implicitly loaded
  454. * into a virtual machine with no security manager, if there is no
  455. * security manager set, the codebase loader is just the current
  456. * thread's context class loader (the supplied codebase URL path
  457. * is ignored, so remote class loading is disabled).
  458. *
  459. * <p>The <b>{@link RMIClassLoaderSpi#getClassLoader(String)
  460. * getClassLoader}</b> method returns the codebase loader for the
  461. * specified codebase URL path. If there is a security manager,
  462. * then if the calling context does not have permission to connect
  463. * to all of the URLs in the codebase URL path, a
  464. * <code>SecurityException</code> will be thrown.
  465. *
  466. * <p>The <b>{@link
  467. * RMIClassLoaderSpi#loadClass(String,String,ClassLoader)
  468. * loadClass}</b> method attempts to load the class with the
  469. * specified name as follows:
  470. *
  471. * <blockquote>
  472. *
  473. * If the <code>defaultLoader</code> argument is
  474. * non-<code>null</code>, it first attempts to load the class with the
  475. * specified <code>name</code> using the
  476. * <code>defaultLoader</code>, such as by evaluating
  477. *
  478. * <pre>
  479. * Class.forName(name, false, defaultLoader)
  480. * </pre>
  481. *
  482. * If the class is successfully loaded from the
  483. * <code>defaultLoader</code>, that class is returned. If an
  484. * exception other than <code>ClassNotFoundException</code> is
  485. * thrown, that exception is thrown to the caller.
  486. *
  487. * <p>Next, the <code>loadClass</code> method attempts to load the
  488. * class with the specified <code>name</code> using the codebase
  489. * loader for the specified codebase URL path.
  490. * If there is a security manager, then the calling context
  491. * must have permission to connect to all of the URLs in the
  492. * codebase URL path; otherwise, the current thread's context
  493. * class loader will be used instead of the codebase loader.
  494. *
  495. * </blockquote>
  496. *
  497. * <p>The <b>{@link
  498. * RMIClassLoaderSpi#loadProxyClass(String,String[],ClassLoader)
  499. * loadProxyClass}</b> method attempts to return a dynamic proxy
  500. * class with the named interface as follows:
  501. *
  502. * <blockquote>
  503. *
  504. * <p>If the <code>defaultLoader</code> argument is
  505. * non-<code>null</code> and all of the named interfaces can be
  506. * resolved through that loader, then,
  507. *
  508. * <ul>
  509. *
  510. * <li>if all of the resolved interfaces are <code>public</code>,
  511. * then it first attempts to obtain a dynamic proxy class (using
  512. * {@link
  513. * java.lang.reflect.Proxy#getProxyClass(ClassLoader,Class[])
  514. * Proxy.getProxyClass}) for the resolved interfaces defined in
  515. * the codebase loader; if that attempt throws an
  516. * <code>IllegalArgumentException</code>, it then attempts to
  517. * obtain a dynamic proxy class for the resolved interfaces
  518. * defined in the <code>defaultLoader</code>. If both attempts
  519. * throw <code>IllegalArgumentException</code>, then this method
  520. * throws a <code>ClassNotFoundException</code>. If any other
  521. * exception is thrown, that exception is thrown to the caller.
  522. *
  523. * <li>if all of the non-<code>public</code> resolved interfaces
  524. * are defined in the same class loader, then it attempts to
  525. * obtain a dynamic proxy class for the resolved interfaces
  526. * defined in that loader.
  527. *
  528. * <li>otherwise, a <code>LinkageError</code> is thrown (because a
  529. * class that implements all of the specified interfaces cannot be
  530. * defined in any loader).
  531. *
  532. * </ul>
  533. *
  534. * <p>Otherwise, if all of the named interfaces can be resolved
  535. * through the codebase loader, then,
  536. *
  537. * <ul>
  538. *
  539. * <li>if all of the resolved interfaces are <code>public</code>,
  540. * then it attempts to obtain a dynamic proxy class for the
  541. * resolved interfaces in the codebase loader. If the attempt
  542. * throws an <code>IllegalArgumentException</code>, then this
  543. * method throws a <code>ClassNotFoundException</code>.
  544. *
  545. * <li>if all of the non-<code>public</code> resolved interfaces
  546. * are defined in the same class loader, then it attempts to
  547. * obtain a dynamic proxy class for the resolved interfaces
  548. * defined in that loader.
  549. *
  550. * <li>otherwise, a <code>LinkageError</code> is thrown (because a
  551. * class that implements all of the specified interfaces cannot be
  552. * defined in any loader).
  553. *
  554. * </ul>
  555. *
  556. * <p>Otherwise, a <code>ClassNotFoundException</code> is thrown
  557. * for one of the named interfaces that could not be resolved.
  558. *
  559. * </blockquote>
  560. *
  561. * </blockquote>
  562. *
  563. * @return the canonical instance of the default service provider
  564. *
  565. * @throws SecurityException if there is a security manager and the
  566. * invocation of its <code>checkPermission</code> method fails
  567. *
  568. * @since 1.4
  569. */
  570. public static RMIClassLoaderSpi getDefaultProviderInstance() {
  571. SecurityManager sm = System.getSecurityManager();
  572. if (sm != null) {
  573. sm.checkPermission(new RuntimePermission("setFactory"));
  574. }
  575. return defaultProvider;
  576. }
  577. /**
  578. * Returns the security context of the given class loader.
  579. *
  580. * @param loader a class loader from which to get the security context
  581. *
  582. * @return the security context
  583. *
  584. * @deprecated no replacement. As of the Java 2 platform v1.2, RMI no
  585. * longer uses this method to obtain a class loader's security context.
  586. * @see java.lang.SecurityManager#getSecurityContext()
  587. */
  588. @Deprecated
  589. public static Object getSecurityContext(ClassLoader loader)
  590. {
  591. return sun.rmi.server.LoaderHandler.getSecurityContext(loader);
  592. }
  593. /**
  594. * Creates an instance of the default provider class.
  595. */
  596. private static RMIClassLoaderSpi newDefaultProviderInstance() {
  597. return new RMIClassLoaderSpi() {
  598. public Class loadClass(String codebase, String name,
  599. ClassLoader defaultLoader)
  600. throws MalformedURLException, ClassNotFoundException
  601. {
  602. return sun.rmi.server.LoaderHandler.loadClass(
  603. codebase, name, defaultLoader);
  604. }
  605. public Class loadProxyClass(String codebase, String[] interfaces,
  606. ClassLoader defaultLoader)
  607. throws MalformedURLException, ClassNotFoundException
  608. {
  609. return sun.rmi.server.LoaderHandler.loadProxyClass(
  610. codebase, interfaces, defaultLoader);
  611. }
  612. public ClassLoader getClassLoader(String codebase)
  613. throws MalformedURLException
  614. {
  615. return sun.rmi.server.LoaderHandler.getClassLoader(codebase);
  616. }
  617. public String getClassAnnotation(Class<?> cl) {
  618. return sun.rmi.server.LoaderHandler.getClassAnnotation(cl);
  619. }
  620. };
  621. }
  622. /**
  623. * Chooses provider instance, following above documentation.
  624. *
  625. * This method assumes that it has been invoked in a privileged block.
  626. */
  627. private static RMIClassLoaderSpi initializeProvider() {
  628. /*
  629. * First check for the system property being set:
  630. */
  631. String providerClassName =
  632. System.getProperty("java.rmi.server.RMIClassLoaderSpi");
  633. if (providerClassName != null) {
  634. if (providerClassName.equals("default")) {
  635. return defaultProvider;
  636. }
  637. try {
  638. Class providerClass =
  639. Class.forName(providerClassName, false,
  640. ClassLoader.getSystemClassLoader());
  641. return (RMIClassLoaderSpi) providerClass.newInstance();
  642. } catch (ClassNotFoundException e) {
  643. throw new NoClassDefFoundError(e.getMessage());
  644. } catch (IllegalAccessException e) {
  645. throw new IllegalAccessError(e.getMessage());
  646. } catch (InstantiationException e) {
  647. throw new InstantiationError(e.getMessage());
  648. } catch (ClassCastException e) {
  649. Error error = new LinkageError(
  650. "provider class not assignable to RMIClassLoaderSpi");
  651. error.initCause(e);
  652. throw error;
  653. }
  654. }
  655. /*
  656. * Next look for a provider configuration file intalled:
  657. */
  658. Iterator iter = Service.providers(RMIClassLoaderSpi.class,
  659. ClassLoader.getSystemClassLoader());
  660. if (iter.hasNext()) {
  661. try {
  662. return (RMIClassLoaderSpi) iter.next();
  663. } catch (ClassCastException e) {
  664. Error error = new LinkageError(
  665. "provider class not assignable to RMIClassLoaderSpi");
  666. error.initCause(e);
  667. throw error;
  668. }
  669. }
  670. /*
  671. * Finally, return the canonical instance of the default provider.
  672. */
  673. return defaultProvider;
  674. }
  675. }