- /*
- * @(#)Activatable.java 1.26 00/02/02
- *
- * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved.
- *
- * This software is the proprietary information of Sun Microsystems, Inc.
- * Use is subject to license terms.
- *
- */
-
- package java.rmi.activation;
-
- import java.lang.reflect.Constructor;
-
- import java.rmi.activation.UnknownGroupException;
- import java.rmi.activation.UnknownObjectException;
- import java.rmi.Remote;
- import java.rmi.RemoteException;
- import java.rmi.MarshalledObject;
-
- import java.rmi.server.*;
-
-
- /**
- * The <code>Activatable</code> class provides support for remote
- * objects that require persistent access over time and that
- * can be activated by the system.
- *
- * @author Ann Wollrath
- * @version 1.26, 02/02/00
- * @since 1.2
- */
- public abstract class Activatable extends RemoteServer {
-
- /**
- * @serial Activation Identifier for this object.
- */
- private ActivationID id;
- /** indicate compatibility with the Java 2 SDK v1.2 version of class */
- private static final long serialVersionUID = -3120617863591563455L;
-
- /* parameter types for server ref constructor invocation used below */
- private static Class[] idPortParamTypes = {
- ActivationID.class, int.class
- };
-
- /* parameter types for server ref constructor invocation used below */
- private static Class[] idPortFactoryParamTypes = {
- ActivationID.class, int.class, RMIClientSocketFactory.class,
- RMIServerSocketFactory.class
- };
-
- /**
- * Constructor used to register and export the object on a
- * specified port (an anonymous port is chosen if port=0) .
- *
- * A concrete subclass of this class must call this constructor to
- * register and export the object during <i>initial</i> construction. As
- * a side-effect of activatable object construction, the remote
- * object is both "registered" with the activation system and
- * "exported" (on an anonymous port if port=0) to the RMI runtime
- * so that it is available to accept incoming calls from clients.
- *
- * @param location the location for classes for this object
- * @param data the object's initialization data
- * @param port the port on which the object is exported (an anonymous
- * port is used if port=0)
- * @param restart if true, the object is restarted (reactivated) when
- * either the activator is restarted or the object's activation group
- * is restarted after an unexpected crash; if false, the object is only
- * activated on demand. Specifying <code>restart</code> to be
- * <code>true</code> does not force an initial immediate activation of
- * a newly registered object; initial activation is lazy.
- * @exception ActivationException if object registration fails.
- * @exception RemoteException if either of the following fails:
- * a) registering the object with the activation system or b) exporting
- * the object to the RMI runtime.
- * @since 1.2
- */
- protected Activatable(String location,
- MarshalledObject data,
- boolean restart,
- int port)
- throws ActivationException, RemoteException
- {
- super();
- id = exportObject(this, location, data, restart, port);
- }
-
- /**
- * Constructor used to register and export the object on a
- * specified port (an anonymous port is chosen if port=0) . <p>
- *
- * A concrete subclass of this class must call this constructor to
- * register and export the object during <i>initial</i> construction. As
- * a side-effect of activatable object construction, the remote
- * object is both "registered" with the activation system and
- * "exported" (on an anonymous port if port=0) to the RMI runtime
- * so that it is available to accept incoming calls from clients.
- *
- * @param location the location for classes for this object
- * @param data the object's initialization data
- * @param restart if true, the object is restarted (reactivated) when
- * either the activator is restarted or the object's activation group
- * is restarted after an unexpected crash; if false, the object is only
- * activated on demand. Specifying <code>restart</code> to be
- * <code>true</code> does not force an initial immediate activation of
- * a newly registered object; initial activation is lazy.
- * @param port the port on which the object is exported (an anonymous
- * port is used if port=0)
- * @param csf the client-side socket factory for making calls to the
- * remote object
- * @param ssf the server-side socket factory for receiving remote calls
- * @exception ActivationException if object registration fails.
- * @exception RemoteException if either of the following fails:
- * a) registering the object with the activation system or b) exporting
- * the object to the RMI runtime.
- * @since 1.2
- */
- protected Activatable(String location,
- MarshalledObject data,
- boolean restart,
- int port,
- RMIClientSocketFactory csf,
- RMIServerSocketFactory ssf)
- throws ActivationException, RemoteException
- {
- super();
- id = exportObject(this, location, data, restart, port, csf, ssf);
- }
-
- /**
- * Constructor used to activate/export the object on a specified
- * port. An "activatable" remote object must have a constructor that
- * takes two arguments: <ul>
- * <li>the object's activation identifier (<code>ActivationID</code>), and
- * <li>the object's initialization data (a <code>MarshalledObject</code>).
- * </ul><p>
- *
- * A concrete subclass of this class must call this constructor when it is
- * <i>activated</i> via the two parameter constructor described above. As
- * a side-effect of construction, the remote object is "exported"
- * to the RMI runtime (on the specified <code>port</code>) and is
- * available to accept incoming calls from clients.
- *
- * @param id activation identifier for the object
- * @param port the port number on which the object is exported
- * @exception RemoteException if exporting the object to the RMI
- * runtime fails
- * @since 1.2
- */
- protected Activatable(ActivationID id, int port)
- throws RemoteException
- {
- super();
- this.id = id;
- exportObject(this, id, port);
- }
-
- /**
- * Constructor used to activate/export the object on a specified
- * port. An "activatable" remote object must have a constructor that
- * takes two arguments: <ul>
- * <li>the object's activation identifier (<code>ActivationID</code>), and
- * <li>the object's initialization data (a <code>MarshalledObject</code>).
- * </ul><p>
- *
- * A concrete subclass of this class must call this constructor when it is
- * <i>activated</i> via the two parameter constructor described above. As
- * a side-effect of construction, the remote object is "exported"
- * to the RMI runtime (on the specified <code>port</code>) and is
- * available to accept incoming calls from clients.
- *
- * @param id activation identifier for the object
- * @param port the port number on which the object is exported
- * @param csf the client-side socket factory for making calls to the
- * remote object
- * @param ssf the server-side socket factory for receiving remote calls
- * @exception RemoteException if exporting the object to the RMI
- * runtime fails
- * @since 1.2
- */
- protected Activatable(ActivationID id, int port,
- RMIClientSocketFactory csf,
- RMIServerSocketFactory ssf)
- throws RemoteException
- {
- super();
- this.id = id;
- exportObject(this, id, port, csf, ssf);
- }
-
- /**
- * Returns the object's activation identifier. The method is
- * protected so that only subclasses can obtain an object's
- * identifier.
- * @return the object's activation identifier
- * @since 1.2
- */
- protected ActivationID getID() {
- return id;
- }
-
- /**
- * Register an object descriptor for an activatable remote
- * object so that is can be activated on demand.
- *
- * @param desc the object's descriptor
- * @return the stub for the activatable remote object
- * @exception UnknownGroupException if group id in <code>desc</code>
- * is not registered with the activation system
- * @exception ActivationException if activation system is not running
- * @exception RemoteException if remote call fails
- * @since 1.2
- */
- public static Remote register(ActivationDesc desc)
- throws UnknownGroupException, ActivationException, RemoteException
- {
- // register object with activator.
- ActivationID id =
- ActivationGroup.getSystem().registerObject(desc);
- return sun.rmi.server.ActivatableRef.getStub(desc, id);
- }
-
- /**
- * Informs the system that the object with the corresponding activation
- * <code>id</code> is currently inactive. If the object is currently
- * active, the object is "unexported" from the RMI runtime (only if
- * there are no pending or in-progress calls)
- * so the that it can no longer receive incoming calls. This call
- * informs this VM's ActivationGroup that the object is inactive,
- * that, in turn, informs its ActivationMonitor. If this call
- * completes successfully, a subsequent activate request to the activator
- * will cause the object to reactivate. The operation may still
- * succeed if the object is considered active but has already
- * unexported itself.
- *
- * @param id the object's activation identifier
- * @return true if the operation succeeds (the operation will
- * succeed if the object in currently known to be active and is
- * either already unexported or is currently exported and has no
- * pending/executing calls); false is returned if the object has
- * pending/executing calls in which case it cannot be deactivated
- * @exception UnknownObjectException if object is not known (it may
- * already be inactive)
- * @exception ActivationException if group is not active
- * @exception RemoteException if call informing monitor fails
- * @since 1.2
- */
- public static boolean inactive(ActivationID id)
- throws UnknownObjectException, ActivationException, RemoteException
- {
- return ActivationGroup.currentGroup().inactiveObject(id);
- }
-
- /**
- * Revokes previous registration for the activation descriptor
- * associated with <code>id</code>. An object can no longer be
- * activated via that <code>id</code>.
- *
- * @param id the object's activation identifier
- * @exception UnknownObjectException if object (<code>id</code>) is unknown
- * @exception ActivationException if activation system is not running
- * @exception RemoteException if remote call to activation system fails
- * @since 1.2
- */
- public static void unregister(ActivationID id)
- throws UnknownObjectException, ActivationException, RemoteException
- {
- ActivationGroup.getSystem().unregisterObject(id);
- }
-
-
- /**
- * This <code>exportObject</code> method may be invoked explicitly
- * by an "activatable" object, that does not extend the
- * <code>Activatable</code> class, in order to both a) register
- * the object's activation descriptor, constructed from the supplied
- * <code>location</code>, and <code>data</code>, with
- * the activation system (so the object can be activated), and
- * b) export the remote object, <code>obj</code>, on a specific
- * port (if port=0, then an anonymous port is chosen). Once the
- * object is exported, it can receive incoming RMI calls.<p>
- *
- * This method does not need to be called if <code>obj</code>
- * extends <code>Activatable</code>, since the first constructor
- * calls this method.
- *
- * @param obj the object being exported
- * @param location the object's code location
- * @param data the object's bootstrapping data
- * @param restart if true, the object is restarted (reactivated) when
- * either the activator is restarted or the object's activation group
- * is restarted after an unexpected crash; if false, the object is only
- * activated on demand. Specifying <code>restart</code> to be
- * <code>true</code> does not force an initial immediate activation of
- * a newly registered object; initial activation is lazy.
- * @param port the port on which the object is exported (an anonymous
- * port is used if port=0)
- * @return the activation identifier obtained from registering the
- * descriptor, <code>desc</code>, with the activation system
- * the wrong group
- * @exception ActivationException if activation group is not active
- * @exception RemoteException if object registration or export fails
- * @since 1.2
- */
- public static ActivationID exportObject(Remote obj,
- String location,
- MarshalledObject data,
- boolean restart,
- int port)
- throws ActivationException, RemoteException
- {
- ActivationDesc desc = new ActivationDesc(obj.getClass().getName(),
- location, data, restart);
- ActivationID id = ActivationGroup.getSystem().registerObject(desc);
- Remote stub = exportObject(obj, id, port);
- ActivationGroup.currentGroup().activeObject(id, obj);
- return id;
- }
-
- /**
- * This <code>exportObject</code> method may be invoked explicitly
- * by an "activatable" object, that does not extend the
- * <code>Activatable</code> class, in order to both a) register
- * the object's activation descriptor, constructed from the supplied
- * <code>location</code>, and <code>data</code>, with
- * the activation system (so the object can be activated), and
- * b) export the remote object, <code>obj</code>, on a specific
- * port (if port=0, then an anonymous port is chosen). Once the
- * object is exported, it can receive incoming RMI calls.<p>
- *
- * This method does not need to be called if <code>obj</code>
- * extends <code>Activatable</code>, since the first constructor
- * calls this method.
- *
- * @param obj the object being exported
- * @param location the object's code location
- * @param data the object's bootstrapping data
- * @param restart if true, the object is restarted (reactivated) when
- * either the activator is restarted or the object's activation group
- * is restarted after an unexpected crash; if false, the object is only
- * activated on demand. Specifying <code>restart</code> to be
- * <code>true</code> does not force an initial immediate activation of
- * a newly registered object; initial activation is lazy.
- * @param port the port on which the object is exported (an anonymous
- * port is used if port=0)
- * @param csf the client-side socket factory for making calls to the
- * remote object
- * @param ssf the server-side socket factory for receiving remote calls
- * @return the activation identifier obtained from registering the
- * descriptor, <code>desc</code>, with the activation system
- * the wrong group
- * @exception ActivationException if activation group is not active
- * @exception RemoteException if object registration or export fails
- * @since 1.2
- */
- public static ActivationID exportObject(Remote obj,
- String location,
- MarshalledObject data,
- boolean restart,
- int port,
- RMIClientSocketFactory csf,
- RMIServerSocketFactory ssf)
- throws ActivationException, RemoteException
- {
- ActivationDesc desc = new ActivationDesc(obj.getClass().getName(),
- location, data, restart);
- ActivationID id = ActivationGroup.getSystem().registerObject(desc);
- Remote stub = exportObject(obj, id, port, csf, ssf);
- ActivationGroup.currentGroup().activeObject(id, obj);
- return id;
- }
-
- /**
- * Export the activatable remote object to the RMI runtime to make
- * the object available to receive incoming calls. The object is
- * exported on an anonymous port, if <code>port</code> is zero. <p>
- *
- * During activation, this <code>exportObject</code> method should
- * be invoked explicitly by an "activatable" object, that does not
- * extend the <code>Activatable</code> class. There is no need for objects
- * that do extend the <code>Activatable</code> class to invoke this
- * method directly; this method is called by the second constructor
- * above (which a subclass should invoke from its special activation
- * constructor).
- *
- * @return the stub for the activatable remote object
- * @param obj the remote object implementation
- * @param id the object's activation identifier
- * @param port the port on which the object is exported (an anonymous
- * port is used if port=0)
- * @exception RemoteException if object export fails
- * @since 1.2
- */
- public static Remote exportObject(Remote obj,
- ActivationID id,
- int port)
- throws RemoteException
- {
- Object[] args = new Object[] { id, new Integer(port) };
- return exportObject(obj, "ActivatableServerRef",
- idPortParamTypes, args);
- }
-
- /**
- * Export the activatable remote object to the RMI runtime to make
- * the object available to receive incoming calls. The object is
- * exported on an anonymous port, if <code>port</code> is zero. <p>
- *
- * During activation, this <code>exportObject</code> method should
- * be invoked explicitly by an "activatable" object, that does not
- * extend the <code>Activatable</code> class. There is no need for objects
- * that do extend the <code>Activatable</code> class to invoke this
- * method directly; this method is called by the second constructor
- * above (which a subclass should invoke from its special activation
- * constructor).
- *
- * @return the stub for the activatable remote object
- * @param obj the remote object implementation
- * @param id the object's activation identifier
- * @param port the port on which the object is exported (an anonymous
- * port is used if port=0)
- * @param csf the client-side socket factory for making calls to the
- * remote object
- * @param ssf the server-side socket factory for receiving remote calls
- * @exception RemoteException if object export fails
- * @since 1.2
- */
- public static Remote exportObject(Remote obj,
- ActivationID id,
- int port,
- RMIClientSocketFactory csf,
- RMIServerSocketFactory ssf)
- throws RemoteException
- {
- Object[] args = new Object[] { id, new Integer(port), csf, ssf };
- return exportObject(obj, "ActivatableServerRef",
- idPortFactoryParamTypes, args);
- }
-
- /**
- * Remove the remote object, obj, from the RMI runtime. If
- * successful, the object can no longer accept incoming RMI calls.
- * If the force parameter is true, the object is forcibly unexported
- * even if there are pending calls to the remote object or the
- * remote object still has calls in progress. If the force
- * parameter is false, the object is only unexported if there are
- * no pending or in progress calls to the object.
- *
- * @param obj the remote object to be unexported
- * @param force if true, unexports the object even if there are
- * pending or in-progress calls; if false, only unexports the object
- * if there are no pending or in-progress calls
- * @return true if operation is successful, false otherwise
- * @exception NoSuchObjectException if the remote object is not
- * currently exported
- * @since 1.2
- */
- public static boolean unexportObject(Remote obj, boolean force)
- throws java.rmi.NoSuchObjectException
- {
- return sun.rmi.transport.ObjectTable.unexportObject(obj, force);
- }
-
- /*
- * Create an instance of given server ref type with constructor chosen
- * by indicated paramters and supplied with given arguements, and
- * export remote object with it.
- *
- * All this code needs to be duplicated from UnicastRemoteObject
- * because java does not have "friends".
- */
- private static Remote exportObject(Remote obj, String refType,
- Class[] params, Object[] args)
- throws RemoteException
- {
- // compose name of server ref class and find it
- String refClassName = RemoteRef.packagePrefix + "." + refType;
- Class refClass;
- try {
- refClass = Class.forName(refClassName);
- } catch (ClassNotFoundException e) {
- throw new ExportException(
- "No class found for server ref type: " + refType);
- }
-
- if (!ServerRef.class.isAssignableFrom(refClass)) {
- throw new ExportException(
- "Server ref class not instance of " +
- ServerRef.class.getName() + ": " + refClass.getName());
- }
-
- // create server ref instance using given constructor and arguments
- ServerRef serverRef;
- try {
- java.lang.reflect.Constructor cons =
- refClass.getConstructor(params);
- serverRef = (ServerRef) cons.newInstance(args);
- // if impl does extend Activatable, set its ref
- if (obj instanceof Activatable)
- ((Activatable)obj).ref = serverRef;
-
- } catch (Exception e) {
- throw new ExportException(
- "Exception creating instance of server ref class: " +
- refClass.getName(), e);
- }
-
- return serverRef.exportObject(obj, null);
- }
- }