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