1 /*
2 * Copyright (c) 1997, 2014, 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
128 * The activator is responsible for monitoring and detecting when
129 * activation groups fail so that it can remove stale remote references
130 * from its internal tables. <p>
131 *
132 * @author Ann Wollrath
133 * @since 1.2
134 */
135 public class Activation implements Serializable {
136
137 /** indicate compatibility with JDK 1.2 version of class */
138 private static final long serialVersionUID = 2921265612698155191L;
139 private static final byte MAJOR_VERSION = 1;
140 private static final byte MINOR_VERSION = 0;
141
142 /** exec policy object */
143 private static Object execPolicy;
144 private static Method execPolicyMethod;
145 private static boolean debugExec;
146
147 /** maps activation id to its respective group id */
148 private Map<ActivationID,ActivationGroupID> idTable =
149 new ConcurrentHashMap<>();
150 /** maps group id to its GroupEntry groups */
151 private Map<ActivationGroupID,GroupEntry> groupTable =
152 new ConcurrentHashMap<>();
153
154 private byte majorVersion = MAJOR_VERSION;
155 private byte minorVersion = MINOR_VERSION;
156
157 /** number of simultaneous group exec's */
158 private transient int groupSemaphore;
159 /** counter for numbering groups */
160 private transient int groupCounter;
161 /** reliable log to hold descriptor table */
162 private transient ReliableLog log;
163 /** number of updates since last snapshot */
164 private transient int numUpdates;
165
166 /** the java command */
167 // accessed by GroupEntry
168 private transient String[] command;
169 /** timeout on wait for child process to be created or destroyed */
170 private static final long groupTimeout =
280 * Previous versions used HashMap instead of ConcurrentHashMap.
281 * Replace any HashMaps found during deserialization with
282 * ConcurrentHashMaps.
283 */
284 private void readObject(ObjectInputStream ois)
285 throws IOException, ClassNotFoundException
286 {
287 ois.defaultReadObject();
288 if (! (groupTable instanceof ConcurrentHashMap)) {
289 groupTable = new ConcurrentHashMap<>(groupTable);
290 }
291 if (! (idTable instanceof ConcurrentHashMap)) {
292 idTable = new ConcurrentHashMap<>(idTable);
293 }
294 }
295
296 private static class SystemRegistryImpl extends RegistryImpl {
297
298 private static final String NAME = ActivationSystem.class.getName();
299 private static final long serialVersionUID = 4877330021609408794L;
300 private ActivationSystem systemStub = null;
301
302 SystemRegistryImpl(int port,
303 RMIClientSocketFactory csf,
304 RMIServerSocketFactory ssf,
305 ActivationSystem systemStub)
306 throws RemoteException
307 {
308 super(port, csf, ssf);
309 assert systemStub != null;
310 synchronized (this) {
311 this.systemStub = systemStub;
312 notifyAll();
313 }
314 }
315
316 /**
317 * Waits for systemStub to be initialized and returns its
318 * initialized value. Any remote call that uses systemStub must
319 * call this method to get it instead of using direct field
481 throws UnknownGroupException, RemoteException
482 {
483 try {
484 checkShutdown();
485 } catch (ActivationException e) {
486 return;
487 }
488 RegistryImpl.checkAccess("ActivationMonitor.inactiveGroup");
489 getGroupEntry(id).inactiveGroup(incarnation, false);
490 }
491 }
492
493
494 /**
495 * SameHostOnlyServerRef checks that access is from a local client
496 * before the parameters are deserialized. The unmarshalCustomCallData
497 * hook is used to check the network address of the caller
498 * with RegistryImpl.checkAccess().
499 * The kind of access is retained for an exception if one is thrown.
500 */
501 static class SameHostOnlyServerRef extends UnicastServerRef {
502 private static final long serialVersionUID = 1234L;
503 private String accessKind; // an exception message
504
505 /**
506 * Construct a new SameHostOnlyServerRef from a LiveRef.
507 * @param lref a LiveRef
508 */
509 SameHostOnlyServerRef(LiveRef lref, String accessKind) {
510 super(lref);
511 this.accessKind = accessKind;
512 }
513
514 @Override
515 protected void unmarshalCustomCallData(ObjectInput in) throws IOException, ClassNotFoundException {
516 RegistryImpl.checkAccess(accessKind);
517 super.unmarshalCustomCallData(in);
518 }
519 }
520
856 *
857 * WARNING: GroupEntry objects should not be written into log file
858 * updates. GroupEntrys are inner classes of Activation and they
859 * can not be serialized independent of this class. If the
860 * complete Activation system is written out as a log update, the
861 * point of having updates is nullified.
862 */
863 private class GroupEntry implements Serializable {
864
865 /** indicate compatibility with JDK 1.2 version of class */
866 private static final long serialVersionUID = 7222464070032993304L;
867 private static final int MAX_TRIES = 2;
868 private static final int NORMAL = 0;
869 private static final int CREATING = 1;
870 private static final int TERMINATE = 2;
871 private static final int TERMINATING = 3;
872
873 ActivationGroupDesc desc = null;
874 ActivationGroupID groupID = null;
875 long incarnation = 0;
876 Map<ActivationID,ObjectEntry> objects = new HashMap<>();
877 Set<ActivationID> restartSet = new HashSet<>();
878
879 transient ActivationInstantiator group = null;
880 transient int status = NORMAL;
881 transient long waitTime = 0;
882 transient String groupName = null;
883 transient Process child = null;
884 transient boolean removed = false;
885 transient Watchdog watchdog = null;
886
887 GroupEntry(ActivationGroupID groupID, ActivationGroupDesc desc) {
888 this.groupID = groupID;
889 this.desc = desc;
890 }
891
892 void restartServices() {
893 Iterator<ActivationID> iter = null;
894
895 synchronized (this) {
896 if (restartSet.isEmpty()) {
|
1 /*
2 * Copyright (c) 1997, 2019, 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
128 * The activator is responsible for monitoring and detecting when
129 * activation groups fail so that it can remove stale remote references
130 * from its internal tables. <p>
131 *
132 * @author Ann Wollrath
133 * @since 1.2
134 */
135 public class Activation implements Serializable {
136
137 /** indicate compatibility with JDK 1.2 version of class */
138 private static final long serialVersionUID = 2921265612698155191L;
139 private static final byte MAJOR_VERSION = 1;
140 private static final byte MINOR_VERSION = 0;
141
142 /** exec policy object */
143 private static Object execPolicy;
144 private static Method execPolicyMethod;
145 private static boolean debugExec;
146
147 /** maps activation id to its respective group id */
148 @SuppressWarnings("serial") // Conditionally serializable
149 private Map<ActivationID,ActivationGroupID> idTable =
150 new ConcurrentHashMap<>();
151 /** maps group id to its GroupEntry groups */
152 @SuppressWarnings("serial") // Conditionally serializable
153 private Map<ActivationGroupID,GroupEntry> groupTable =
154 new ConcurrentHashMap<>();
155
156 private byte majorVersion = MAJOR_VERSION;
157 private byte minorVersion = MINOR_VERSION;
158
159 /** number of simultaneous group exec's */
160 private transient int groupSemaphore;
161 /** counter for numbering groups */
162 private transient int groupCounter;
163 /** reliable log to hold descriptor table */
164 private transient ReliableLog log;
165 /** number of updates since last snapshot */
166 private transient int numUpdates;
167
168 /** the java command */
169 // accessed by GroupEntry
170 private transient String[] command;
171 /** timeout on wait for child process to be created or destroyed */
172 private static final long groupTimeout =
282 * Previous versions used HashMap instead of ConcurrentHashMap.
283 * Replace any HashMaps found during deserialization with
284 * ConcurrentHashMaps.
285 */
286 private void readObject(ObjectInputStream ois)
287 throws IOException, ClassNotFoundException
288 {
289 ois.defaultReadObject();
290 if (! (groupTable instanceof ConcurrentHashMap)) {
291 groupTable = new ConcurrentHashMap<>(groupTable);
292 }
293 if (! (idTable instanceof ConcurrentHashMap)) {
294 idTable = new ConcurrentHashMap<>(idTable);
295 }
296 }
297
298 private static class SystemRegistryImpl extends RegistryImpl {
299
300 private static final String NAME = ActivationSystem.class.getName();
301 private static final long serialVersionUID = 4877330021609408794L;
302 @SuppressWarnings("serial") // Not statically typed as Serializable
303 private ActivationSystem systemStub = null;
304
305 SystemRegistryImpl(int port,
306 RMIClientSocketFactory csf,
307 RMIServerSocketFactory ssf,
308 ActivationSystem systemStub)
309 throws RemoteException
310 {
311 super(port, csf, ssf);
312 assert systemStub != null;
313 synchronized (this) {
314 this.systemStub = systemStub;
315 notifyAll();
316 }
317 }
318
319 /**
320 * Waits for systemStub to be initialized and returns its
321 * initialized value. Any remote call that uses systemStub must
322 * call this method to get it instead of using direct field
484 throws UnknownGroupException, RemoteException
485 {
486 try {
487 checkShutdown();
488 } catch (ActivationException e) {
489 return;
490 }
491 RegistryImpl.checkAccess("ActivationMonitor.inactiveGroup");
492 getGroupEntry(id).inactiveGroup(incarnation, false);
493 }
494 }
495
496
497 /**
498 * SameHostOnlyServerRef checks that access is from a local client
499 * before the parameters are deserialized. The unmarshalCustomCallData
500 * hook is used to check the network address of the caller
501 * with RegistryImpl.checkAccess().
502 * The kind of access is retained for an exception if one is thrown.
503 */
504 @SuppressWarnings("serial") // Externalizable class w/o no-arg c'tor
505 static class SameHostOnlyServerRef extends UnicastServerRef {
506 private static final long serialVersionUID = 1234L;
507 private String accessKind; // an exception message
508
509 /**
510 * Construct a new SameHostOnlyServerRef from a LiveRef.
511 * @param lref a LiveRef
512 */
513 SameHostOnlyServerRef(LiveRef lref, String accessKind) {
514 super(lref);
515 this.accessKind = accessKind;
516 }
517
518 @Override
519 protected void unmarshalCustomCallData(ObjectInput in) throws IOException, ClassNotFoundException {
520 RegistryImpl.checkAccess(accessKind);
521 super.unmarshalCustomCallData(in);
522 }
523 }
524
860 *
861 * WARNING: GroupEntry objects should not be written into log file
862 * updates. GroupEntrys are inner classes of Activation and they
863 * can not be serialized independent of this class. If the
864 * complete Activation system is written out as a log update, the
865 * point of having updates is nullified.
866 */
867 private class GroupEntry implements Serializable {
868
869 /** indicate compatibility with JDK 1.2 version of class */
870 private static final long serialVersionUID = 7222464070032993304L;
871 private static final int MAX_TRIES = 2;
872 private static final int NORMAL = 0;
873 private static final int CREATING = 1;
874 private static final int TERMINATE = 2;
875 private static final int TERMINATING = 3;
876
877 ActivationGroupDesc desc = null;
878 ActivationGroupID groupID = null;
879 long incarnation = 0;
880 @SuppressWarnings("serial") // Conditionally serializable
881 Map<ActivationID,ObjectEntry> objects = new HashMap<>();
882 @SuppressWarnings("serial") // Conditionally serializable
883 Set<ActivationID> restartSet = new HashSet<>();
884
885 transient ActivationInstantiator group = null;
886 transient int status = NORMAL;
887 transient long waitTime = 0;
888 transient String groupName = null;
889 transient Process child = null;
890 transient boolean removed = false;
891 transient Watchdog watchdog = null;
892
893 GroupEntry(ActivationGroupID groupID, ActivationGroupDesc desc) {
894 this.groupID = groupID;
895 this.desc = desc;
896 }
897
898 void restartServices() {
899 Iterator<ActivationID> iter = null;
900
901 synchronized (this) {
902 if (restartSet.isEmpty()) {
|