FileDocCategorySizeDatePackage
ActivationGroup.javaAPI DocJava SE 5 API20673Fri Aug 26 14:57:12 BST 2005java.rmi.activation

ActivationGroup

public abstract class ActivationGroup extends UnicastRemoteObject implements ActivationInstantiator
An ActivationGroup is responsible for creating new instances of "activatable" objects in its group, informing its ActivationMonitor when either: its object's become active or inactive, or the group as a whole becomes inactive.

An ActivationGroup is initially created in one of several ways:

  • as a side-effect of creating an ActivationDesc without an explicit ActivationGroupID for the first activatable object in the group, or
  • via the ActivationGroup.createGroup method
  • as a side-effect of activating the first object in a group whose ActivationGroupDesc was only registered.

Only the activator can recreate an ActivationGroup. The activator spawns, as needed, a separate VM (as a child process, for example) for each registered activation group and directs activation requests to the appropriate group. It is implementation specific how VMs are spawned. An activation group is created via the ActivationGroup.createGroup static method. The createGroup method has two requirements on the group to be created: 1) the group must be a concrete subclass of ActivationGroup, and 2) the group must have a constructor that takes two arguments:

  • the group's ActivationGroupID, and
  • the group's initialization data (in a java.rmi.MarshalledObject)

When created, the default implementation of ActivationGroup will override the system properties with the properties requested when its ActivationGroupDesc was created, and will set a java.rmi.RMISecurityManager as the default system security manager. If your application requires specific properties to be set when objects are activated in the group, the application should create a special Properties object containing these properties, then create an ActivationGroupDesc with the Properties object, and use ActivationGroup.createGroup before creating any ActivationDescs (before the default ActivationGroupDesc is created). If your application requires the use of a security manager other than java.rmi.RMISecurityManager, in the ActivativationGroupDescriptor properties list you can set java.security.manager property to the name of the security manager you would like to install.

author
Ann Wollrath
version
1.44, 03/12/19
see
ActivationInstantiator
see
ActivationGroupDesc
see
ActivationGroupID
since
1.2

Fields Summary
private ActivationGroupID
groupID
private ActivationMonitor
monitor
private long
incarnation
private static ActivationGroup
currGroup
the current activation group for this VM
private static ActivationGroupID
currGroupID
the current group's identifier
private static ActivationSystem
currSystem
the current group's activation system
private static boolean
canCreate
used to control a group being created only once
private static Class[]
groupConstrParams
formal parameters for constructing an activation group
private static final long
serialVersionUID
indicate compatibility with the Java 2 SDK v1.2 version of class
Constructors Summary
protected ActivationGroup(ActivationGroupID groupID)
Constructs an activation group with the given activation group identifier. The group is exported as a java.rmi.server.UnicastRemoteObject.

param
groupID the group's identifier
throws
RemoteException if this group could not be exported
since
1.2

    
                       	    	        	      
      
	  
    
	// call super constructor to export the object
	super();
	this.groupID = groupID;
    
Methods Summary
public abstract voidactiveObject(ActivationID id, java.rmi.Remote obj)
The group's activeObject method is called when an object is exported (either by Activatable object construction or an explicit call to Activatable.exportObject. The group must inform its ActivationMonitor that the object is active (via the monitor's activeObject method) if the group hasn't already done so.

param
id the object's identifier
param
obj the remote object implementation
exception
UnknownObjectException if object is not registered
exception
RemoteException if call informing monitor fails
exception
ActivationException if group is inactive
since
1.2

protected voidactiveObject(ActivationID id, java.rmi.MarshalledObject mobj)
This protected method is necessary for subclasses to make the activeObject callback to the group's monitor. The call is simply forwarded to the group's ActivationMonitor.

param
id the object's identifier
param
mobj a marshalled object containing the remote object's stub
exception
UnknownObjectException if object is not registered
exception
RemoteException if call informing monitor fails
exception
ActivationException if an activation error occurs
since
1.2

	getMonitor().activeObject(id, mobj);
    
public static synchronized java.rmi.activation.ActivationGroupcreateGroup(ActivationGroupID id, ActivationGroupDesc desc, long incarnation)
Create and set the activation group for the current VM. The activation group can only be set if it is not currently set. An activation group is set using the createGroup method when the Activator initiates the re-creation of an activation group in order to carry out incoming activate requests. A group must first be registered with the ActivationSystem before it can be created via this method.

The group class specified by the ActivationGroupDesc must be a concrete subclass of ActivationGroup and have a public constructor that takes two arguments: the ActivationGroupID for the group and the MarshalledObject containing the group's initialization data (obtained from the ActivationGroupDesc.

