home *** CD-ROM | disk | FTP | other *** search
/ Java 1.2 How-To / JavaHowTo.iso / 3rdParty / jbuilder / unsupported / JDK1.2beta3 / SOURCE / SRC.ZIP / java / rmi / activation / Activatable.java next >
Encoding:
Java Source  |  1998-03-20  |  15.3 KB  |  383 lines

  1. /*
  2.  * @(#)Activatable.java    1.14 98/03/18
  3.  *
  4.  * Copyright 1997, 1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  *
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14.  
  15. package java.rmi.activation;
  16.  
  17. import java.lang.reflect.Constructor;
  18.  
  19. import java.rmi.activation.UnknownGroupException;
  20. import java.rmi.activation.UnknownObjectException;
  21. import java.rmi.Remote;
  22. import java.rmi.RemoteException;
  23. import java.rmi.MarshalledObject;
  24.  
  25. import java.rmi.server.ExportException;
  26. import java.rmi.server.RemoteRef;
  27. import java.rmi.server.RemoteServer;
  28. import java.rmi.server.ServerRef;
  29.  
  30. import java.security.CodeSource;
  31.  
  32.  
  33. /**
  34.  * The <code>Activatable</code> class provides support for remote
  35.  * objects that require persistent access over time and that
  36.  * can be activated by the system.
  37.  *
  38.  * @author    Ann Wollrath
  39.  * @version    1.14, 03/18/98
  40.  * @since    JDK1.2
  41.  */
  42. public abstract class Activatable extends RemoteServer {
  43.  
  44.     private ActivationID id;
  45.     /** indicate compatibility with JDK 1.2 version of class */
  46.     private static final long serialVersionUID = -3120617863591563455L;
  47.     
  48.     /* parameter types for server ref constructor invocation used below */
  49.     private static Class[] refConstrParams = {
  50.     int.class, ActivationID.class
  51.     };
  52.     
  53.     /**
  54.      * Constructor used to register and export the object on a
  55.      * specified port (an anonymous port is chosen if port=0) . <p>
  56.      *
  57.      * A concrete subclass of this class must call this constructor to
  58.      * register and export the object during <i>initial</i> construction.  As
  59.      * a side-effect of activatable object construction, the remote
  60.      * object is both "registered" with the activation system and
  61.      * "exported" (on an anonymous port if port=0) to the RMI runtime
  62.      * so that it is available to accept incoming calls from clients.
  63.      * Note that objects created via this constructor will be activated
  64.      * on demand, not restarted when the activation daemon starts.  If
  65.      * an activatable objects requires restart when the activation daemon
  66.      * rmid starts, use the second Activatable constructor form.
  67.      *
  68.      * @param source the CodeSource for classes for this object
  69.      * @param data the object's initialization data
  70.      * @param port the port on which the object is exported (an anonymous
  71.      * port is used if port=0)
  72.      * @exception ActivationException if object registration fails.
  73.      * @exception RemoteException if either of the following fails:
  74.      * a) registering the object with the activation system or b) exporting
  75.      * the object to the RMI runtime.
  76.      */
  77.     protected Activatable(CodeSource source, MarshalledObject data, int port)
  78.     throws ActivationException, RemoteException
  79.     {
  80.     super();
  81.     id = exportObject(this, source, data, false, port);
  82.     }
  83.  
  84.     /**
  85.      * Constructor used to register and export the object on a
  86.      * specified port (an anonymous port is chosen if port=0) .
  87.      *
  88.      * A concrete subclass of this class must call this constructor to
  89.      * register and export the object during <i>initial</i> construction.  As
  90.      * a side-effect of activatable object construction, the remote
  91.      * object is both "registered" with the activation system and
  92.      * "exported" (on an anonymous port if port=0) to the RMI runtime
  93.      * so that it is available to accept incoming calls from clients.
  94.      *
  95.      * @param source the CodeSource for classes for this object
  96.      * @param data the object's initialization data
  97.      * @param port the port on which the object is exported (an anonymous
  98.      * port is used if port=0)
  99.      * @param restart if true, the object is restarted when the activator
  100.      * is restarted; if false, the object is activated on demand.
  101.      * @exception ActivationException if object registration fails.
  102.      * @exception RemoteException if either of the following fails:
  103.      * a) registering the object with the activation system or b) exporting
  104.      * the object to the RMI runtime.
  105.      */
  106.     protected Activatable(CodeSource source,
  107.               MarshalledObject data,
  108.               boolean restart,
  109.               int port)
  110.     throws ActivationException, RemoteException
  111.     {
  112.     super();
  113.     id = exportObject(this, source, data, restart, port);
  114.     }
  115.     
  116.     /**
  117.      * Constructor used to activate/export the object on a specified
  118.      * port. An "activatable" remote object must have a constructor that
  119.      * takes two arguments: <ul>
  120.      * <li>the object's activation identifier (<code>ActivationID</code>), and
  121.      * <li>the object's initialization data (a <code>MarshalledObject</code>).
  122.      * </ul><p>
  123.      *
  124.      * A concrete subclass of this class must call this constructor when it is
  125.      * <i>activated</i> via the two parameter constructor described above. As
  126.      * a side-effect of construction, the remote object is "exported"
  127.      * to the RMI runtime (on the specified <code>port</code>) and is
  128.      * available to accept incoming calls from clients.
  129.      *
  130.      * @param id activation identifier for the object
  131.      * @param port the port number on which the object is exported
  132.      * @exception RemoteException if exporting the object to the RMI
  133.      * runtime fails
  134.      */
  135.     protected Activatable(ActivationID id, int port)
  136.     throws RemoteException 
  137.     {
  138.     super();
  139.     this.id = id;
  140.     exportObject(this, id, port);
  141.     }
  142.  
  143.     /**
  144.      * Returns the object's activation identifier.  The method is
  145.      * protected so that only subclasses can obtain an object's
  146.      * identifier.
  147.      * @return the object's activation identifier
  148.      */
  149.     protected ActivationID getID() 
  150.     {
  151.     return id;
  152.     }
  153.  
  154.     /** 
  155.      * Register an object descriptor for an activatable remote
  156.      * object so that is can be activated on demand.
  157.      *
  158.      * @param desc  the object's descriptor
  159.      * @return the stub for the activatable remote object
  160.      * @exception UnknownGroupException if group id in <code>desc</code>
  161.      * is not registered with the activation system
  162.      * @exception ActivationException if activation system is not running
  163.      * @exception RemoteException if remote call fails
  164.      */
  165.     public static Remote register(ActivationDesc desc)
  166.     throws UnknownGroupException, ActivationException, RemoteException
  167.     {
  168.     // register object with activator.
  169.     ActivationID id =
  170.         ActivationGroup.getSystem().registerObject(desc);
  171.     return sun.rmi.server.ActivatableRef.getStub(desc, id);
  172.     }
  173.     
  174.     /**
  175.      * Informs the system that the object with the corresponding activation
  176.      * <code>id</code> is currently inactive. If the object is currently
  177.      * active, the object is "unexported" from the RMI runtime (only if
  178.      * there are no pending or in-progress calls)
  179.      * so the that it can no longer receive incoming calls. This call
  180.      * informs this VM's ActivationGroup that the object is inactive,
  181.      * that, in turn, informs its ActivationMonitor. If this call
  182.      * completes successfully, a subsequent activate request to the activator
  183.      * will cause the object to reactivate. The operation may still
  184.      * succeed if the object is considered active but has already
  185.      * unexported itself.
  186.      *
  187.      * @param id the object's activation identifier
  188.      * @returns true if the operation succeeds (the operation will
  189.      * succeed if the object in currently known to be active and is
  190.      * either already unexported or is currently exported and has no
  191.      * pending/executing calls); false is returned if the object has
  192.      * pending/executing calls in which case it cannot be deactivated
  193.      * @exception UnknownObjectException if object is not known (it may
  194.      * already be inactive)
  195.      * @exception ActivationException if group is not active
  196.      * @exception RemoteException if call informing monitor fails
  197.      */
  198.     public static boolean inactive(ActivationID id)
  199.     throws UnknownObjectException, ActivationException, RemoteException
  200.     {
  201.     return ActivationGroup.currentGroup().inactiveObject(id);
  202.     }
  203.  
  204.     /**
  205.      * Revokes previous registration for the activation descriptor
  206.      * associated with <code>id</code>. An object can no longer be
  207.      * activated via that <code>id</code>.
  208.      *
  209.      * @param id the object's activation identifier
  210.      * @exception UnknownObjectException if object (<code>id</code>) is unknown
  211.      * @exception ActivationException if activation system is not running
  212.      * @exception RemoteException if remote call to activation system fails
  213.      */
  214.     
  215.     public static void unregister(ActivationID id)
  216.     throws UnknownObjectException, ActivationException, RemoteException
  217.     {
  218.     ActivationGroup.getSystem().unregisterObject(id);
  219.     }
  220.  
  221.  
  222.     /**
  223.      * This <code>exportObject</code> method may be invoked explicitly
  224.      * by an "activatable" object, that does not extend the
  225.      * <code>Activatable</code> class, in order to both a) register
  226.      * the object's activation descriptor, constructed from the supplied
  227.      * <code>source</code>, and <code>data</code>, with
  228.      * the activation system (so the object can be activated), and
  229.      * b) export the remote object, <code>obj</code>, on a specific
  230.      * port (if port=0, then an anonymous port is chosen). Once the
  231.      * object is exported, it can receive incoming RMI calls.<p>
  232.      *
  233.      * Note that objects exported via this method will be activated
  234.      * on demand, not restarted when the activation daemon starts.  If
  235.      * an activatable objects requires restart when the activation daemon
  236.      * rmid starts, use the second <code>exportObject</code> method (the
  237.      * one that takes the parameter <code>restart</code>).<p>
  238.      *
  239.      * This method does not need to be called if <code>obj</code>
  240.      * extends <code>Activatable</code>, since the first constructor
  241.      * calls this method.
  242.      *
  243.      * @param obj the object being exported
  244.      * @param source the object's code source
  245.      * @param data the object's bootstrapping data
  246.      * @param port the port on which the object is exported (an anonymous
  247.      * port is used if port=0)
  248.      * @returns the activation identifier obtained from registering the
  249.      * descriptor, <code>desc</code>, with the activation system
  250.      * the wrong group
  251.      * @exception ActivationException if activation group is not active
  252.      * @exception RemoteException if object registration or export fails
  253.      */
  254.     public static ActivationID exportObject(Remote obj,
  255.                         CodeSource source,
  256.                         MarshalledObject data,
  257.                         int port)
  258.     throws ActivationException, RemoteException
  259.     {
  260.     return exportObject(obj, source, data, false, port);
  261.     }
  262.  
  263.     /**
  264.      * This <code>exportObject</code> method may be invoked explicitly
  265.      * by an "activatable" object, that does not extend the
  266.      * <code>Activatable</code> class, in order to both a) register
  267.      * the object's activation descriptor, constructed from the supplied
  268.      * <code>source</code>, and <code>data</code>, with
  269.      * the activation system (so the object can be activated), and
  270.      * b) export the remote object, <code>obj</code>, on a specific
  271.      * port (if port=0, then an anonymous port is chosen). Once the
  272.      * object is exported, it can receive incoming RMI calls.<p>
  273.      *
  274.      * This method does not need to be called if <code>obj</code>
  275.      * extends <code>Activatable</code>, since the first constructor
  276.      * calls this method.
  277.      *
  278.      * @param obj the object being exported
  279.      * @param source the object's code source
  280.      * @param data the object's bootstrapping data
  281.      * @param restart if true, the object is restarted when the activator
  282.      * is restarted; if false, the object is activated on demand.
  283.      * @param port the port on which the object is exported (an anonymous
  284.      * port is used if port=0)
  285.      * @returns the activation identifier obtained from registering the
  286.      * descriptor, <code>desc</code>, with the activation system
  287.      * the wrong group
  288.      * @exception ActivationException if activation group is not active
  289.      * @exception RemoteException if object registration or export fails
  290.      */
  291.     public static ActivationID exportObject(Remote obj,
  292.                         CodeSource source,
  293.                         MarshalledObject data,
  294.                         boolean restart,
  295.                         int port)
  296.     throws ActivationException, RemoteException
  297.     {
  298.     ActivationDesc desc = new ActivationDesc(obj.getClass().getName(),
  299.                          source, data, restart);
  300.     ActivationID id = ActivationGroup.getSystem().registerObject(desc);
  301.     Remote stub = exportObject(obj, id, port);
  302.     ActivationGroup.currentGroup().activeObject(id, obj); 
  303.     return id;
  304.     }
  305.  
  306.     /** 
  307.      * Export the activatable remote object to the RMI runtime to make
  308.      * the object available to receive incoming calls. The object is
  309.      * exported on an anonymous port, if <code>port</code> is zero. <p>
  310.      *
  311.      * During activation, this <code>exportObject</code> method should
  312.      * be invoked explicitly by an "activatable" object, that does not
  313.      * extend the <code>Activatable</code> class. There is no need for objects
  314.      * that do extend the <code>Activatable</code> class to invoke this
  315.      * method directly; this method is called by the second constructor
  316.      * above (which a subclass should invoke from its special activation
  317.      * constructor).
  318.      * 
  319.      * @return the stub for the activatable remote object
  320.      * @param obj the remote object implementation
  321.      * @param id the object's  activation identifier
  322.      * @param port the port on which the object is exported (an anonymous
  323.      * port is used if port=0)
  324.      * @exception RemoteException if object export fails
  325.      */
  326.     public static Remote exportObject(Remote obj,
  327.                       ActivationID id,
  328.                       int port)
  329.     throws RemoteException
  330.     {
  331.     Object[] args = new Object[] { new Integer(port), id }; 
  332.     return exportObject(obj, "ActivatableServerRef",
  333.                 refConstrParams, args);
  334.     }
  335.  
  336.     /*
  337.      * Create an instance of given server ref type with constructor chosen
  338.      * by indicated paramters and supplied with given arguements, and
  339.      * export remote object with it.
  340.      *
  341.      * All this code needs to be duplicated from UnicastRemoteObject
  342.      * because java does not have "friends".
  343.      */
  344.     private static Remote exportObject(Remote obj, String refType,
  345.                        Class[] params, Object[] args)
  346.     throws RemoteException
  347.     {
  348.     // compose name of server ref class and find it
  349.     String refClassName = RemoteRef.packagePrefix + "." + refType;
  350.     Class refClass;
  351.     try {
  352.         refClass = Class.forName(refClassName);
  353.     } catch (ClassNotFoundException e) {
  354.         throw new ExportException(
  355.         "No class found for server ref type: " + refType);
  356.     }
  357.  
  358.     if (!ServerRef.class.isAssignableFrom(refClass)) {
  359.         throw new ExportException(
  360.         "Server ref class not instance of " +
  361.         ServerRef.class.getName() + ": " + refClass.getName());
  362.     }
  363.  
  364.     // create server ref instance using given constructor and arguments
  365.     ServerRef serverRef;
  366.     try {
  367.         java.lang.reflect.Constructor cons =
  368.         refClass.getConstructor(params);
  369.         serverRef = (ServerRef) cons.newInstance(args);
  370.         // if impl does extend Activatable, set its ref
  371.         if (obj instanceof Activatable)
  372.         ((Activatable)obj).ref = serverRef;
  373.  
  374.     } catch (Exception e) {
  375.         throw new ExportException(
  376.         "Exception creating instance of server ref class: " +
  377.         refClass.getName(), e);
  378.     }
  379.  
  380.     return serverRef.exportObject(obj, null);
  381.     }
  382. }
  383.