Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/java/rmi/activation/Activatable.java
38918 views
/*1* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package java.rmi.activation;2627import java.rmi.MarshalledObject;28import java.rmi.NoSuchObjectException;29import java.rmi.Remote;30import java.rmi.RemoteException;31import java.rmi.activation.UnknownGroupException;32import java.rmi.activation.UnknownObjectException;33import java.rmi.server.RMIClientSocketFactory;34import java.rmi.server.RMIServerSocketFactory;35import java.rmi.server.RemoteServer;36import sun.rmi.server.ActivatableServerRef;3738/**39* The <code>Activatable</code> class provides support for remote40* objects that require persistent access over time and that41* can be activated by the system.42*43* <p>For the constructors and static <code>exportObject</code> methods,44* the stub for a remote object being exported is obtained as described in45* {@link java.rmi.server.UnicastRemoteObject}.46*47* <p>An attempt to serialize explicitly an instance of this class will48* fail.49*50* @author Ann Wollrath51* @since 1.252* @serial exclude53*/54public abstract class Activatable extends RemoteServer {5556private ActivationID id;57/** indicate compatibility with the Java 2 SDK v1.2 version of class */58private static final long serialVersionUID = -3120617863591563455L;5960/**61* Constructs an activatable remote object by registering62* an activation descriptor (with the specified location, data, and63* restart mode) for this object, and exporting the object with the64* specified port.65*66* <p><strong>Note:</strong> Using the <code>Activatable</code>67* constructors that both register and export an activatable remote68* object is strongly discouraged because the actions of registering69* and exporting the remote object are <i>not</i> guaranteed to be70* atomic. Instead, an application should register an activation71* descriptor and export a remote object separately, so that exceptions72* can be handled properly.73*74* <p>This method invokes the {@link75* #exportObject(Remote,String,MarshalledObject,boolean,int)76* exportObject} method with this object, and the specified location,77* data, restart mode, and port. Subsequent calls to {@link #getID}78* will return the activation identifier returned from the call to79* <code>exportObject</code>.80*81* @param location the location for classes for this object82* @param data the object's initialization data83* @param port the port on which the object is exported (an anonymous84* port is used if port=0)85* @param restart if true, the object is restarted (reactivated) when86* either the activator is restarted or the object's activation group87* is restarted after an unexpected crash; if false, the object is only88* activated on demand. Specifying <code>restart</code> to be89* <code>true</code> does not force an initial immediate activation of90* a newly registered object; initial activation is lazy.91* @exception ActivationException if object registration fails.92* @exception RemoteException if either of the following fails:93* a) registering the object with the activation system or b) exporting94* the object to the RMI runtime.95* @exception UnsupportedOperationException if and only if activation is96* not supported by this implementation.97* @since 1.298**/99protected Activatable(String location,100MarshalledObject<?> data,101boolean restart,102int port)103throws ActivationException, RemoteException104{105super();106id = exportObject(this, location, data, restart, port);107}108109/**110* Constructs an activatable remote object by registering111* an activation descriptor (with the specified location, data, and112* restart mode) for this object, and exporting the object with the113* specified port, and specified client and server socket factories.114*115* <p><strong>Note:</strong> Using the <code>Activatable</code>116* constructors that both register and export an activatable remote117* object is strongly discouraged because the actions of registering118* and exporting the remote object are <i>not</i> guaranteed to be119* atomic. Instead, an application should register an activation120* descriptor and export a remote object separately, so that exceptions121* can be handled properly.122*123* <p>This method invokes the {@link124* #exportObject(Remote,String,MarshalledObject,boolean,int,RMIClientSocketFactory,RMIServerSocketFactory)125* exportObject} method with this object, and the specified location,126* data, restart mode, port, and client and server socket factories.127* Subsequent calls to {@link #getID} will return the activation128* identifier returned from the call to <code>exportObject</code>.129*130* @param location the location for classes for this object131* @param data the object's initialization data132* @param restart if true, the object is restarted (reactivated) when133* either the activator is restarted or the object's activation group134* is restarted after an unexpected crash; if false, the object is only135* activated on demand. Specifying <code>restart</code> to be136* <code>true</code> does not force an initial immediate activation of137* a newly registered object; initial activation is lazy.138* @param port the port on which the object is exported (an anonymous139* port is used if port=0)140* @param csf the client-side socket factory for making calls to the141* remote object142* @param ssf the server-side socket factory for receiving remote calls143* @exception ActivationException if object registration fails.144* @exception RemoteException if either of the following fails:145* a) registering the object with the activation system or b) exporting146* the object to the RMI runtime.147* @exception UnsupportedOperationException if and only if activation is148* not supported by this implementation.149* @since 1.2150**/151protected Activatable(String location,152MarshalledObject<?> data,153boolean restart,154int port,155RMIClientSocketFactory csf,156RMIServerSocketFactory ssf)157throws ActivationException, RemoteException158{159super();160id = exportObject(this, location, data, restart, port, csf, ssf);161}162163/**164* Constructor used to activate/export the object on a specified165* port. An "activatable" remote object must have a constructor that166* takes two arguments: <ul>167* <li>the object's activation identifier (<code>ActivationID</code>), and168* <li>the object's initialization data (a <code>MarshalledObject</code>).169* </ul><p>170*171* A concrete subclass of this class must call this constructor when it is172* <i>activated</i> via the two parameter constructor described above. As173* a side-effect of construction, the remote object is "exported"174* to the RMI runtime (on the specified <code>port</code>) and is175* available to accept incoming calls from clients.176*177* @param id activation identifier for the object178* @param port the port number on which the object is exported179* @exception RemoteException if exporting the object to the RMI180* runtime fails181* @exception UnsupportedOperationException if and only if activation is182* not supported by this implementation183* @since 1.2184*/185protected Activatable(ActivationID id, int port)186throws RemoteException187{188super();189this.id = id;190exportObject(this, id, port);191}192193/**194* Constructor used to activate/export the object on a specified195* port. An "activatable" remote object must have a constructor that196* takes two arguments: <ul>197* <li>the object's activation identifier (<code>ActivationID</code>), and198* <li>the object's initialization data (a <code>MarshalledObject</code>).199* </ul><p>200*201* A concrete subclass of this class must call this constructor when it is202* <i>activated</i> via the two parameter constructor described above. As203* a side-effect of construction, the remote object is "exported"204* to the RMI runtime (on the specified <code>port</code>) and is205* available to accept incoming calls from clients.206*207* @param id activation identifier for the object208* @param port the port number on which the object is exported209* @param csf the client-side socket factory for making calls to the210* remote object211* @param ssf the server-side socket factory for receiving remote calls212* @exception RemoteException if exporting the object to the RMI213* runtime fails214* @exception UnsupportedOperationException if and only if activation is215* not supported by this implementation216* @since 1.2217*/218protected Activatable(ActivationID id, int port,219RMIClientSocketFactory csf,220RMIServerSocketFactory ssf)221throws RemoteException222{223super();224this.id = id;225exportObject(this, id, port, csf, ssf);226}227228/**229* Returns the object's activation identifier. The method is230* protected so that only subclasses can obtain an object's231* identifier.232* @return the object's activation identifier233* @since 1.2234*/235protected ActivationID getID() {236return id;237}238239/**240* Register an object descriptor for an activatable remote241* object so that is can be activated on demand.242*243* @param desc the object's descriptor244* @return the stub for the activatable remote object245* @exception UnknownGroupException if group id in <code>desc</code>246* is not registered with the activation system247* @exception ActivationException if activation system is not running248* @exception RemoteException if remote call fails249* @exception UnsupportedOperationException if and only if activation is250* not supported by this implementation251* @since 1.2252*/253public static Remote register(ActivationDesc desc)254throws UnknownGroupException, ActivationException, RemoteException255{256// register object with activator.257ActivationID id =258ActivationGroup.getSystem().registerObject(desc);259return sun.rmi.server.ActivatableRef.getStub(desc, id);260}261262/**263* Informs the system that the object with the corresponding activation264* <code>id</code> is currently inactive. If the object is currently265* active, the object is "unexported" from the RMI runtime (only if266* there are no pending or in-progress calls)267* so the that it can no longer receive incoming calls. This call268* informs this VM's ActivationGroup that the object is inactive,269* that, in turn, informs its ActivationMonitor. If this call270* completes successfully, a subsequent activate request to the activator271* will cause the object to reactivate. The operation may still272* succeed if the object is considered active but has already273* unexported itself.274*275* @param id the object's activation identifier276* @return true if the operation succeeds (the operation will277* succeed if the object in currently known to be active and is278* either already unexported or is currently exported and has no279* pending/executing calls); false is returned if the object has280* pending/executing calls in which case it cannot be deactivated281* @exception UnknownObjectException if object is not known (it may282* already be inactive)283* @exception ActivationException if group is not active284* @exception RemoteException if call informing monitor fails285* @exception UnsupportedOperationException if and only if activation is286* not supported by this implementation287* @since 1.2288*/289public static boolean inactive(ActivationID id)290throws UnknownObjectException, ActivationException, RemoteException291{292return ActivationGroup.currentGroup().inactiveObject(id);293}294295/**296* Revokes previous registration for the activation descriptor297* associated with <code>id</code>. An object can no longer be298* activated via that <code>id</code>.299*300* @param id the object's activation identifier301* @exception UnknownObjectException if object (<code>id</code>) is unknown302* @exception ActivationException if activation system is not running303* @exception RemoteException if remote call to activation system fails304* @exception UnsupportedOperationException if and only if activation is305* not supported by this implementation306* @since 1.2307*/308public static void unregister(ActivationID id)309throws UnknownObjectException, ActivationException, RemoteException310{311ActivationGroup.getSystem().unregisterObject(id);312}313314/**315* Registers an activation descriptor (with the specified location,316* data, and restart mode) for the specified object, and exports that317* object with the specified port.318*319* <p><strong>Note:</strong> Using this method (as well as the320* <code>Activatable</code> constructors that both register and export321* an activatable remote object) is strongly discouraged because the322* actions of registering and exporting the remote object are323* <i>not</i> guaranteed to be atomic. Instead, an application should324* register an activation descriptor and export a remote object325* separately, so that exceptions can be handled properly.326*327* <p>This method invokes the {@link328* #exportObject(Remote,String,MarshalledObject,boolean,int,RMIClientSocketFactory,RMIServerSocketFactory)329* exportObject} method with the specified object, location, data,330* restart mode, and port, and <code>null</code> for both client and331* server socket factories, and then returns the resulting activation332* identifier.333*334* @param obj the object being exported335* @param location the object's code location336* @param data the object's bootstrapping data337* @param restart if true, the object is restarted (reactivated) when338* either the activator is restarted or the object's activation group339* is restarted after an unexpected crash; if false, the object is only340* activated on demand. Specifying <code>restart</code> to be341* <code>true</code> does not force an initial immediate activation of342* a newly registered object; initial activation is lazy.343* @param port the port on which the object is exported (an anonymous344* port is used if port=0)345* @return the activation identifier obtained from registering the346* descriptor, <code>desc</code>, with the activation system347* the wrong group348* @exception ActivationException if activation group is not active349* @exception RemoteException if object registration or export fails350* @exception UnsupportedOperationException if and only if activation is351* not supported by this implementation352* @since 1.2353**/354public static ActivationID exportObject(Remote obj,355String location,356MarshalledObject<?> data,357boolean restart,358int port)359throws ActivationException, RemoteException360{361return exportObject(obj, location, data, restart, port, null, null);362}363364/**365* Registers an activation descriptor (with the specified location,366* data, and restart mode) for the specified object, and exports that367* object with the specified port, and the specified client and server368* socket factories.369*370* <p><strong>Note:</strong> Using this method (as well as the371* <code>Activatable</code> constructors that both register and export372* an activatable remote object) is strongly discouraged because the373* actions of registering and exporting the remote object are374* <i>not</i> guaranteed to be atomic. Instead, an application should375* register an activation descriptor and export a remote object376* separately, so that exceptions can be handled properly.377*378* <p>This method first registers an activation descriptor for the379* specified object as follows. It obtains the activation system by380* invoking the method {@link ActivationGroup#getSystem381* ActivationGroup.getSystem}. This method then obtains an {@link382* ActivationID} for the object by invoking the activation system's383* {@link ActivationSystem#registerObject registerObject} method with384* an {@link ActivationDesc} constructed with the specified object's385* class name, and the specified location, data, and restart mode. If386* an exception occurs obtaining the activation system or registering387* the activation descriptor, that exception is thrown to the caller.388*389* <p>Next, this method exports the object by invoking the {@link390* #exportObject(Remote,ActivationID,int,RMIClientSocketFactory,RMIServerSocketFactory)391* exportObject} method with the specified remote object, the392* activation identifier obtained from registration, the specified393* port, and the specified client and server socket factories. If an394* exception occurs exporting the object, this method attempts to395* unregister the activation identifier (obtained from registration) by396* invoking the activation system's {@link397* ActivationSystem#unregisterObject unregisterObject} method with the398* activation identifier. If an exception occurs unregistering the399* identifier, that exception is ignored, and the original exception400* that occurred exporting the object is thrown to the caller.401*402* <p>Finally, this method invokes the {@link403* ActivationGroup#activeObject activeObject} method on the activation404* group in this VM with the activation identifier and the specified405* remote object, and returns the activation identifier to the caller.406*407* @param obj the object being exported408* @param location the object's code location409* @param data the object's bootstrapping data410* @param restart if true, the object is restarted (reactivated) when411* either the activator is restarted or the object's activation group412* is restarted after an unexpected crash; if false, the object is only413* activated on demand. Specifying <code>restart</code> to be414* <code>true</code> does not force an initial immediate activation of415* a newly registered object; initial activation is lazy.416* @param port the port on which the object is exported (an anonymous417* port is used if port=0)418* @param csf the client-side socket factory for making calls to the419* remote object420* @param ssf the server-side socket factory for receiving remote calls421* @return the activation identifier obtained from registering the422* descriptor with the activation system423* @exception ActivationException if activation group is not active424* @exception RemoteException if object registration or export fails425* @exception UnsupportedOperationException if and only if activation is426* not supported by this implementation427* @since 1.2428**/429public static ActivationID exportObject(Remote obj,430String location,431MarshalledObject<?> data,432boolean restart,433int port,434RMIClientSocketFactory csf,435RMIServerSocketFactory ssf)436throws ActivationException, RemoteException437{438ActivationDesc desc = new ActivationDesc(obj.getClass().getName(),439location, data, restart);440/*441* Register descriptor.442*/443ActivationSystem system = ActivationGroup.getSystem();444ActivationID id = system.registerObject(desc);445446/*447* Export object.448*/449try {450exportObject(obj, id, port, csf, ssf);451} catch (RemoteException e) {452/*453* Attempt to unregister activation descriptor because export454* failed and register/export should be atomic (see 4323621).455*/456try {457system.unregisterObject(id);458} catch (Exception ex) {459}460/*461* Report original exception.462*/463throw e;464}465466/*467* This call can't fail (it is a local call, and the only possible468* exception, thrown if the group is inactive, will not be thrown469* because the group is not inactive).470*/471ActivationGroup.currentGroup().activeObject(id, obj);472473return id;474}475476/**477* Export the activatable remote object to the RMI runtime to make478* the object available to receive incoming calls. The object is479* exported on an anonymous port, if <code>port</code> is zero. <p>480*481* During activation, this <code>exportObject</code> method should482* be invoked explicitly by an "activatable" object, that does not483* extend the <code>Activatable</code> class. There is no need for objects484* that do extend the <code>Activatable</code> class to invoke this485* method directly because the object is exported during construction.486*487* @return the stub for the activatable remote object488* @param obj the remote object implementation489* @param id the object's activation identifier490* @param port the port on which the object is exported (an anonymous491* port is used if port=0)492* @exception RemoteException if object export fails493* @exception UnsupportedOperationException if and only if activation is494* not supported by this implementation495* @since 1.2496*/497public static Remote exportObject(Remote obj,498ActivationID id,499int port)500throws RemoteException501{502return exportObject(obj, new ActivatableServerRef(id, port));503}504505/**506* Export the activatable remote object to the RMI runtime to make507* the object available to receive incoming calls. The object is508* exported on an anonymous port, if <code>port</code> is zero. <p>509*510* During activation, this <code>exportObject</code> method should511* be invoked explicitly by an "activatable" object, that does not512* extend the <code>Activatable</code> class. There is no need for objects513* that do extend the <code>Activatable</code> class to invoke this514* method directly because the object is exported during construction.515*516* @return the stub for the activatable remote object517* @param obj the remote object implementation518* @param id the object's activation identifier519* @param port the port on which the object is exported (an anonymous520* port is used if port=0)521* @param csf the client-side socket factory for making calls to the522* remote object523* @param ssf the server-side socket factory for receiving remote calls524* @exception RemoteException if object export fails525* @exception UnsupportedOperationException if and only if activation is526* not supported by this implementation527* @since 1.2528*/529public static Remote exportObject(Remote obj,530ActivationID id,531int port,532RMIClientSocketFactory csf,533RMIServerSocketFactory ssf)534throws RemoteException535{536return exportObject(obj, new ActivatableServerRef(id, port, csf, ssf));537}538539/**540* Remove the remote object, obj, from the RMI runtime. If541* successful, the object can no longer accept incoming RMI calls.542* If the force parameter is true, the object is forcibly unexported543* even if there are pending calls to the remote object or the544* remote object still has calls in progress. If the force545* parameter is false, the object is only unexported if there are546* no pending or in progress calls to the object.547*548* @param obj the remote object to be unexported549* @param force if true, unexports the object even if there are550* pending or in-progress calls; if false, only unexports the object551* if there are no pending or in-progress calls552* @return true if operation is successful, false otherwise553* @exception NoSuchObjectException if the remote object is not554* currently exported555* @exception UnsupportedOperationException if and only if activation is556* not supported by this implementation557* @since 1.2558*/559public static boolean unexportObject(Remote obj, boolean force)560throws NoSuchObjectException561{562return sun.rmi.transport.ObjectTable.unexportObject(obj, force);563}564565/**566* Exports the specified object using the specified server ref.567*/568private static Remote exportObject(Remote obj, ActivatableServerRef sref)569throws RemoteException570{571// if obj extends Activatable, set its ref.572if (obj instanceof Activatable) {573((Activatable) obj).ref = sref;574575}576return sref.exportObject(obj, null, false);577}578}579580581