If the group class name specified in the ActivationGroupDesc is null, then this method will behave as if the group descriptor contained the name of the default activation group implementation class.

Note that if your application creates its own custom activation group, a security manager must be set for that group. Otherwise objects cannot be activated in the group. java.rmi.RMISecurityManager is set by default.

If a security manager is already set in the group VM, this method first calls the security manager's checkSetFactory method. This could result in a SecurityException. If your application needs to set a different security manager, you must ensure that the policy file specified by the group's ActivationGroupDesc grants the group the necessary permissions to set a new security manager. (Note: This will be necessary if your group downloads and sets a security manager).

After the group is created, the ActivationSystem is informed that the group is active by calling the activeGroup method which returns the ActivationMonitor for the group. The application need not call activeGroup independently since it is taken care of by this method.

Once a group is created, subsequent calls to the currentGroupID method will return the identifier for this group until the group becomes inactive.

param
id the activation group's identifier
param
desc the activation group's descriptor
param
incarnation the group's incarnation number (zero on group's initial creation)
return
the activation group for the VM
exception
ActivationException if group already exists or if error occurs during group creation
exception
SecurityException if permission to create group is denied. (Note: The default implementation of the security manager checkSetFactory method requires the RuntimePermission "setFactory")
see
SecurityManager#checkSetFactory
since
1.2

	SecurityManager security = System.getSecurityManager();
	if (security != null)
	    security.checkSetFactory();
	    
	if (currGroup != null)
	    throw new ActivationException("group already exists");
	
	if (canCreate == false)
	    throw new ActivationException("group deactivated and " +
					  "cannot be recreated");

	try {
	    // load group's class
	    String groupClassName = desc.getClassName();

	    /*
	     * Fix for 4252236: resolution of the default
	     * activation group implementation name should be
	     * delayed until now.
	     */
	    if (groupClassName == null) {
		groupClassName = sun.rmi.server.ActivationGroupImpl.class.getName();
	    }
		
	    final String className = groupClassName;
		
	    /*
	     * Fix for 4170955: Because the default group
	     * implementation is a sun.* class, the group class
	     * needs to be loaded in a privileged block of code.  
	     */
	    Class cl;
	    try {
		cl = (Class) java.security.AccessController.
		    doPrivileged(new PrivilegedExceptionAction() {
			public Object run() throws ClassNotFoundException, 
			    MalformedURLException 
			    {
				return RMIClassLoader.
				    loadClass(desc.getLocation(), className);
			    }
		    });
	    } catch (PrivilegedActionException pae) {
		throw new ActivationException("Could not load default group " + 
					      "implementation class", 
					      pae.getException());
	    }
		
	    // create group
	    Constructor constructor = cl.getConstructor(groupConstrParams);
	    Object[] params = new Object[] { id, desc.getData() };

	    Object obj = constructor.newInstance(params);
	    if (obj instanceof ActivationGroup) {
		ActivationGroup newGroup = (ActivationGroup) obj;
		currSystem = id.getSystem();
		newGroup.incarnation = incarnation;
		newGroup.monitor =
		    currSystem.activeGroup(id, newGroup, incarnation);
		currGroup = newGroup;
		currGroupID = id;
		canCreate = false;
	    } else {
		throw new ActivationException("group not correct class: " +
					      obj.getClass().getName());
	    }
	} catch (java.lang.reflect.InvocationTargetException e) {
		e.getTargetException().printStackTrace();
		throw new ActivationException("exception in group constructor",
					      e.getTargetException());
		
	} catch (ActivationException e) {
	    throw e;
	    
	} catch (Exception e) {
	    throw new ActivationException("exception creating group", e);
	}
	
	return currGroup;
    
static synchronized java.rmi.activation.ActivationGroupcurrentGroup()
Returns the current group for the VM.

exception
ActivationException if current group is null (not active)

	if (currGroup == null) {
	    throw new ActivationException("group is not active");
	}
	return currGroup;
    
public static synchronized ActivationGroupIDcurrentGroupID()
Returns the current activation group's identifier. Returns null if no group is currently active for this VM.

return
the activation group's identifier
since
1.2

	return currGroupID;
    
private static synchronized voiddestroyGroup()
Destroys the current group.

	currGroup = null;
	currGroupID = null;
	// NOTE: don't set currSystem to null since it may be needed
    
