1. /*
  2. * @(#)UnicastRemoteObject.java 1.30 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.rmi.*;
  9. /**
  10. * The UnicastRemoteObject class defines a non-replicated remote
  11. * object whose references are valid only while the server process is
  12. * alive. The UnicastRemoteObject class provides support for
  13. * point-to-point active object references (invocations, parameters,
  14. * and results) using TCP streams.
  15. *
  16. * <p>Objects that require remote behavior should extend RemoteObject,
  17. * typically via UnicastRemoteObject. If UnicastRemoteObject is not
  18. * extended, the implementation class must then assume the
  19. * responsibility for the correct semantics of the hashCode, equals,
  20. * and toString methods inherited from the Object class, so that they
  21. * behave appropriately for remote objects.
  22. *
  23. * @version 1.30, 01/23/03
  24. * @author Ann Wollrath
  25. * @author Peter Jones
  26. * @since JDK1.1
  27. * @see RemoteServer
  28. * @see RemoteObject
  29. */
  30. public class UnicastRemoteObject extends RemoteServer {
  31. /**
  32. * @serial port number on which to export object
  33. */
  34. private int port = 0;
  35. /**
  36. * @serial client-side socket factory (if any)
  37. */
  38. private RMIClientSocketFactory csf = null;
  39. /**
  40. * @serial server-side socket factory (if any) to use when
  41. * exporting object
  42. */
  43. private RMIServerSocketFactory ssf = null;
  44. /* indicate compatibility with JDK 1.1.x version of class */
  45. private static final long serialVersionUID = 4974527148936298033L;
  46. /**
  47. * Creates and exports a new UnicastRemoteObject object using an
  48. * anonymous port.
  49. * @throws RemoteException if failed to export object
  50. * @since JDK1.1
  51. */
  52. protected UnicastRemoteObject() throws RemoteException
  53. {
  54. this(0);
  55. }
  56. /**
  57. * Creates and exports a new UnicastRemoteObject object using the
  58. * particular supplied port.
  59. * @param port the port number on which the remote object receives calls
  60. * (if <code>port</code> is zero, an anonymous port is chosen)
  61. * @throws RemoteException if failed to export object
  62. * @since 1.2
  63. */
  64. protected UnicastRemoteObject(int port) throws RemoteException
  65. {
  66. this.port = port;
  67. exportObject((Remote)this, port);
  68. }
  69. /**
  70. * Creates and exports a new UnicastRemoteObject object using the
  71. * particular supplied port and socket factories.
  72. * @param port the port number on which the remote object receives calls
  73. * (if <code>port</code> is zero, an anonymous port is chosen)
  74. * @param csf the client-side socket factory for making calls to the
  75. * remote object
  76. * @param ssf the server-side socket factory for receiving remote calls
  77. * @throws RemoteException if failed to export object
  78. * @since 1.2
  79. */
  80. protected UnicastRemoteObject(int port,
  81. RMIClientSocketFactory csf,
  82. RMIServerSocketFactory ssf)
  83. throws RemoteException
  84. {
  85. this.port = port;
  86. this.csf = csf;
  87. this.ssf = ssf;
  88. exportObject((Remote)this, port, csf, ssf);
  89. }
  90. /**
  91. * Re-export the remote object when it is deserialized.
  92. */
  93. private void readObject(java.io.ObjectInputStream in)
  94. throws java.io.IOException, java.lang.ClassNotFoundException
  95. {
  96. in.defaultReadObject();
  97. reexport();
  98. }
  99. /**
  100. * Returns a clone of the remote object that is distinct from
  101. * the original.
  102. *
  103. * @exception CloneNotSupportedException if clone failed due to
  104. * a RemoteException.
  105. * @return the new remote object
  106. * @since JDK1.1
  107. */
  108. public Object clone() throws CloneNotSupportedException
  109. {
  110. try {
  111. UnicastRemoteObject cloned = (UnicastRemoteObject)super.clone();
  112. cloned.reexport();
  113. return cloned;
  114. } catch (RemoteException e) {
  115. throw new ServerCloneException("Clone failed", e);
  116. }
  117. }
  118. /*
  119. * Exports this UnicastRemoteObject using its initialized fields because
  120. * its creation bypassed running its constructors (via deserialization
  121. * or cloning, for example).
  122. */
  123. private void reexport() throws RemoteException
  124. {
  125. if (csf == null && ssf == null) {
  126. exportObject((Remote)this, port);
  127. } else {
  128. exportObject((Remote)this, port, csf, ssf);
  129. }
  130. }
  131. /**
  132. * Exports the remote object to make it available to receive incoming
  133. * calls using an anonymous port.
  134. * @param obj the remote object to be exported
  135. * @return remote object stub
  136. * @exception RemoteException if export fails
  137. * @since JDK1.1
  138. */
  139. public static RemoteStub exportObject(Remote obj)
  140. throws RemoteException
  141. {
  142. return (RemoteStub)exportObject(obj, 0);
  143. }
  144. /* parameter types for server ref constructor invocation used below */
  145. private static Class[] portParamTypes = {
  146. int.class
  147. };
  148. /**
  149. * Exports the remote object to make it available to receive incoming
  150. * calls, using the particular supplied port.
  151. * @param obj the remote object to be exported
  152. * @param port the port to export the object on
  153. * @return remote object stub
  154. * @exception RemoteException if export fails
  155. * @since 1.2
  156. */
  157. public static Remote exportObject(Remote obj, int port)
  158. throws RemoteException
  159. {
  160. // prepare arguments for server ref constructor
  161. Object[] args = new Object[] { new Integer(port) };
  162. return exportObject(obj, "UnicastServerRef", portParamTypes, args);
  163. }
  164. /* parameter types for server ref constructor invocation used below */
  165. private static Class[] portFactoryParamTypes = {
  166. int.class, RMIClientSocketFactory.class, RMIServerSocketFactory.class
  167. };
  168. /**
  169. * Exports the remote object to make it available to receive incoming
  170. * calls, using a transport specified by the given socket factory.
  171. * @param obj the remote object to be exported
  172. * @param port the port to export the object on
  173. * @param csf the client-side socket factory for making calls to the
  174. * remote object
  175. * @param ssf the server-side socket factory for receiving remote calls
  176. * @return remote object stub
  177. * @exception RemoteException if export fails
  178. * @since 1.2
  179. */
  180. public static Remote exportObject(Remote obj, int port,
  181. RMIClientSocketFactory csf,
  182. RMIServerSocketFactory ssf)
  183. throws RemoteException
  184. {
  185. // prepare arguments for server ref constructor
  186. Object[] args = new Object[] { new Integer(port), csf, ssf };
  187. return exportObject(obj, "UnicastServerRef2", portFactoryParamTypes,
  188. args);
  189. }
  190. /**
  191. * Removes the remote object, obj, from the RMI runtime. If
  192. * successful, the object can no longer accept incoming RMI calls.
  193. * If the force parameter is true, the object is forcibly unexported
  194. * even if there are pending calls to the remote object or the
  195. * remote object still has calls in progress. If the force
  196. * parameter is false, the object is only unexported if there are
  197. * no pending or in progress calls to the object.
  198. *
  199. * @param obj the remote object to be unexported
  200. * @param force if true, unexports the object even if there are
  201. * pending or in-progress calls; if false, only unexports the object
  202. * if there are no pending or in-progress calls
  203. * @return true if operation is successful, false otherwise
  204. * @exception NoSuchObjectException if the remote object is not
  205. * currently exported
  206. * @since 1.2
  207. */
  208. public static boolean unexportObject(Remote obj, boolean force)
  209. throws java.rmi.NoSuchObjectException
  210. {
  211. return sun.rmi.transport.ObjectTable.unexportObject(obj, force);
  212. }
  213. /*
  214. * Creates an instance of given server ref type with constructor chosen
  215. * by indicated paramters and supplied with given arguements, and
  216. * export remote object with it.
  217. */
  218. private static Remote exportObject(Remote obj, String refType,
  219. Class[] params, Object[] args)
  220. throws RemoteException
  221. {
  222. // compose name of server ref class and find it
  223. String refClassName = RemoteRef.packagePrefix + "." + refType;
  224. Class refClass;
  225. try {
  226. refClass = Class.forName(refClassName);
  227. } catch (ClassNotFoundException e) {
  228. throw new ExportException(
  229. "No class found for server ref type: " + refType);
  230. }
  231. if (!ServerRef.class.isAssignableFrom(refClass)) {
  232. throw new ExportException(
  233. "Server ref class not instance of " +
  234. ServerRef.class.getName() + ": " + refClass.getName());
  235. }
  236. // create server ref instance using given constructor and arguments
  237. ServerRef serverRef;
  238. try {
  239. java.lang.reflect.Constructor cons =
  240. refClass.getConstructor(params);
  241. serverRef = (ServerRef) cons.newInstance(args);
  242. // if impl does extends UnicastRemoteObject, set its ref
  243. if (obj instanceof UnicastRemoteObject)
  244. ((UnicastRemoteObject)obj).ref = serverRef;
  245. } catch (Exception e) {
  246. throw new ExportException(
  247. "Exception creating instance of server ref class: " +
  248. refClass.getName(), e);
  249. }
  250. return serverRef.exportObject(obj, null);
  251. }
  252. }