1 /*
2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
57 import java.rmi.RemoteException;
58 import java.rmi.activation.ActivationDesc;
59 import java.rmi.activation.ActivationException;
60 import java.rmi.activation.ActivationGroupDesc;
61 import java.rmi.activation.ActivationGroup;
62 import java.rmi.activation.ActivationGroupID;
63 import java.rmi.activation.ActivationID;
64 import java.rmi.activation.ActivationInstantiator;
65 import java.rmi.activation.ActivationMonitor;
66 import java.rmi.activation.ActivationSystem;
67 import java.rmi.activation.Activator;
68 import java.rmi.activation.UnknownGroupException;
69 import java.rmi.activation.UnknownObjectException;
70 import java.rmi.registry.Registry;
71 import java.rmi.server.ObjID;
72 import java.rmi.server.RMIClassLoader;
73 import java.rmi.server.RMIClientSocketFactory;
74 import java.rmi.server.RMIServerSocketFactory;
75 import java.rmi.server.RemoteObject;
76 import java.rmi.server.RemoteServer;
77 import java.rmi.server.UnicastRemoteObject;
78 import java.security.AccessControlException;
79 import java.security.AccessController;
80 import java.security.AllPermission;
81 import java.security.CodeSource;
82 import java.security.Permission;
83 import java.security.PermissionCollection;
84 import java.security.Permissions;
85 import java.security.Policy;
86 import java.security.PrivilegedAction;
87 import java.security.PrivilegedExceptionAction;
88 import java.security.cert.Certificate;
89 import java.text.MessageFormat;
90 import java.util.ArrayList;
91 import java.util.Arrays;
92 import java.util.Date;
93 import java.util.Enumeration;
94 import java.util.HashMap;
95 import java.util.HashSet;
96 import java.util.Iterator;
97 import java.util.List;
98 import java.util.Map;
99 import java.util.MissingResourceException;
100 import java.util.Properties;
101 import java.util.ResourceBundle;
102 import java.util.Set;
103 import java.util.concurrent.ConcurrentHashMap;
104 import sun.rmi.log.LogHandler;
105 import sun.rmi.log.ReliableLog;
106 import sun.rmi.registry.RegistryImpl;
107 import sun.rmi.runtime.NewThreadAction;
108 import sun.rmi.server.UnicastServerRef;
109 import sun.rmi.transport.LiveRef;
110 import sun.security.action.GetBooleanAction;
111 import sun.security.action.GetIntegerAction;
112 import sun.security.action.GetPropertyAction;
113 import sun.security.provider.PolicyFile;
114 import com.sun.rmi.rmid.ExecPermission;
115 import com.sun.rmi.rmid.ExecOptionPermission;
116
117 /**
118 * The Activator facilitates remote object activation. A "faulting"
119 * remote reference calls the activator's <code>activate</code> method
120 * to obtain a "live" reference to a activatable remote object. Upon
121 * receiving a request for activation, the activator looks up the
122 * activation descriptor for the activation identifier, id, determines
123 * the group in which the object should be activated and invokes the
124 * activate method on the object's activation group (described by the
125 * remote interface <code>ActivationInstantiator</code>). The
126 * activator initiates the execution of activation groups as
127 * necessary. For example, if an activation group for a specific group
128 * identifier is not already executing, the activator will spawn a
129 * child process for the activation group. <p>
165 private transient ReliableLog log;
166 /** number of updates since last snapshot */
167 private transient int numUpdates;
168
169 /** the java command */
170 // accessed by GroupEntry
171 private transient String[] command;
172 /** timeout on wait for child process to be created or destroyed */
173 private static final long groupTimeout =
174 getInt("sun.rmi.activation.groupTimeout", 60000);
175 /** take snapshot after this many updates */
176 private static final int snapshotInterval =
177 getInt("sun.rmi.activation.snapshotInterval", 200);
178 /** timeout on wait for child process to be created */
179 private static final long execTimeout =
180 getInt("sun.rmi.activation.execTimeout", 30000);
181
182 private static final Object initLock = new Object();
183 private static boolean initDone = false;
184
185 // this should be a *private* method since it is privileged
186 private static int getInt(String name, int def) {
187 return AccessController.doPrivileged(new GetIntegerAction(name, def));
188 }
189
190 private transient Activator activator;
191 private transient Activator activatorStub;
192 private transient ActivationSystem system;
193 private transient ActivationSystem systemStub;
194 private transient ActivationMonitor monitor;
195 private transient Registry registry;
196 private transient volatile boolean shuttingDown = false;
197 private transient volatile Object startupLock;
198 private transient Thread shutdownHook;
199
200 private static ResourceBundle resources = null;
201
202 /**
203 * Create an uninitialized instance of Activation that can be
204 * populated with log data. This is only called when the initial
205 * snapshot is taken during the first incarnation of rmid.
206 */
207 private Activation() {}
208
209 /**
210 * Recover activation state from the reliable log and initialize
211 * activation services.
212 */
213 private static void startActivation(int port,
214 RMIServerSocketFactory ssf,
215 String logName,
216 String[] childArgs)
217 throws Exception
218 {
219 ReliableLog log = new ReliableLog(logName, new ActLogHandler());
220 Activation state = (Activation) log.recover();
221 state.init(port, ssf, log, childArgs);
222 }
223
224 /**
225 * Initialize the Activation instantiation; start activation
226 * services.
227 */
228 private void init(int port,
229 RMIServerSocketFactory ssf,
409
410 class ActivationMonitorImpl extends UnicastRemoteObject
411 implements ActivationMonitor
412 {
413 private static final long serialVersionUID = -6214940464757948867L;
414
415 ActivationMonitorImpl(int port, RMIServerSocketFactory ssf)
416 throws RemoteException
417 {
418 super(port, null, ssf);
419 }
420
421 public void inactiveObject(ActivationID id)
422 throws UnknownObjectException, RemoteException
423 {
424 try {
425 checkShutdown();
426 } catch (ActivationException e) {
427 return;
428 }
429 RegistryImpl.checkAccess("Activator.inactiveObject");
430 getGroupEntry(id).inactiveObject(id);
431 }
432
433 public void activeObject(ActivationID id,
434 MarshalledObject<? extends Remote> mobj)
435 throws UnknownObjectException, RemoteException
436 {
437 try {
438 checkShutdown();
439 } catch (ActivationException e) {
440 return;
441 }
442 RegistryImpl.checkAccess("ActivationSystem.activeObject");
443 getGroupEntry(id).activeObject(id, mobj);
444 }
445
446 public void inactiveGroup(ActivationGroupID id,
447 long incarnation)
448 throws UnknownGroupException, RemoteException
449 {
450 try {
451 checkShutdown();
452 } catch (ActivationException e) {
453 return;
454 }
455 RegistryImpl.checkAccess("ActivationMonitor.inactiveGroup");
456 getGroupEntry(id).inactiveGroup(incarnation, false);
457 }
458 }
459
460
461 class ActivationSystemImpl
462 extends RemoteServer
463 implements ActivationSystem
464 {
465 private static final long serialVersionUID = 9100152600327688967L;
466
467 // Because ActivationSystemImpl has a fixed ObjID, it can be
468 // called by clients holding stale remote references. Each of
469 // its remote methods, then, must check startupLock (calling
470 // checkShutdown() is easiest).
471 ActivationSystemImpl(int port, RMIServerSocketFactory ssf)
472 throws RemoteException
473 {
474 /* Server ref must be created and assigned before remote object
475 * 'this' can be exported.
476 */
477 LiveRef lref = new LiveRef(new ObjID(4), port, null, ssf);
478 UnicastServerRef uref = new UnicastServerRef(lref);
479 ref = uref;
480 uref.exportObject(this, null);
481 }
482
483 public ActivationID registerObject(ActivationDesc desc)
484 throws ActivationException, UnknownGroupException, RemoteException
485 {
486 checkShutdown();
487 RegistryImpl.checkAccess("ActivationSystem.registerObject");
488
489 ActivationGroupID groupID = desc.getGroupID();
490 ActivationID id = new ActivationID(activatorStub);
491 getGroupEntry(groupID).registerObject(id, desc, true);
492 return id;
493 }
494
495 public void unregisterObject(ActivationID id)
496 throws ActivationException, UnknownObjectException, RemoteException
497 {
498 checkShutdown();
499 RegistryImpl.checkAccess("ActivationSystem.unregisterObject");
500 getGroupEntry(id).unregisterObject(id, true);
501 }
502
503 public ActivationGroupID registerGroup(ActivationGroupDesc desc)
504 throws ActivationException, RemoteException
505 {
506 checkShutdown();
507 RegistryImpl.checkAccess("ActivationSystem.registerGroup");
508 checkArgs(desc, null);
509
510 ActivationGroupID id = new ActivationGroupID(systemStub);
511 GroupEntry entry = new GroupEntry(id, desc);
512 // table insertion must take place before log update
513 groupTable.put(id, entry);
514 addLogRecord(new LogRegisterGroup(id, desc));
515 return id;
516 }
517
518 public ActivationMonitor activeGroup(ActivationGroupID id,
519 ActivationInstantiator group,
520 long incarnation)
521 throws ActivationException, UnknownGroupException, RemoteException
522 {
523 checkShutdown();
524 RegistryImpl.checkAccess("ActivationSystem.activeGroup");
525
526 getGroupEntry(id).activeGroup(group, incarnation);
527 return monitor;
528 }
529
530 public void unregisterGroup(ActivationGroupID id)
531 throws ActivationException, UnknownGroupException, RemoteException
532 {
533 checkShutdown();
534 RegistryImpl.checkAccess("ActivationSystem.unregisterGroup");
535
536 // remove entry before unregister so state is updated before
537 // logged
538 removeGroupEntry(id).unregisterGroup(true);
539 }
540
541 public ActivationDesc setActivationDesc(ActivationID id,
542 ActivationDesc desc)
543 throws ActivationException, UnknownObjectException, RemoteException
544 {
545 checkShutdown();
546 RegistryImpl.checkAccess("ActivationSystem.setActivationDesc");
547
548 if (!getGroupID(id).equals(desc.getGroupID())) {
549 throw new ActivationException(
550 "ActivationDesc contains wrong group");
551 }
552 return getGroupEntry(id).setActivationDesc(id, desc, true);
553 }
554
555 public ActivationGroupDesc setActivationGroupDesc(ActivationGroupID id,
556 ActivationGroupDesc desc)
557 throws ActivationException, UnknownGroupException, RemoteException
558 {
559 checkShutdown();
560 RegistryImpl.checkAccess(
561 "ActivationSystem.setActivationGroupDesc");
562
563 checkArgs(desc, null);
564 return getGroupEntry(id).setActivationGroupDesc(id, desc, true);
565 }
566
567 public ActivationDesc getActivationDesc(ActivationID id)
568 throws ActivationException, UnknownObjectException, RemoteException
569 {
570 checkShutdown();
571 RegistryImpl.checkAccess("ActivationSystem.getActivationDesc");
572
573 return getGroupEntry(id).getActivationDesc(id);
574 }
575
576 public ActivationGroupDesc getActivationGroupDesc(ActivationGroupID id)
577 throws ActivationException, UnknownGroupException, RemoteException
578 {
579 checkShutdown();
580 RegistryImpl.checkAccess
581 ("ActivationSystem.getActivationGroupDesc");
582
583 return getGroupEntry(id).desc;
584 }
585
586 /**
587 * Shutdown the activation system. Destroys all groups spawned by
588 * the activation daemon and exits the activation daemon.
589 */
590 public void shutdown() throws AccessException {
591 RegistryImpl.checkAccess("ActivationSystem.shutdown");
592
593 Object lock = startupLock;
594 if (lock != null) {
595 synchronized (lock) {
596 // nothing
597 }
598 }
599
600 synchronized (Activation.this) {
601 if (!shuttingDown) {
602 shuttingDown = true;
603 (new Shutdown()).start();
604 }
605 }
606 }
607 }
608
609 private void checkShutdown() throws ActivationException {
610 // if the startup critical section is running, wait until it
611 // completes/fails before continuing with the remote call.
|
1 /*
2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
57 import java.rmi.RemoteException;
58 import java.rmi.activation.ActivationDesc;
59 import java.rmi.activation.ActivationException;
60 import java.rmi.activation.ActivationGroupDesc;
61 import java.rmi.activation.ActivationGroup;
62 import java.rmi.activation.ActivationGroupID;
63 import java.rmi.activation.ActivationID;
64 import java.rmi.activation.ActivationInstantiator;
65 import java.rmi.activation.ActivationMonitor;
66 import java.rmi.activation.ActivationSystem;
67 import java.rmi.activation.Activator;
68 import java.rmi.activation.UnknownGroupException;
69 import java.rmi.activation.UnknownObjectException;
70 import java.rmi.registry.Registry;
71 import java.rmi.server.ObjID;
72 import java.rmi.server.RMIClassLoader;
73 import java.rmi.server.RMIClientSocketFactory;
74 import java.rmi.server.RMIServerSocketFactory;
75 import java.rmi.server.RemoteObject;
76 import java.rmi.server.RemoteServer;
77 import java.rmi.server.ServerNotActiveException;
78 import java.rmi.server.UnicastRemoteObject;
79 import java.security.AccessControlException;
80 import java.security.AccessController;
81 import java.security.AllPermission;
82 import java.security.CodeSource;
83 import java.security.Permission;
84 import java.security.PermissionCollection;
85 import java.security.Permissions;
86 import java.security.Policy;
87 import java.security.PrivilegedAction;
88 import java.security.PrivilegedActionException;
89 import java.security.PrivilegedExceptionAction;
90 import java.security.cert.Certificate;
91 import java.text.MessageFormat;
92 import java.util.ArrayList;
93 import java.util.Arrays;
94 import java.util.Date;
95 import java.util.Enumeration;
96 import java.util.HashMap;
97 import java.util.HashSet;
98 import java.util.Iterator;
99 import java.util.List;
100 import java.util.Map;
101 import java.util.MissingResourceException;
102 import java.util.Properties;
103 import java.util.ResourceBundle;
104 import java.util.Set;
105 import java.util.concurrent.ConcurrentHashMap;
106 import sun.rmi.log.LogHandler;
107 import sun.rmi.log.ReliableLog;
108 import sun.rmi.registry.RegistryImpl;
109 import sun.rmi.runtime.NewThreadAction;
110 import sun.rmi.server.UnicastServerRef;
111 import sun.rmi.transport.LiveRef;
112 import sun.rmi.transport.tcp.TCPTransport;
113 import sun.security.action.GetBooleanAction;
114 import sun.security.action.GetIntegerAction;
115 import sun.security.action.GetPropertyAction;
116 import sun.security.provider.PolicyFile;
117 import com.sun.rmi.rmid.ExecPermission;
118 import com.sun.rmi.rmid.ExecOptionPermission;
119
120 /**
121 * The Activator facilitates remote object activation. A "faulting"
122 * remote reference calls the activator's <code>activate</code> method
123 * to obtain a "live" reference to a activatable remote object. Upon
124 * receiving a request for activation, the activator looks up the
125 * activation descriptor for the activation identifier, id, determines
126 * the group in which the object should be activated and invokes the
127 * activate method on the object's activation group (described by the
128 * remote interface <code>ActivationInstantiator</code>). The
129 * activator initiates the execution of activation groups as
130 * necessary. For example, if an activation group for a specific group
131 * identifier is not already executing, the activator will spawn a
132 * child process for the activation group. <p>
168 private transient ReliableLog log;
169 /** number of updates since last snapshot */
170 private transient int numUpdates;
171
172 /** the java command */
173 // accessed by GroupEntry
174 private transient String[] command;
175 /** timeout on wait for child process to be created or destroyed */
176 private static final long groupTimeout =
177 getInt("sun.rmi.activation.groupTimeout", 60000);
178 /** take snapshot after this many updates */
179 private static final int snapshotInterval =
180 getInt("sun.rmi.activation.snapshotInterval", 200);
181 /** timeout on wait for child process to be created */
182 private static final long execTimeout =
183 getInt("sun.rmi.activation.execTimeout", 30000);
184
185 private static final Object initLock = new Object();
186 private static boolean initDone = false;
187
188 private static final InetAddress remoteClientAddress;
189 static {
190 remoteClientAddress = java.security.AccessController.doPrivileged(
191 new java.security.PrivilegedAction<InetAddress>() {
192 public InetAddress run() {
193 String remoteClientProp =
194 System.getProperty("sun.rmi.activation.remoteClient",
195 null);
196
197 if (remoteClientProp == null) {
198 return null;
199 }
200
201 try {
202 return InetAddress.getByName(remoteClientProp);
203 } catch (Throwable t) {
204 System.err.println("Activation: Cannot get the IP " +
205 "address of the remote client: " +
206 remoteClientProp);
207 }
208
209 return null;
210 }});
211 }
212
213 // this should be a *private* method since it is privileged
214 private static int getInt(String name, int def) {
215 return AccessController.doPrivileged(new GetIntegerAction(name, def));
216 }
217
218 private transient Activator activator;
219 private transient Activator activatorStub;
220 private transient ActivationSystem system;
221 private transient ActivationSystem systemStub;
222 private transient ActivationMonitor monitor;
223 private transient Registry registry;
224 private transient volatile boolean shuttingDown = false;
225 private transient volatile Object startupLock;
226 private transient Thread shutdownHook;
227
228 private static ResourceBundle resources = null;
229
230 /**
231 * Create an uninitialized instance of Activation that can be
232 * populated with log data. This is only called when the initial
233 * snapshot is taken during the first incarnation of rmid.
234 */
235 private Activation() {}
236
237 /**
238 * Check that the caller has access to this interface.
239 * <p>
240 * Use the default policy as implemented in RegistryImpl.checkAccess,
241 * unless the sun.rmi.activation.remoteClient property is set, and in
242 * that case only allow access from that host.
243 *
244 * @param op name of operation used to create a meaningful exception
245 * message, the parameter is not used to determine access
246 */
247 static void checkAccess(String op) throws AccessException {
248 if (remoteClientAddress == null) {
249 /*
250 * Note, the op arg to checkAccess is only used to build an
251 * access exception message if needed.
252 */
253 RegistryImpl.checkAccess(op);
254 return;
255 }
256
257 InetAddress clientHost;
258
259 try {
260 // Get client host that this operation was made from.
261 final String clientHostName = TCPTransport.getClientHost();
262
263 try {
264 clientHost = java.security.AccessController.doPrivileged(
265 new java.security.PrivilegedExceptionAction<InetAddress>() {
266 public InetAddress run()
267 throws java.net.UnknownHostException
268 {
269 return InetAddress.getByName(clientHostName);
270 }
271 });
272 } catch (PrivilegedActionException pae) {
273 throw new AccessException("RMI " + op + " disallowed; " +
274 clientHostName + " is an unknown client");
275 }
276 } catch (ServerNotActiveException ex) {
277 throw new AccessException("RMI " + op +
278 " is not allowed from the local host");
279 }
280
281 if (remoteClientAddress.equals(clientHost)) {
282 return;
283 }
284
285 throw new AccessException("RMI " + op + " is not allowed from " +
286 clientHost);
287 }
288
289 /**
290 * Recover activation state from the reliable log and initialize
291 * activation services.
292 */
293 private static void startActivation(int port,
294 RMIServerSocketFactory ssf,
295 String logName,
296 String[] childArgs)
297 throws Exception
298 {
299 ReliableLog log = new ReliableLog(logName, new ActLogHandler());
300 Activation state = (Activation) log.recover();
301 state.init(port, ssf, log, childArgs);
302 }
303
304 /**
305 * Initialize the Activation instantiation; start activation
306 * services.
307 */
308 private void init(int port,
309 RMIServerSocketFactory ssf,
489
490 class ActivationMonitorImpl extends UnicastRemoteObject
491 implements ActivationMonitor
492 {
493 private static final long serialVersionUID = -6214940464757948867L;
494
495 ActivationMonitorImpl(int port, RMIServerSocketFactory ssf)
496 throws RemoteException
497 {
498 super(port, null, ssf);
499 }
500
501 public void inactiveObject(ActivationID id)
502 throws UnknownObjectException, RemoteException
503 {
504 try {
505 checkShutdown();
506 } catch (ActivationException e) {
507 return;
508 }
509 Activation.checkAccess("Activator.inactiveObject");
510 getGroupEntry(id).inactiveObject(id);
511 }
512
513 public void activeObject(ActivationID id,
514 MarshalledObject<? extends Remote> mobj)
515 throws UnknownObjectException, RemoteException
516 {
517 try {
518 checkShutdown();
519 } catch (ActivationException e) {
520 return;
521 }
522 Activation.checkAccess("ActivationSystem.activeObject");
523 getGroupEntry(id).activeObject(id, mobj);
524 }
525
526 public void inactiveGroup(ActivationGroupID id,
527 long incarnation)
528 throws UnknownGroupException, RemoteException
529 {
530 try {
531 checkShutdown();
532 } catch (ActivationException e) {
533 return;
534 }
535 Activation.checkAccess("ActivationMonitor.inactiveGroup");
536 getGroupEntry(id).inactiveGroup(incarnation, false);
537 }
538 }
539
540
541 class ActivationSystemImpl
542 extends RemoteServer
543 implements ActivationSystem
544 {
545 private static final long serialVersionUID = 9100152600327688967L;
546
547 // Because ActivationSystemImpl has a fixed ObjID, it can be
548 // called by clients holding stale remote references. Each of
549 // its remote methods, then, must check startupLock (calling
550 // checkShutdown() is easiest).
551 ActivationSystemImpl(int port, RMIServerSocketFactory ssf)
552 throws RemoteException
553 {
554 /* Server ref must be created and assigned before remote object
555 * 'this' can be exported.
556 */
557 LiveRef lref = new LiveRef(new ObjID(4), port, null, ssf);
558 UnicastServerRef uref = new UnicastServerRef(lref);
559 ref = uref;
560 uref.exportObject(this, null);
561 }
562
563 public ActivationID registerObject(ActivationDesc desc)
564 throws ActivationException, UnknownGroupException, RemoteException
565 {
566 checkShutdown();
567 Activation.checkAccess("ActivationSystem.registerObject");
568
569 ActivationGroupID groupID = desc.getGroupID();
570 ActivationID id = new ActivationID(activatorStub);
571 getGroupEntry(groupID).registerObject(id, desc, true);
572 return id;
573 }
574
575 public void unregisterObject(ActivationID id)
576 throws ActivationException, UnknownObjectException, RemoteException
577 {
578 checkShutdown();
579 Activation.checkAccess("ActivationSystem.unregisterObject");
580 getGroupEntry(id).unregisterObject(id, true);
581 }
582
583 public ActivationGroupID registerGroup(ActivationGroupDesc desc)
584 throws ActivationException, RemoteException
585 {
586 checkShutdown();
587 Activation.checkAccess("ActivationSystem.registerGroup");
588 checkArgs(desc, null);
589
590 ActivationGroupID id = new ActivationGroupID(systemStub);
591 GroupEntry entry = new GroupEntry(id, desc);
592 // table insertion must take place before log update
593 groupTable.put(id, entry);
594 addLogRecord(new LogRegisterGroup(id, desc));
595 return id;
596 }
597
598 public ActivationMonitor activeGroup(ActivationGroupID id,
599 ActivationInstantiator group,
600 long incarnation)
601 throws ActivationException, UnknownGroupException, RemoteException
602 {
603 checkShutdown();
604 Activation.checkAccess("ActivationSystem.activeGroup");
605
606 getGroupEntry(id).activeGroup(group, incarnation);
607 return monitor;
608 }
609
610 public void unregisterGroup(ActivationGroupID id)
611 throws ActivationException, UnknownGroupException, RemoteException
612 {
613 checkShutdown();
614 Activation.checkAccess("ActivationSystem.unregisterGroup");
615
616 // remove entry before unregister so state is updated before
617 // logged
618 removeGroupEntry(id).unregisterGroup(true);
619 }
620
621 public ActivationDesc setActivationDesc(ActivationID id,
622 ActivationDesc desc)
623 throws ActivationException, UnknownObjectException, RemoteException
624 {
625 checkShutdown();
626 Activation.checkAccess("ActivationSystem.setActivationDesc");
627
628 if (!getGroupID(id).equals(desc.getGroupID())) {
629 throw new ActivationException(
630 "ActivationDesc contains wrong group");
631 }
632 return getGroupEntry(id).setActivationDesc(id, desc, true);
633 }
634
635 public ActivationGroupDesc setActivationGroupDesc(ActivationGroupID id,
636 ActivationGroupDesc desc)
637 throws ActivationException, UnknownGroupException, RemoteException
638 {
639 checkShutdown();
640 Activation.checkAccess(
641 "ActivationSystem.setActivationGroupDesc");
642
643 checkArgs(desc, null);
644 return getGroupEntry(id).setActivationGroupDesc(id, desc, true);
645 }
646
647 public ActivationDesc getActivationDesc(ActivationID id)
648 throws ActivationException, UnknownObjectException, RemoteException
649 {
650 checkShutdown();
651 Activation.checkAccess("ActivationSystem.getActivationDesc");
652
653 return getGroupEntry(id).getActivationDesc(id);
654 }
655
656 public ActivationGroupDesc getActivationGroupDesc(ActivationGroupID id)
657 throws ActivationException, UnknownGroupException, RemoteException
658 {
659 checkShutdown();
660 Activation.checkAccess
661 ("ActivationSystem.getActivationGroupDesc");
662
663 return getGroupEntry(id).desc;
664 }
665
666 /**
667 * Shutdown the activation system. Destroys all groups spawned by
668 * the activation daemon and exits the activation daemon.
669 */
670 public void shutdown() throws AccessException {
671 Activation.checkAccess("ActivationSystem.shutdown");
672
673 Object lock = startupLock;
674 if (lock != null) {
675 synchronized (lock) {
676 // nothing
677 }
678 }
679
680 synchronized (Activation.this) {
681 if (!shuttingDown) {
682 shuttingDown = true;
683 (new Shutdown()).start();
684 }
685 }
686 }
687 }
688
689 private void checkShutdown() throws ActivationException {
690 // if the startup critical section is running, wait until it
691 // completes/fails before continuing with the remote call.
|