private ActivationMonitorgetMonitor()
Returns the monitor for the activation group.

	synchronized (ActivationGroup.class) {
	    if (monitor != null) {
		return monitor;
	    }
	}
	throw new RemoteException("monitor not received");
    
public static synchronized ActivationSystemgetSystem()
Returns the activation system for the VM. The activation system may be set by the setSystem method. If the activation system is not set via the setSystem method, then the getSystem method attempts to obtain a reference to the ActivationSystem by looking up the name "java.rmi.activation.ActivationSystem" in the Activator's registry. By default, the port number used to look up the activation system is defined by ActivationSystem.SYSTEM_PORT. This port can be overridden by setting the property java.rmi.activation.port.

return
the activation system for the VM/group
exception
ActivationException if activation system cannot be obtained or is not bound (means that it is not running)
see
#setSystem
since
1.2

	if (currSystem == null) {
	    try {
		int port;
		port = ((Integer)java.security.AccessController.doPrivileged(
                    new GetIntegerAction("java.rmi.activation.port",
					 ActivationSystem.SYSTEM_PORT))).intValue();
		currSystem = (ActivationSystem)
		    Naming.lookup("//:" + port +
				  "/java.rmi.activation.ActivationSystem");
	    } catch (Exception e) {
		throw new ActivationException(
		    "unable to obtain ActivationSystem", e);
	    }
	}
	return currSystem;
    
protected voidinactiveGroup()
This protected method is necessary for subclasses to make the inactiveGroup callback to the group's monitor. The call is simply forwarded to the group's ActivationMonitor. Also, the current group for the VM is set to null.

exception
UnknownGroupException if group is not registered
exception
RemoteException if call informing monitor fails
since
1.2

	try {
	    getMonitor().inactiveGroup(groupID, incarnation);
	} finally {
	    destroyGroup();
	}
    
public booleaninactiveObject(ActivationID id)
The group's inactiveObject method is called indirectly via a call to the Activatable.inactive method. A remote object implementation must call Activatable's inactive method when that object deactivates (the object deems that it is no longer active). If the object does not call Activatable.inactive when it deactivates, the object will never be garbage collected since the group keeps strong references to the objects it creates.

The group's inactiveObject method unexports the remote object from the RMI runtime so that the object can no longer receive incoming RMI calls. An object will only be unexported if the object has no pending or executing calls. The subclass of ActivationGroup must override this method and unexport the object.

After removing the object from the RMI runtime, the group must inform its ActivationMonitor (via the monitor's inactiveObject method) that the remote object is not currently active so that the remote object will be re-activated by the activator upon a subsequent activation request.

This method simply informs the group's monitor that the object is inactive. It is up to the concrete subclass of ActivationGroup to fulfill the additional requirement of unexporting the object.

param
id the object's activation identifier
return
true if the object was successfully deactivated; otherwise returns false.
exception
UnknownObjectException if object is unknown (may already be inactive)
exception
RemoteException if call informing monitor fails
exception
ActivationException if group is inactive
since
1.2

	getMonitor().inactiveObject(id);
	return true;
    
static synchronized ActivationGroupIDinternalCurrentGroupID()
Returns the activation group identifier for the VM. If an activation group does not exist for this VM, a default activation group is created. A group can be created only once, so if a group has already become active and deactivated.

return
the activation group identifier
exception
ActivationException if error occurs during group creation, if security manager is not set, or if the group has already been created and deactivated.

	if (currGroupID == null)
	    throw new ActivationException("nonexistent group");

	return currGroupID;
    
public static synchronized voidsetSystem(ActivationSystem system)
Set the activation system for the VM. The activation system can only be set it if no group is currently active. If the activation system is not set via this call, then the getSystem method attempts to obtain a reference to the ActivationSystem by looking up the name "java.rmi.activation.ActivationSystem" in the Activator's registry. By default, the port number used to look up the activation system is defined by ActivationSystem.SYSTEM_PORT. This port can be overridden by setting the property java.rmi.activation.port.

If there is a security manager, this method first calls the security manager's checkSetFactory method. This could result in a SecurityException.

param
system remote reference to the ActivationSystem
exception
ActivationException if activation system is already set
exception
SecurityException if permission to set the activation system is denied. (Note: The default implementation of the security manager checkSetFactory method requires the RuntimePermission "setFactory")
see
#getSystem
see
SecurityManager#checkSetFactory
since
1.2

	SecurityManager security = System.getSecurityManager();
	if (security != null)
	    security.checkSetFactory();
	
	if (currSystem != null)
	    throw new ActivationException("activation system already set");

	currSystem = system;