1. /*
  2. * @(#)UnicastRemoteObject.java 1.22 01/11/29
  3. *
  4. * Copyright 2002 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.22, 11/29/01
  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. * Create and export a new UnicastRemoteObject object using an
  48. * anonymous port.
  49. * @since JDK1.1
  50. */
  51. protected UnicastRemoteObject() throws RemoteException
  52. {
  53. this(0);
  54. }
  55. /**
  56. * Create and export a new UnicastRemoteObject object using the
  57. * particular supplied port.
  58. * @param port the port number on which the remote object receives calls
  59. * (if <code>port</code> is zero, an anonymous port is chosen)
  60. * @since JDK1.2
  61. */
  62. protected UnicastRemoteObject(int port) throws RemoteException
  63. {
  64. this.port = port;
  65. exportObject((Remote)this, port);
  66. }
  67. /**
  68. * Create and export a new UnicastRemoteObject object using the
  69. * particular supplied port and socket factories
  70. * @param port the port number on which the remote object receives calls
  71. * (if <code>port</code> is zero, an anonymous port is chosen)
  72. * @param csf the client-side socket factory for making calls to the
  73. * remote object
  74. * @param ssf the server-side socket factory for receiving remote calls
  75. * @since JDK1.2
  76. */
  77. protected UnicastRemoteObject(int port,
  78. RMIClientSocketFactory csf,
  79. RMIServerSocketFactory ssf)
  80. throws RemoteException
  81. {
  82. this.port = port;
  83. this.csf = csf;
  84. this.ssf = ssf;
  85. exportObject((Remote)this, port, csf, ssf);
  86. }
  87. /**
  88. * Re-export the remote object when it is deserialized.
  89. */
  90. private void readObject(java.io.ObjectInputStream in)
  91. throws java.io.IOException, java.lang.ClassNotFoundException
  92. {
  93. in.defaultReadObject();
  94. reexport();
  95. }
  96. /**
  97. * Returns a clone of the remote object that is distinct from
  98. * the original.
  99. *
  100. * @exception CloneNotSupportedException if clone failed due to
  101. * a RemoteException.
  102. * @return the new remote object
  103. * @since JDK1.1
  104. */
  105. public Object clone() throws CloneNotSupportedException
  106. {
  107. try {
  108. UnicastRemoteObject cloned = (UnicastRemoteObject)super.clone();
  109. cloned.reexport();
  110. return cloned;
  111. } catch (RemoteException e) {
  112. throw new ServerCloneException("Clone failed", e);
  113. }
  114. }
  115. /*
  116. * Export this UnicastRemoteObject using its initialized fields because
  117. * its creation bypassed running its constructors (via deserialization
  118. * or cloning, for example).
  119. */
  120. private void reexport() throws RemoteException
  121. {
  122. if (csf == null && ssf == null) {
  123. exportObject((Remote)this, port);
  124. } else {
  125. exportObject((Remote)this, port, csf, ssf);
  126. }
  127. }
  128. /**
  129. * Export the remote object to make it available to receive incoming calls,
  130. * using an anonymous port.
  131. * @param obj the remote object to be exported
  132. * @exception RemoteException if export fails
  133. * @since JDK1.1
  134. */
  135. public static RemoteStub exportObject(Remote obj)
  136. throws RemoteException
  137. {
  138. return (RemoteStub)exportObject(obj, 0);
  139. }
  140. /* parameter types for server ref constructor invocation used below */
  141. private static Class[] portParamTypes = {
  142. int.class
  143. };
  144. /**
  145. * Export the remote object to make it available to receive incoming calls,
  146. * using the particular supplied port.
  147. * @param obj the remote object to be exported
  148. * @param port the port to export the object on
  149. * @exception RemoteException if export fails
  150. * @since JDK1.2
  151. */
  152. public static Remote exportObject(Remote obj, int port)
  153. throws RemoteException
  154. {
  155. // prepare arguments for server ref constructor
  156. Object[] args = new Object[] { new Integer(port) };
  157. return exportObject(obj, "UnicastServerRef", portParamTypes, args);
  158. }
  159. /* parameter types for server ref constructor invocation used below */
  160. private static Class[] portFactoryParamTypes = {
  161. int.class, RMIClientSocketFactory.class, RMIServerSocketFactory.class
  162. };
  163. /**
  164. * Export the remote object to make it available to receive incoming calls,
  165. * using a transport specified by the given socket factory.
  166. * @param obj the remote object to be exported
  167. * @param port the port to export the object on
  168. * @param csf the client-side socket factory for making calls to the
  169. * remote object
  170. * @param ssf the server-side socket factory for receiving remote calls
  171. * @exception RemoteException if export fails
  172. * @since JDK1.2
  173. */
  174. public static Remote exportObject(Remote obj, int port,
  175. RMIClientSocketFactory csf,
  176. RMIServerSocketFactory ssf)
  177. throws RemoteException
  178. {
  179. // prepare arguments for server ref constructor
  180. Object[] args = new Object[] { new Integer(port), csf, ssf };
  181. return exportObject(obj, "UnicastServerRef2", portFactoryParamTypes,
  182. args);
  183. }
  184. /**
  185. * Remove the remote object, obj, from the RMI runtime. If
  186. * successful, the object can no longer accept incoming RMI calls.
  187. * If the force parameter is true, the object is forcibly unexported
  188. * even if there are pending calls to the remote object or the
  189. * remote object still has calls in progress. If the force
  190. * parameter is false, the object is only unexported if there are
  191. * no pending or in progress calls to the object.
  192. *
  193. * @param obj the remote object to be unexported
  194. * @param force if true, unexports the object even if there are
  195. * pending or in-progress calls; if false, only unexports the object
  196. * if there are no pending or in-progress calls
  197. * @return true if operation is successful, false otherwise
  198. * @exception NoSuchObjectException if the remote object is not
  199. * currently exported
  200. * @since JDK1.2
  201. */
  202. public static boolean unexportObject(Remote obj, boolean force)
  203. throws java.rmi.NoSuchObjectException
  204. {
  205. return sun.rmi.transport.ObjectTable.unexportObject(obj, force);
  206. }
  207. /*
  208. * Create instance of given server ref type with constructor chosen
  209. * by indicated paramters and supplied with given arguements, and
  210. * export remote object with it.
  211. */
  212. private static Remote exportObject(Remote obj, String refType,
  213. Class[] params, Object[] args)
  214. throws RemoteException
  215. {
  216. // compose name of server ref class and find it
  217. String refClassName = RemoteRef.packagePrefix + "." + refType;
  218. Class refClass;
  219. try {
  220. refClass = Class.forName(refClassName);
  221. } catch (ClassNotFoundException e) {
  222. throw new ExportException(
  223. "No class found for server ref type: " + refType);
  224. }
  225. if (!ServerRef.class.isAssignableFrom(refClass)) {
  226. throw new ExportException(
  227. "Server ref class not instance of " +
  228. ServerRef.class.getName() + ": " + refClass.getName());
  229. }
  230. // create server ref instance using given constructor and arguments
  231. ServerRef serverRef;
  232. try {
  233. java.lang.reflect.Constructor cons =
  234. refClass.getConstructor(params);
  235. serverRef = (ServerRef) cons.newInstance(args);
  236. // if impl does extends UnicastRemoteObject, set its ref
  237. if (obj instanceof UnicastRemoteObject)
  238. ((UnicastRemoteObject)obj).ref = serverRef;
  239. } catch (Exception e) {
  240. throw new ExportException(
  241. "Exception creating instance of server ref class: " +
  242. refClass.getName(), e);
  243. }
  244. return serverRef.exportObject(obj, null);
  245. }
  246. }