1. /*
  2. * @(#)UnicastRemoteObject.java 1.32 03/12/19
  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.rmi.*;
  9. import sun.rmi.server.UnicastServerRef;
  10. import sun.rmi.server.UnicastServerRef2;
  11. /**
  12. * Used for exporting a remote object with JRMP and obtaining a stub
  13. * that communicates to the remote object.
  14. *
  15. * <p>For the constructors and static <code>exportObject</code> methods
  16. * below, the stub for a remote object being exported is obtained as
  17. * follows:
  18. *
  19. * <p><ul>
  20. *
  21. * <li>If the remote object is exported using the {@link
  22. * #exportObject(Remote) UnicastRemoteObject.exportObject(Remote)} method,
  23. * a stub class (typically pregenerated from the remote object's class
  24. * using the <code>rmic</code> tool) is loaded and an instance of that stub
  25. * class is constructed as follows.
  26. * <ul>
  27. *
  28. * <li>A "root class" is determined as follows: if the remote object's
  29. * class directly implements an interface that extends {@link Remote}, then
  30. * the remote object's class is the root class; otherwise, the root class is
  31. * the most derived superclass of the remote object's class that directly
  32. * implements an interface that extends <code>Remote</code>.
  33. *
  34. * <li>The name of the stub class to load is determined by concatenating
  35. * the binary name of the root class with the suffix <code>"_Stub"</code>.
  36. *
  37. * <li>The stub class is loaded by name using the class loader of the root
  38. * class. The stub class must extend {@link RemoteStub} and must have a
  39. * public constructor that has one parameter, of type {@link RemoteRef}.
  40. *
  41. * <li>Finally, an instance of the stub class is constructed with a
  42. * {@link RemoteRef}.
  43. * </ul>
  44. *
  45. * <li>If the appropriate stub class could not be found, or the stub class
  46. * could not be loaded, or a problem occurs creating the stub instance, a
  47. * {@link StubNotFoundException} is thrown.
  48. *
  49. * <p>
  50. * <li>For all other means of exporting:
  51. * <p><ul>
  52. *
  53. * <li>If the remote object's stub class (as defined above) could not be
  54. * loaded or the system property
  55. * <code>java.rmi.server.ignoreStubClasses</code> is set to
  56. * <code>"true"</code> (case insensitive), a {@link
  57. * java.lang.reflect.Proxy} instance is constructed with the following
  58. * properties:
  59. *
  60. * <ul>
  61. *
  62. * <li>The proxy's class is defined by the class loader of the remote
  63. * object's class.
  64. *
  65. * <li>The proxy implements all the remote interfaces implemented by the
  66. * remote object's class.
  67. *
  68. * <li>The proxy's invocation handler is a {@link
  69. * RemoteObjectInvocationHandler} instance constructed with a
  70. * {@link RemoteRef}.
  71. *
  72. * <li>If the proxy could not be created, a {@link StubNotFoundException}
  73. * will be thrown.
  74. * </ul>
  75. *
  76. * <p>
  77. * <li>Otherwise, an instance of the remote object's stub class (as
  78. * described above) is used as the stub.
  79. *
  80. * </ul>
  81. * </ul>
  82. *
  83. * @version 1.32, 12/19/03
  84. * @author Ann Wollrath
  85. * @author Peter Jones
  86. * @since JDK1.1
  87. **/
  88. public class UnicastRemoteObject extends RemoteServer {
  89. /**
  90. * @serial port number on which to export object
  91. */
  92. private int port = 0;
  93. /**
  94. * @serial client-side socket factory (if any)
  95. */
  96. private RMIClientSocketFactory csf = null;
  97. /**
  98. * @serial server-side socket factory (if any) to use when
  99. * exporting object
  100. */
  101. private RMIServerSocketFactory ssf = null;
  102. /* indicate compatibility with JDK 1.1.x version of class */
  103. private static final long serialVersionUID = 4974527148936298033L;
  104. /**
  105. * Creates and exports a new UnicastRemoteObject object using an
  106. * anonymous port.
  107. * @throws RemoteException if failed to export object
  108. * @since JDK1.1
  109. */
  110. protected UnicastRemoteObject() throws RemoteException
  111. {
  112. this(0);
  113. }
  114. /**
  115. * Creates and exports a new UnicastRemoteObject object using the
  116. * particular supplied port.
  117. * @param port the port number on which the remote object receives calls
  118. * (if <code>port</code> is zero, an anonymous port is chosen)
  119. * @throws RemoteException if failed to export object
  120. * @since 1.2
  121. */
  122. protected UnicastRemoteObject(int port) throws RemoteException
  123. {
  124. this.port = port;
  125. exportObject((Remote) this, port);
  126. }
  127. /**
  128. * Creates and exports a new UnicastRemoteObject object using the
  129. * particular supplied port and socket factories.
  130. * @param port the port number on which the remote object receives calls
  131. * (if <code>port</code> is zero, an anonymous port is chosen)
  132. * @param csf the client-side socket factory for making calls to the
  133. * remote object
  134. * @param ssf the server-side socket factory for receiving remote calls
  135. * @throws RemoteException if failed to export object
  136. * @since 1.2
  137. */
  138. protected UnicastRemoteObject(int port,
  139. RMIClientSocketFactory csf,
  140. RMIServerSocketFactory ssf)
  141. throws RemoteException
  142. {
  143. this.port = port;
  144. this.csf = csf;
  145. this.ssf = ssf;
  146. exportObject((Remote) this, port, csf, ssf);
  147. }
  148. /**
  149. * Re-export the remote object when it is deserialized.
  150. */
  151. private void readObject(java.io.ObjectInputStream in)
  152. throws java.io.IOException, java.lang.ClassNotFoundException
  153. {
  154. in.defaultReadObject();
  155. reexport();
  156. }
  157. /**
  158. * Returns a clone of the remote object that is distinct from
  159. * the original.
  160. *
  161. * @exception CloneNotSupportedException if clone failed due to
  162. * a RemoteException.
  163. * @return the new remote object
  164. * @since JDK1.1
  165. */
  166. public Object clone() throws CloneNotSupportedException
  167. {
  168. try {
  169. UnicastRemoteObject cloned = (UnicastRemoteObject) super.clone();
  170. cloned.reexport();
  171. return cloned;
  172. } catch (RemoteException e) {
  173. throw new ServerCloneException("Clone failed", e);
  174. }
  175. }
  176. /*
  177. * Exports this UnicastRemoteObject using its initialized fields because
  178. * its creation bypassed running its constructors (via deserialization
  179. * or cloning, for example).
  180. */
  181. private void reexport() throws RemoteException
  182. {
  183. if (csf == null && ssf == null) {
  184. exportObject((Remote) this, port);
  185. } else {
  186. exportObject((Remote) this, port, csf, ssf);
  187. }
  188. }
  189. /**
  190. * Exports the remote object to make it available to receive incoming
  191. * calls using an anonymous port.
  192. * @param obj the remote object to be exported
  193. * @return remote object stub
  194. * @exception RemoteException if export fails
  195. * @since JDK1.1
  196. */
  197. public static RemoteStub exportObject(Remote obj)
  198. throws RemoteException
  199. {
  200. /*
  201. * Use UnicastServerRef constructor passing the boolean value true
  202. * to indicate that only a generated stub class should be used. A
  203. * generated stub class must be used instead of a dynamic proxy
  204. * because the return value of this method is RemoteStub which a
  205. * dynamic proxy class cannot extend.
  206. */
  207. return (RemoteStub) exportObject(obj, new UnicastServerRef(true));
  208. }
  209. /**
  210. * Exports the remote object to make it available to receive incoming
  211. * calls, using the particular supplied port.
  212. * @param obj the remote object to be exported
  213. * @param port the port to export the object on
  214. * @return remote object stub
  215. * @exception RemoteException if export fails
  216. * @since 1.2
  217. */
  218. public static Remote exportObject(Remote obj, int port)
  219. throws RemoteException
  220. {
  221. return exportObject(obj, new UnicastServerRef(port));
  222. }
  223. /**
  224. * Exports the remote object to make it available to receive incoming
  225. * calls, using a transport specified by the given socket factory.
  226. * @param obj the remote object to be exported
  227. * @param port the port to export the object on
  228. * @param csf the client-side socket factory for making calls to the
  229. * remote object
  230. * @param ssf the server-side socket factory for receiving remote calls
  231. * @return remote object stub
  232. * @exception RemoteException if export fails
  233. * @since 1.2
  234. */
  235. public static Remote exportObject(Remote obj, int port,
  236. RMIClientSocketFactory csf,
  237. RMIServerSocketFactory ssf)
  238. throws RemoteException
  239. {
  240. return exportObject(obj, new UnicastServerRef2(port, csf, ssf));
  241. }
  242. /**
  243. * Removes the remote object, obj, from the RMI runtime. If
  244. * successful, the object can no longer accept incoming RMI calls.
  245. * If the force parameter is true, the object is forcibly unexported
  246. * even if there are pending calls to the remote object or the
  247. * remote object still has calls in progress. If the force
  248. * parameter is false, the object is only unexported if there are
  249. * no pending or in progress calls to the object.
  250. *
  251. * @param obj the remote object to be unexported
  252. * @param force if true, unexports the object even if there are
  253. * pending or in-progress calls; if false, only unexports the object
  254. * if there are no pending or in-progress calls
  255. * @return true if operation is successful, false otherwise
  256. * @exception NoSuchObjectException if the remote object is not
  257. * currently exported
  258. * @since 1.2
  259. */
  260. public static boolean unexportObject(Remote obj, boolean force)
  261. throws java.rmi.NoSuchObjectException
  262. {
  263. return sun.rmi.transport.ObjectTable.unexportObject(obj, force);
  264. }
  265. /**
  266. * Exports the specified object using the specified server ref.
  267. */
  268. private static Remote exportObject(Remote obj, UnicastServerRef sref)
  269. throws RemoteException
  270. {
  271. // if obj extends UnicastRemoteObject, set its ref.
  272. if (obj instanceof UnicastRemoteObject) {
  273. ((UnicastRemoteObject) obj).ref = sref;
  274. }
  275. return sref.exportObject(obj, null, false);
  276. }
  277. }