/* * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package sun.rmi.server; import java.io.ByteArrayOutputStream;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.ObjectInputStream;import java.io.OutputStream;import java.io.PrintStream;import java.io.PrintWriter;import java.io.Serializable;import java.lang.Process;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.net.InetAddress;import java.net.ServerSocket;import java.net.Socket;import java.net.SocketAddress;import java.net.SocketException;import java.nio.channels.Channel;import java.nio.channels.ServerSocketChannel;import java.rmi.AccessException;import java.rmi.AlreadyBoundException;import java.rmi.ConnectException;import java.rmi.ConnectIOException;import java.rmi.MarshalledObject;import java.rmi.NoSuchObjectException;import java.rmi.NotBoundException;import java.rmi.Remote;import java.rmi.RemoteException;import java.rmi.activation.ActivationDesc;import java.rmi.activation.ActivationException;import java.rmi.activation.ActivationGroupDesc;import java.rmi.activation.ActivationGroup;import java.rmi.activation.ActivationGroupID;import java.rmi.activation.ActivationID;import java.rmi.activation.ActivationInstantiator;import java.rmi.activation.ActivationMonitor;import java.rmi.activation.ActivationSystem;import java.rmi.activation.Activator;import java.rmi.activation.UnknownGroupException;import java.rmi.activation.UnknownObjectException;import java.rmi.registry.Registry;import java.rmi.server.ObjID;import java.rmi.server.RMIClassLoader;import java.rmi.server.RMIClientSocketFactory;import java.rmi.server.RMIServerSocketFactory;import java.rmi.server.RemoteObject;import java.rmi.server.RemoteServer;import java.rmi.server.UnicastRemoteObject;import java.security.AccessControlException;import java.security.AccessController;import java.security.AllPermission;import java.security.CodeSource;import java.security.Permission;import java.security.PermissionCollection;import java.security.Permissions;import java.security.Policy;import java.security.PrivilegedAction;import java.security.PrivilegedExceptionAction;import java.security.cert.Certificate;import java.text.MessageFormat;import java.util.ArrayList;import java.util.Arrays;import java.util.Date;import java.util.Enumeration;import java.util.HashMap;import java.util.HashSet;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.MissingResourceException;import java.util.Properties;import java.util.ResourceBundle;import java.util.Set;import java.util.concurrent.ConcurrentHashMap;import sun.rmi.log.LogHandler;import sun.rmi.log.ReliableLog;import sun.rmi.registry.RegistryImpl;import sun.rmi.runtime.NewThreadAction;import sun.rmi.server.UnicastServerRef;import sun.rmi.transport.LiveRef;import sun.security.action.GetBooleanAction;import sun.security.action.GetIntegerAction;import sun.security.action.GetPropertyAction;import sun.security.provider.PolicyFile;import com.sun.rmi.rmid.ExecPermission;import com.sun.rmi.rmid.ExecOptionPermission; /** * The Activator facilitates remote object activation. A "faulting" * remote reference calls the activator's <code>activate</code> method * to obtain a "live" reference to a activatable remote object. Upon * receiving a request for activation, the activator looks up the * activation descriptor for the activation identifier, id, determines * the group in which the object should be activated and invokes the * activate method on the object's activation group (described by the * remote interface <code>ActivationInstantiator</code>). The * activator initiates the execution of activation groups as * necessary. For example, if an activation group for a specific group * identifier is not already executing, the activator will spawn a * child process for the activation group. <p> * * The activator is responsible for monitoring and detecting when * activation groups fail so that it can remove stale remote references * from its internal tables. <p> * * @author Ann Wollrath * @since 1.2 */public class Activation implements Serializable { /** indicate compatibility with JDK 1.2 version of class */ private static final long serialVersionUID = 2921265612698155191L; private static final byte MAJOR_VERSION = 1; private static final byte MINOR_VERSION = 0; /** exec policy object */ private static Object execPolicy; private static Method execPolicyMethod; private static boolean debugExec; /** maps activation id to its respective group id */ private Map<ActivationID,ActivationGroupID> idTable = new ConcurrentHashMap<>(); /** maps group id to its GroupEntry groups */ private Map<ActivationGroupID,GroupEntry> groupTable = new ConcurrentHashMap<>(); private byte majorVersion = MAJOR_VERSION; private byte minorVersion = MINOR_VERSION; /** number of simultaneous group exec's */ private transient int groupSemaphore; /** counter for numbering groups */ private transient int groupCounter; /** reliable log to hold descriptor table */ private transient ReliableLog log; /** number of updates since last snapshot */ private transient int numUpdates; /** the java command */ // accessed by GroupEntry private transient String[] command; /** timeout on wait for child process to be created or destroyed */ private static final long groupTimeout = getInt("sun.rmi.activation.groupTimeout", 60000); /** take snapshot after this many updates */ private static final int snapshotInterval = getInt("sun.rmi.activation.snapshotInterval", 200); /** timeout on wait for child process to be created */ private static final long execTimeout = getInt("sun.rmi.activation.execTimeout", 30000); private static final Object initLock = new Object(); private static boolean initDone = false; // this should be a *private* method since it is privileged private static int getInt(String name, int def) { return AccessController.doPrivileged(new GetIntegerAction(name, def)); } private transient Activator activator; private transient Activator activatorStub; private transient ActivationSystem system; private transient ActivationSystem systemStub; private transient ActivationMonitor monitor; private transient Registry registry; private transient volatile boolean shuttingDown = false; private transient volatile Object startupLock; private transient Thread shutdownHook; private static ResourceBundle resources = null; /** * Create an uninitialized instance of Activation that can be * populated with log data. This is only called when the initial * snapshot is taken during the first incarnation of rmid. */ private Activation() {} /** * Recover activation state from the reliable log and initialize * activation services. */ private static void startActivation(int port, RMIServerSocketFactory ssf, String logName, String[] childArgs) throws Exception { ReliableLog log = new ReliableLog(logName, new ActLogHandler()); Activation state = (Activation) log.recover(); state.init(port, ssf, log, childArgs); } /** * Initialize the Activation instantiation; start activation * services. */ private void init(int port, RMIServerSocketFactory ssf, ReliableLog log, String[] childArgs) throws Exception { // initialize this.log = log; numUpdates = 0; shutdownHook = new ShutdownHook(); groupSemaphore = getInt("sun.rmi.activation.groupThrottle", 3); groupCounter = 0; Runtime.getRuntime().addShutdownHook(shutdownHook); // Use array size of 0, since the value from calling size() // may be out of date by the time toArray() is called. ActivationGroupID[] gids = groupTable.keySet().toArray(new ActivationGroupID[0]); synchronized (startupLock = new Object()) { // all the remote methods briefly synchronize on startupLock // (via checkShutdown) to make sure they don't happen in the // middle of this block. This block must not cause any such // incoming remote calls to happen, or deadlock would result! activator = new ActivatorImpl(port, ssf); activatorStub = (Activator) RemoteObject.toStub(activator); system = new ActivationSystemImpl(port, ssf); systemStub = (ActivationSystem) RemoteObject.toStub(system); monitor = new ActivationMonitorImpl(port, ssf); initCommand(childArgs); registry = new SystemRegistryImpl(port, null, ssf, systemStub); if (ssf != null) { synchronized (initLock) { initDone = true; initLock.notifyAll(); } } } startupLock = null; // restart services for (int i = gids.length; --i >= 0; ) { try { getGroupEntry(gids[i]).restartServices(); } catch (UnknownGroupException e) { System.err.println( getTextResource("rmid.restart.group.warning")); e.printStackTrace(); } } } /** * Previous versions used HashMap instead of ConcurrentHashMap. * Replace any HashMaps found during deserialization with * ConcurrentHashMaps. */ private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { ois.defaultReadObject(); if (! (groupTable instanceof ConcurrentHashMap)) { groupTable = new ConcurrentHashMap<>(groupTable); } if (! (idTable instanceof ConcurrentHashMap)) { idTable = new ConcurrentHashMap<>(idTable); } } private static class SystemRegistryImpl extends RegistryImpl { private static final String NAME = ActivationSystem.class.getName(); private final ActivationSystem systemStub; SystemRegistryImpl(int port, RMIClientSocketFactory csf, RMIServerSocketFactory ssf, ActivationSystem systemStub) throws RemoteException { super(port, csf, ssf); this.systemStub = systemStub; } /** * Returns the activation system stub if the specified name * matches the activation system's class name, otherwise * returns the result of invoking super.lookup with the specified * name. */ public Remote lookup(String name) throws RemoteException, NotBoundException { if (name.equals(NAME)) { return systemStub; } else { return super.lookup(name); } } public String[] list() throws RemoteException { String[] list1 = super.list(); int length = list1.length; String[] list2 = new String[length + 1]; if (length > 0) { System.arraycopy(list1, 0, list2, 0, length); } list2[length] = NAME; return list2; } public void bind(String name, Remote obj) throws RemoteException, AlreadyBoundException, AccessException { if (name.equals(NAME)) { throw new AccessException( "binding ActivationSystem is disallowed"); } else { super.bind(name, obj); } } public void unbind(String name) throws RemoteException, NotBoundException, AccessException { if (name.equals(NAME)) { throw new AccessException( "unbinding ActivationSystem is disallowed"); } else { super.unbind(name); } } public void rebind(String name, Remote obj) throws RemoteException, AccessException { if (name.equals(NAME)) { throw new AccessException( "binding ActivationSystem is disallowed"); } else { super.rebind(name, obj); } } } class ActivatorImpl extends RemoteServer implements Activator { // Because ActivatorImpl has a fixed ObjID, it can be // called by clients holding stale remote references. Each of // its remote methods, then, must check startupLock (calling // checkShutdown() is easiest). private static final long serialVersionUID = -3654244726254566136L; /** * Construct a new Activator on a specified port. */ ActivatorImpl(int port, RMIServerSocketFactory ssf) throws RemoteException { /* Server ref must be created and assigned before remote object * 'this' can be exported. */ LiveRef lref = new LiveRef(new ObjID(ObjID.ACTIVATOR_ID), port, null, ssf); UnicastServerRef uref = new UnicastServerRef(lref); ref = uref; uref.exportObject(this, null, false); } public MarshalledObject<? extends Remote> activate(ActivationID id, boolean force) throws ActivationException, UnknownObjectException, RemoteException { checkShutdown(); return getGroupEntry(id).activate(id, force); } } class ActivationMonitorImpl extends UnicastRemoteObject implements ActivationMonitor { private static final long serialVersionUID = -6214940464757948867L; ActivationMonitorImpl(int port, RMIServerSocketFactory ssf) throws RemoteException { super(port, null, ssf); } public void inactiveObject(ActivationID id) throws UnknownObjectException, RemoteException { try { checkShutdown(); } catch (ActivationException e) { return; } RegistryImpl.checkAccess("Activator.inactiveObject"); getGroupEntry(id).inactiveObject(id); } public void activeObject(ActivationID id, MarshalledObject<? extends Remote> mobj) throws UnknownObjectException, RemoteException { try { checkShutdown(); } catch (ActivationException e) { return; } RegistryImpl.checkAccess("ActivationSystem.activeObject"); getGroupEntry(id).activeObject(id, mobj); } public void inactiveGroup(ActivationGroupID id, long incarnation) throws UnknownGroupException, RemoteException { try { checkShutdown(); } catch (ActivationException e) { return; } RegistryImpl.checkAccess("ActivationMonitor.inactiveGroup"); getGroupEntry(id).inactiveGroup(incarnation, false); } } class ActivationSystemImpl extends RemoteServer implements ActivationSystem { private static final long serialVersionUID = 9100152600327688967L; // Because ActivationSystemImpl has a fixed ObjID, it can be // called by clients holding stale remote references. Each of // its remote methods, then, must check startupLock (calling // checkShutdown() is easiest). ActivationSystemImpl(int port, RMIServerSocketFactory ssf) throws RemoteException { /* Server ref must be created and assigned before remote object * 'this' can be exported. */ LiveRef lref = new LiveRef(new ObjID(4), port, null, ssf); UnicastServerRef uref = new UnicastServerRef(lref); ref = uref; uref.exportObject(this, null); } public ActivationID registerObject(ActivationDesc desc) throws ActivationException, UnknownGroupException, RemoteException { checkShutdown(); RegistryImpl.checkAccess("ActivationSystem.registerObject"); ActivationGroupID groupID = desc.getGroupID(); ActivationID id = new ActivationID(activatorStub); getGroupEntry(groupID).registerObject(id, desc, true); return id; } public void unregisterObject(ActivationID id) throws ActivationException, UnknownObjectException, RemoteException { checkShutdown(); RegistryImpl.checkAccess("ActivationSystem.unregisterObject"); getGroupEntry(id).unregisterObject(id, true); }Lines 1–500 of 2502. Load more
/* * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package sun.rmi.server; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.io.OutputStream; import java.io.PrintStream; import java.io.PrintWriter; import java.io.Serializable; import java.lang.Process; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketAddress; import java.net.SocketException; import java.nio.channels.Channel; import java.nio.channels.ServerSocketChannel; import java.rmi.AccessException; import java.rmi.AlreadyBoundException; import java.rmi.ConnectException; import java.rmi.ConnectIOException; import java.rmi.MarshalledObject; import java.rmi.NoSuchObjectException; import java.rmi.NotBoundException; import java.rmi.Remote; import java.rmi.RemoteException; import java.rmi.activation.ActivationDesc; import java.rmi.activation.ActivationException; import java.rmi.activation.ActivationGroupDesc; import java.rmi.activation.ActivationGroup; import java.rmi.activation.ActivationGroupID; import java.rmi.activation.ActivationID; import java.rmi.activation.ActivationInstantiator; import java.rmi.activation.ActivationMonitor; import java.rmi.activation.ActivationSystem; import java.rmi.activation.Activator; import java.rmi.activation.UnknownGroupException; import java.rmi.activation.UnknownObjectException; import java.rmi.registry.Registry; import java.rmi.server.ObjID; import java.rmi.server.RMIClassLoader; import java.rmi.server.RMIClientSocketFactory; import java.rmi.server.RMIServerSocketFactory; import java.rmi.server.RemoteObject; import java.rmi.server.RemoteServer; import java.rmi.server.UnicastRemoteObject; import java.security.AccessControlException; import java.security.AccessController; import java.security.AllPermission; import java.security.CodeSource; import java.security.Permission; import java.security.PermissionCollection; import java.security.Permissions; import java.security.Policy; import java.security.PrivilegedAction; import java.security.PrivilegedExceptionAction; import java.security.cert.Certificate; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.MissingResourceException; import java.util.Properties; import java.util.ResourceBundle; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import sun.rmi.log.LogHandler; import sun.rmi.log.ReliableLog; import sun.rmi.registry.RegistryImpl; import sun.rmi.runtime.NewThreadAction; import sun.rmi.server.UnicastServerRef; import sun.rmi.transport.LiveRef; import sun.security.action.GetBooleanAction; import sun.security.action.GetIntegerAction; import sun.security.action.GetPropertyAction; import sun.security.provider.PolicyFile; import com.sun.rmi.rmid.ExecPermission; import com.sun.rmi.rmid.ExecOptionPermission; /** * The Activator facilitates remote object activation. A "faulting" * remote reference calls the activator's <code>activate</code> method * to obtain a "live" reference to a activatable remote object. Upon * receiving a request for activation, the activator looks up the * activation descriptor for the activation identifier, id, determines * the group in which the object should be activated and invokes the * activate method on the object's activation group (described by the * remote interface <code>ActivationInstantiator</code>). The * activator initiates the execution of activation groups as * necessary. For example, if an activation group for a specific group * identifier is not already executing, the activator will spawn a * child process for the activation group. <p> * * The activator is responsible for monitoring and detecting when * activation groups fail so that it can remove stale remote references * from its internal tables. <p> * * @author Ann Wollrath * @since 1.2 */ public class Activation implements Serializable { /** indicate compatibility with JDK 1.2 version of class */ private static final long serialVersionUID = 2921265612698155191L; private static final byte MAJOR_VERSION = 1; private static final byte MINOR_VERSION = 0; /** exec policy object */ private static Object execPolicy; private static Method execPolicyMethod; private static boolean debugExec; /** maps activation id to its respective group id */ private Map<ActivationID,ActivationGroupID> idTable = new ConcurrentHashMap<>(); /** maps group id to its GroupEntry groups */ private Map<ActivationGroupID,GroupEntry> groupTable = new ConcurrentHashMap<>(); private byte majorVersion = MAJOR_VERSION; private byte minorVersion = MINOR_VERSION; /** number of simultaneous group exec's */ private transient int groupSemaphore; /** counter for numbering groups */ private transient int groupCounter; /** reliable log to hold descriptor table */ private transient ReliableLog log; /** number of updates since last snapshot */ private transient int numUpdates; /** the java command */ // accessed by GroupEntry private transient String[] command; /** timeout on wait for child process to be created or destroyed */ private static final long groupTimeout = getInt("sun.rmi.activation.groupTimeout", 60000); /** take snapshot after this many updates */ private static final int snapshotInterval = getInt("sun.rmi.activation.snapshotInterval", 200); /** timeout on wait for child process to be created */ private static final long execTimeout = getInt("sun.rmi.activation.execTimeout", 30000); private static final Object initLock = new Object(); private static boolean initDone = false; // this should be a *private* method since it is privileged private static int getInt(String name, int def) { return AccessController.doPrivileged(new GetIntegerAction(name, def)); } private transient Activator activator; private transient Activator activatorStub; private transient ActivationSystem system; private transient ActivationSystem systemStub; private transient ActivationMonitor monitor; private transient Registry registry; private transient volatile boolean shuttingDown = false; private transient volatile Object startupLock; private transient Thread shutdownHook; private static ResourceBundle resources = null; /** * Create an uninitialized instance of Activation that can be * populated with log data. This is only called when the initial * snapshot is taken during the first incarnation of rmid. */ private Activation() {} /** * Recover activation state from the reliable log and initialize * activation services. */ private static void startActivation(int port, RMIServerSocketFactory ssf, String logName, String[] childArgs) throws Exception { ReliableLog log = new ReliableLog(logName, new ActLogHandler()); Activation state = (Activation) log.recover(); state.init(port, ssf, log, childArgs); } /** * Initialize the Activation instantiation; start activation * services. */ private void init(int port, RMIServerSocketFactory ssf, ReliableLog log, String[] childArgs) throws Exception { // initialize this.log = log; numUpdates = 0; shutdownHook = new ShutdownHook(); groupSemaphore = getInt("sun.rmi.activation.groupThrottle", 3); groupCounter = 0; Runtime.getRuntime().addShutdownHook(shutdownHook); // Use array size of 0, since the value from calling size() // may be out of date by the time toArray() is called. ActivationGroupID[] gids = groupTable.keySet().toArray(new ActivationGroupID[0]); synchronized (startupLock = new Object()) { // all the remote methods briefly synchronize on startupLock // (via checkShutdown) to make sure they don't happen in the // middle of this block. This block must not cause any such // incoming remote calls to happen, or deadlock would result! activator = new ActivatorImpl(port, ssf); activatorStub = (Activator) RemoteObject.toStub(activator); system = new ActivationSystemImpl(port, ssf); systemStub = (ActivationSystem) RemoteObject.toStub(system); monitor = new ActivationMonitorImpl(port, ssf); initCommand(childArgs); registry = new SystemRegistryImpl(port, null, ssf, systemStub); if (ssf != null) { synchronized (initLock) { initDone = true; initLock.notifyAll(); } } } startupLock = null; // restart services for (int i = gids.length; --i >= 0; ) { try { getGroupEntry(gids[i]).restartServices(); } catch (UnknownGroupException e) { System.err.println( getTextResource("rmid.restart.group.warning")); e.printStackTrace(); } } } /** * Previous versions used HashMap instead of ConcurrentHashMap. * Replace any HashMaps found during deserialization with * ConcurrentHashMaps. */ private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { ois.defaultReadObject(); if (! (groupTable instanceof ConcurrentHashMap)) { groupTable = new ConcurrentHashMap<>(groupTable); } if (! (idTable instanceof ConcurrentHashMap)) { idTable = new ConcurrentHashMap<>(idTable); } } private static class SystemRegistryImpl extends RegistryImpl { private static final String NAME = ActivationSystem.class.getName(); private final ActivationSystem systemStub; SystemRegistryImpl(int port, RMIClientSocketFactory csf, RMIServerSocketFactory ssf, ActivationSystem systemStub) throws RemoteException { super(port, csf, ssf); this.systemStub = systemStub; } /** * Returns the activation system stub if the specified name * matches the activation system's class name, otherwise * returns the result of invoking super.lookup with the specified * name. */ public Remote lookup(String name) throws RemoteException, NotBoundException { if (name.equals(NAME)) { return systemStub; } else { return super.lookup(name); } } public String[] list() throws RemoteException { String[] list1 = super.list(); int length = list1.length; String[] list2 = new String[length + 1]; if (length > 0) { System.arraycopy(list1, 0, list2, 0, length); } list2[length] = NAME; return list2; } public void bind(String name, Remote obj) throws RemoteException, AlreadyBoundException, AccessException { if (name.equals(NAME)) { throw new AccessException( "binding ActivationSystem is disallowed"); } else { super.bind(name, obj); } } public void unbind(String name) throws RemoteException, NotBoundException, AccessException { if (name.equals(NAME)) { throw new AccessException( "unbinding ActivationSystem is disallowed"); } else { super.unbind(name); } } public void rebind(String name, Remote obj) throws RemoteException, AccessException { if (name.equals(NAME)) { throw new AccessException( "binding ActivationSystem is disallowed"); } else { super.rebind(name, obj); } } } class ActivatorImpl extends RemoteServer implements Activator { // Because ActivatorImpl has a fixed ObjID, it can be // called by clients holding stale remote references. Each of // its remote methods, then, must check startupLock (calling // checkShutdown() is easiest). private static final long serialVersionUID = -3654244726254566136L; /** * Construct a new Activator on a specified port. */ ActivatorImpl(int port, RMIServerSocketFactory ssf) throws RemoteException { /* Server ref must be created and assigned before remote object * 'this' can be exported. */ LiveRef lref = new LiveRef(new ObjID(ObjID.ACTIVATOR_ID), port, null, ssf); UnicastServerRef uref = new UnicastServerRef(lref); ref = uref; uref.exportObject(this, null, false); } public MarshalledObject<? extends Remote> activate(ActivationID id, boolean force) throws ActivationException, UnknownObjectException, RemoteException { checkShutdown(); return getGroupEntry(id).activate(id, force); } } class ActivationMonitorImpl extends UnicastRemoteObject implements ActivationMonitor { private static final long serialVersionUID = -6214940464757948867L; ActivationMonitorImpl(int port, RMIServerSocketFactory ssf) throws RemoteException { super(port, null, ssf); } public void inactiveObject(ActivationID id) throws UnknownObjectException, RemoteException { try { checkShutdown(); } catch (ActivationException e) { return; } RegistryImpl.checkAccess("Activator.inactiveObject"); getGroupEntry(id).inactiveObject(id); } public void activeObject(ActivationID id, MarshalledObject<? extends Remote> mobj) throws UnknownObjectException, RemoteException { try { checkShutdown(); } catch (ActivationException e) { return; } RegistryImpl.checkAccess("ActivationSystem.activeObject"); getGroupEntry(id).activeObject(id, mobj); } public void inactiveGroup(ActivationGroupID id, long incarnation) throws UnknownGroupException, RemoteException { try { checkShutdown(); } catch (ActivationException e) { return; } RegistryImpl.checkAccess("ActivationMonitor.inactiveGroup"); getGroupEntry(id).inactiveGroup(incarnation, false); } } class ActivationSystemImpl extends RemoteServer implements ActivationSystem { private static final long serialVersionUID = 9100152600327688967L; // Because ActivationSystemImpl has a fixed ObjID, it can be // called by clients holding stale remote references. Each of // its remote methods, then, must check startupLock (calling // checkShutdown() is easiest). ActivationSystemImpl(int port, RMIServerSocketFactory ssf) throws RemoteException { /* Server ref must be created and assigned before remote object * 'this' can be exported. */ LiveRef lref = new LiveRef(new ObjID(4), port, null, ssf); UnicastServerRef uref = new UnicastServerRef(lref); ref = uref; uref.exportObject(this, null); } public ActivationID registerObject(ActivationDesc desc) throws ActivationException, UnknownGroupException, RemoteException { checkShutdown(); RegistryImpl.checkAccess("ActivationSystem.registerObject"); ActivationGroupID groupID = desc.getGroupID(); ActivationID id = new ActivationID(activatorStub); getGroupEntry(groupID).registerObject(id, desc, true); return id; } public void unregisterObject(ActivationID id) throws ActivationException, UnknownObjectException, RemoteException { checkShutdown(); RegistryImpl.checkAccess("ActivationSystem.unregisterObject"); getGroupEntry(id).unregisterObject(id, true); }