1. /*
  2. * @(#)Activatable.java 1.34 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.activation;
  8. import java.lang.reflect.Constructor;
  9. import java.rmi.activation.UnknownGroupException;
  10. import java.rmi.activation.UnknownObjectException;
  11. import java.rmi.Remote;
  12. import java.rmi.RemoteException;
  13. import java.rmi.MarshalledObject;
  14. import java.rmi.NoSuchObjectException;
  15. import java.rmi.server.*;
  16. import sun.rmi.server.ActivatableServerRef;
  17. /**
  18. * The <code>Activatable</code> class provides support for remote
  19. * objects that require persistent access over time and that
  20. * can be activated by the system.
  21. *
  22. * <p>For the constructors and static <code>exportObject</code> methods,
  23. * the stub for a remote object being exported is obtained as described in
  24. * {@link java.rmi.server.UnicastRemoteObject}.
  25. *
  26. * @author Ann Wollrath
  27. * @version 1.34, 03/12/19
  28. * @since 1.2
  29. */
  30. public abstract class Activatable extends RemoteServer {
  31. /**
  32. * @serial Activation Identifier for this object.
  33. */
  34. private ActivationID id;
  35. /** indicate compatibility with the Java 2 SDK v1.2 version of class */
  36. private static final long serialVersionUID = -3120617863591563455L;
  37. /**
  38. * Constructor used to register and export the object on a
  39. * specified port (an anonymous port is chosen if port=0) .
  40. *
  41. * A concrete subclass of this class must call this constructor to
  42. * register and export the object during <i>initial</i> construction. As
  43. * a side-effect of activatable object construction, the remote
  44. * object is both "registered" with the activation system and
  45. * "exported" (on an anonymous port if port=0) to the RMI runtime
  46. * so that it is available to accept incoming calls from clients.
  47. *
  48. * @param location the location for classes for this object
  49. * @param data the object's initialization data
  50. * @param port the port on which the object is exported (an anonymous
  51. * port is used if port=0)
  52. * @param restart if true, the object is restarted (reactivated) when
  53. * either the activator is restarted or the object's activation group
  54. * is restarted after an unexpected crash; if false, the object is only
  55. * activated on demand. Specifying <code>restart</code> to be
  56. * <code>true</code> does not force an initial immediate activation of
  57. * a newly registered object; initial activation is lazy.
  58. * @exception ActivationException if object registration fails.
  59. * @exception RemoteException if either of the following fails:
  60. * a) registering the object with the activation system or b) exporting
  61. * the object to the RMI runtime.
  62. * @since 1.2
  63. */
  64. protected Activatable(String location,
  65. MarshalledObject data,
  66. boolean restart,
  67. int port)
  68. throws ActivationException, RemoteException
  69. {
  70. super();
  71. id = exportObject(this, location, data, restart, port);
  72. }
  73. /**
  74. * Constructor used to register and export the object on a
  75. * specified port (an anonymous port is chosen if port=0) . <p>
  76. *
  77. * A concrete subclass of this class must call this constructor to
  78. * register and export the object during <i>initial</i> construction. As
  79. * a side-effect of activatable object construction, the remote
  80. * object is both "registered" with the activation system and
  81. * "exported" (on an anonymous port if port=0) to the RMI runtime
  82. * so that it is available to accept incoming calls from clients.
  83. *
  84. * @param location the location for classes for this object
  85. * @param data the object's initialization data
  86. * @param restart if true, the object is restarted (reactivated) when
  87. * either the activator is restarted or the object's activation group
  88. * is restarted after an unexpected crash; if false, the object is only
  89. * activated on demand. Specifying <code>restart</code> to be
  90. * <code>true</code> does not force an initial immediate activation of
  91. * a newly registered object; initial activation is lazy.
  92. * @param port the port on which the object is exported (an anonymous
  93. * port is used if port=0)
  94. * @param csf the client-side socket factory for making calls to the
  95. * remote object
  96. * @param ssf the server-side socket factory for receiving remote calls
  97. * @exception ActivationException if object registration fails.
  98. * @exception RemoteException if either of the following fails:
  99. * a) registering the object with the activation system or b) exporting
  100. * the object to the RMI runtime.
  101. * @since 1.2
  102. */
  103. protected Activatable(String location,
  104. MarshalledObject data,
  105. boolean restart,
  106. int port,
  107. RMIClientSocketFactory csf,
  108. RMIServerSocketFactory ssf)
  109. throws ActivationException, RemoteException
  110. {
  111. super();
  112. id = exportObject(this, location, data, restart, port, csf, ssf);
  113. }
  114. /**
  115. * Constructor used to activate/export the object on a specified
  116. * port. An "activatable" remote object must have a constructor that
  117. * takes two arguments: <ul>
  118. * <li>the object's activation identifier (<code>ActivationID</code>), and
  119. * <li>the object's initialization data (a <code>MarshalledObject</code>).
  120. * </ul><p>
  121. *
  122. * A concrete subclass of this class must call this constructor when it is
  123. * <i>activated</i> via the two parameter constructor described above. As
  124. * a side-effect of construction, the remote object is "exported"
  125. * to the RMI runtime (on the specified <code>port</code>) and is
  126. * available to accept incoming calls from clients.
  127. *
  128. * @param id activation identifier for the object
  129. * @param port the port number on which the object is exported
  130. * @exception RemoteException if exporting the object to the RMI
  131. * runtime fails
  132. * @since 1.2
  133. */
  134. protected Activatable(ActivationID id, int port)
  135. throws RemoteException
  136. {
  137. super();
  138. this.id = id;
  139. exportObject(this, id, port);
  140. }
  141. /**
  142. * Constructor used to activate/export the object on a specified
  143. * port. An "activatable" remote object must have a constructor that
  144. * takes two arguments: <ul>
  145. * <li>the object's activation identifier (<code>ActivationID</code>), and
  146. * <li>the object's initialization data (a <code>MarshalledObject</code>).
  147. * </ul><p>
  148. *
  149. * A concrete subclass of this class must call this constructor when it is
  150. * <i>activated</i> via the two parameter constructor described above. As
  151. * a side-effect of construction, the remote object is "exported"
  152. * to the RMI runtime (on the specified <code>port</code>) and is
  153. * available to accept incoming calls from clients.
  154. *
  155. * @param id activation identifier for the object
  156. * @param port the port number on which the object is exported
  157. * @param csf the client-side socket factory for making calls to the
  158. * remote object
  159. * @param ssf the server-side socket factory for receiving remote calls
  160. * @exception RemoteException if exporting the object to the RMI
  161. * runtime fails
  162. * @since 1.2
  163. */
  164. protected Activatable(ActivationID id, int port,
  165. RMIClientSocketFactory csf,
  166. RMIServerSocketFactory ssf)
  167. throws RemoteException
  168. {
  169. super();
  170. this.id = id;
  171. exportObject(this, id, port, csf, ssf);
  172. }
  173. /**
  174. * Returns the object's activation identifier. The method is
  175. * protected so that only subclasses can obtain an object's
  176. * identifier.
  177. * @return the object's activation identifier
  178. * @since 1.2
  179. */
  180. protected ActivationID getID() {
  181. return id;
  182. }
  183. /**
  184. * Register an object descriptor for an activatable remote
  185. * object so that is can be activated on demand.
  186. *
  187. * @param desc the object's descriptor
  188. * @return the stub for the activatable remote object
  189. * @exception UnknownGroupException if group id in <code>desc</code>
  190. * is not registered with the activation system
  191. * @exception ActivationException if activation system is not running
  192. * @exception RemoteException if remote call fails
  193. * @since 1.2
  194. */
  195. public static Remote register(ActivationDesc desc)
  196. throws UnknownGroupException, ActivationException, RemoteException
  197. {
  198. // register object with activator.
  199. ActivationID id =
  200. ActivationGroup.getSystem().registerObject(desc);
  201. return sun.rmi.server.ActivatableRef.getStub(desc, id);
  202. }
  203. /**
  204. * Informs the system that the object with the corresponding activation
  205. * <code>id</code> is currently inactive. If the object is currently
  206. * active, the object is "unexported" from the RMI runtime (only if
  207. * there are no pending or in-progress calls)
  208. * so the that it can no longer receive incoming calls. This call
  209. * informs this VM's ActivationGroup that the object is inactive,
  210. * that, in turn, informs its ActivationMonitor. If this call
  211. * completes successfully, a subsequent activate request to the activator
  212. * will cause the object to reactivate. The operation may still
  213. * succeed if the object is considered active but has already
  214. * unexported itself.
  215. *
  216. * @param id the object's activation identifier
  217. * @return true if the operation succeeds (the operation will
  218. * succeed if the object in currently known to be active and is
  219. * either already unexported or is currently exported and has no
  220. * pending/executing calls); false is returned if the object has
  221. * pending/executing calls in which case it cannot be deactivated
  222. * @exception UnknownObjectException if object is not known (it may
  223. * already be inactive)
  224. * @exception ActivationException if group is not active
  225. * @exception RemoteException if call informing monitor fails
  226. * @since 1.2
  227. */
  228. public static boolean inactive(ActivationID id)
  229. throws UnknownObjectException, ActivationException, RemoteException
  230. {
  231. return ActivationGroup.currentGroup().inactiveObject(id);
  232. }
  233. /**
  234. * Revokes previous registration for the activation descriptor
  235. * associated with <code>id</code>. An object can no longer be
  236. * activated via that <code>id</code>.
  237. *
  238. * @param id the object's activation identifier
  239. * @exception UnknownObjectException if object (<code>id</code>) is unknown
  240. * @exception ActivationException if activation system is not running
  241. * @exception RemoteException if remote call to activation system fails
  242. * @since 1.2
  243. */
  244. public static void unregister(ActivationID id)
  245. throws UnknownObjectException, ActivationException, RemoteException
  246. {
  247. ActivationGroup.getSystem().unregisterObject(id);
  248. }
  249. /**
  250. * This <code>exportObject</code> method may be invoked explicitly
  251. * by an "activatable" object, that does not extend the
  252. * <code>Activatable</code> class, in order to both a) register
  253. * the object's activation descriptor, constructed from the supplied
  254. * <code>location</code>, and <code>data</code>, with
  255. * the activation system (so the object can be activated), and
  256. * b) export the remote object, <code>obj</code>, on a specific
  257. * port (if port=0, then an anonymous port is chosen). Once the
  258. * object is exported, it can receive incoming RMI calls.<p>
  259. *
  260. * This method does not need to be called if <code>obj</code>
  261. * extends <code>Activatable</code>, since the first constructor
  262. * calls this method.
  263. *
  264. * @param obj the object being exported
  265. * @param location the object's code location
  266. * @param data the object's bootstrapping data
  267. * @param restart if true, the object is restarted (reactivated) when
  268. * either the activator is restarted or the object's activation group
  269. * is restarted after an unexpected crash; if false, the object is only
  270. * activated on demand. Specifying <code>restart</code> to be
  271. * <code>true</code> does not force an initial immediate activation of
  272. * a newly registered object; initial activation is lazy.
  273. * @param port the port on which the object is exported (an anonymous
  274. * port is used if port=0)
  275. * @return the activation identifier obtained from registering the
  276. * descriptor, <code>desc</code>, with the activation system
  277. * the wrong group
  278. * @exception ActivationException if activation group is not active
  279. * @exception RemoteException if object registration or export fails
  280. * @since 1.2
  281. */
  282. public static ActivationID exportObject(Remote obj,
  283. String location,
  284. MarshalledObject data,
  285. boolean restart,
  286. int port)
  287. throws ActivationException, RemoteException
  288. {
  289. ActivationDesc desc = new ActivationDesc(obj.getClass().getName(),
  290. location, data, restart);
  291. ActivationID id = ActivationGroup.getSystem().registerObject(desc);
  292. Remote stub = exportObject(obj, id, port);
  293. ActivationGroup.currentGroup().activeObject(id, obj);
  294. return id;
  295. }
  296. /**
  297. * This <code>exportObject</code> method may be invoked explicitly
  298. * by an "activatable" object, that does not extend the
  299. * <code>Activatable</code> class, in order to both a) register
  300. * the object's activation descriptor, constructed from the supplied
  301. * <code>location</code>, and <code>data</code>, with
  302. * the activation system (so the object can be activated), and
  303. * b) export the remote object, <code>obj</code>, on a specific
  304. * port (if port=0, then an anonymous port is chosen). Once the
  305. * object is exported, it can receive incoming RMI calls.<p>
  306. *
  307. * This method does not need to be called if <code>obj</code>
  308. * extends <code>Activatable</code>, since the first constructor
  309. * calls this method.
  310. *
  311. * @param obj the object being exported
  312. * @param location the object's code location
  313. * @param data the object's bootstrapping data
  314. * @param restart if true, the object is restarted (reactivated) when
  315. * either the activator is restarted or the object's activation group
  316. * is restarted after an unexpected crash; if false, the object is only
  317. * activated on demand. Specifying <code>restart</code> to be
  318. * <code>true</code> does not force an initial immediate activation of
  319. * a newly registered object; initial activation is lazy.
  320. * @param port the port on which the object is exported (an anonymous
  321. * port is used if port=0)
  322. * @param csf the client-side socket factory for making calls to the
  323. * remote object
  324. * @param ssf the server-side socket factory for receiving remote calls
  325. * @return the activation identifier obtained from registering the
  326. * descriptor, <code>desc</code>, with the activation system
  327. * the wrong group
  328. * @exception ActivationException if activation group is not active
  329. * @exception RemoteException if object registration or export fails
  330. * @since 1.2
  331. */
  332. public static ActivationID exportObject(Remote obj,
  333. String location,
  334. MarshalledObject data,
  335. boolean restart,
  336. int port,
  337. RMIClientSocketFactory csf,
  338. RMIServerSocketFactory ssf)
  339. throws ActivationException, RemoteException
  340. {
  341. ActivationDesc desc = new ActivationDesc(obj.getClass().getName(),
  342. location, data, restart);
  343. ActivationID id = ActivationGroup.getSystem().registerObject(desc);
  344. Remote stub = exportObject(obj, id, port, csf, ssf);
  345. ActivationGroup.currentGroup().activeObject(id, obj);
  346. return id;
  347. }
  348. /**
  349. * Export the activatable remote object to the RMI runtime to make
  350. * the object available to receive incoming calls. The object is
  351. * exported on an anonymous port, if <code>port</code> is zero. <p>
  352. *
  353. * During activation, this <code>exportObject</code> method should
  354. * be invoked explicitly by an "activatable" object, that does not
  355. * extend the <code>Activatable</code> class. There is no need for objects
  356. * that do extend the <code>Activatable</code> class to invoke this
  357. * method directly; this method is called by the second constructor
  358. * above (which a subclass should invoke from its special activation
  359. * constructor).
  360. *
  361. * @return the stub for the activatable remote object
  362. * @param obj the remote object implementation
  363. * @param id the object's activation identifier
  364. * @param port the port on which the object is exported (an anonymous
  365. * port is used if port=0)
  366. * @exception RemoteException if object export fails
  367. * @since 1.2
  368. */
  369. public static Remote exportObject(Remote obj,
  370. ActivationID id,
  371. int port)
  372. throws RemoteException
  373. {
  374. return exportObject(obj, new ActivatableServerRef(id, port));
  375. }
  376. /**
  377. * Export the activatable remote object to the RMI runtime to make
  378. * the object available to receive incoming calls. The object is
  379. * exported on an anonymous port, if <code>port</code> is zero. <p>
  380. *
  381. * During activation, this <code>exportObject</code> method should
  382. * be invoked explicitly by an "activatable" object, that does not
  383. * extend the <code>Activatable</code> class. There is no need for objects
  384. * that do extend the <code>Activatable</code> class to invoke this
  385. * method directly; this method is called by the second constructor
  386. * above (which a subclass should invoke from its special activation
  387. * constructor).
  388. *
  389. * @return the stub for the activatable remote object
  390. * @param obj the remote object implementation
  391. * @param id the object's activation identifier
  392. * @param port the port on which the object is exported (an anonymous
  393. * port is used if port=0)
  394. * @param csf the client-side socket factory for making calls to the
  395. * remote object
  396. * @param ssf the server-side socket factory for receiving remote calls
  397. * @exception RemoteException if object export fails
  398. * @since 1.2
  399. */
  400. public static Remote exportObject(Remote obj,
  401. ActivationID id,
  402. int port,
  403. RMIClientSocketFactory csf,
  404. RMIServerSocketFactory ssf)
  405. throws RemoteException
  406. {
  407. return exportObject(obj, new ActivatableServerRef(id, port, csf, ssf));
  408. }
  409. /**
  410. * Remove the remote object, obj, from the RMI runtime. If
  411. * successful, the object can no longer accept incoming RMI calls.
  412. * If the force parameter is true, the object is forcibly unexported
  413. * even if there are pending calls to the remote object or the
  414. * remote object still has calls in progress. If the force
  415. * parameter is false, the object is only unexported if there are
  416. * no pending or in progress calls to the object.
  417. *
  418. * @param obj the remote object to be unexported
  419. * @param force if true, unexports the object even if there are
  420. * pending or in-progress calls; if false, only unexports the object
  421. * if there are no pending or in-progress calls
  422. * @return true if operation is successful, false otherwise
  423. * @exception NoSuchObjectException if the remote object is not
  424. * currently exported
  425. * @since 1.2
  426. */
  427. public static boolean unexportObject(Remote obj, boolean force)
  428. throws NoSuchObjectException
  429. {
  430. return sun.rmi.transport.ObjectTable.unexportObject(obj, force);
  431. }
  432. /**
  433. * Exports the specified object using the specified server ref.
  434. */
  435. private static Remote exportObject(Remote obj, ActivatableServerRef sref)
  436. throws RemoteException
  437. {
  438. // if obj extends Activatable, set its ref.
  439. if (obj instanceof Activatable) {
  440. ((Activatable) obj).ref = sref;
  441. }
  442. return sref.exportObject(obj, null, false);
  443. }
  444. }