0001: /*
0002: * Licensed to the Apache Software Foundation (ASF) under one or more
0003: * contributor license agreements. See the NOTICE file distributed with
0004: * this work for additional information regarding copyright ownership.
0005: * The ASF licenses this file to You under the Apache License, Version 2.0
0006: * (the "License"); you may not use this file except in compliance with
0007: * the License. You may obtain a copy of the License at
0008: *
0009: * http://www.apache.org/licenses/LICENSE-2.0
0010: *
0011: * Unless required by applicable law or agreed to in writing, software
0012: * distributed under the License is distributed on an "AS IS" BASIS,
0013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014: *
0015: * See the License for the specific language governing permissions and
0016: * limitations under the License.
0017: */
0018:
0019: /**
0020: * @author Victor A. Martynov
0021: * @version $Revision: 1.1.2.8 $
0022: */package org.apache.harmony.rmi.activation;
0023:
0024: import java.io.BufferedOutputStream;
0025: import java.io.EOFException;
0026: import java.io.File;
0027: import java.io.FileInputStream;
0028: import java.io.FileOutputStream;
0029: import java.io.IOException;
0030: import java.io.InputStream;
0031: import java.io.ObjectInputStream;
0032: import java.io.ObjectOutputStream;
0033: import java.io.OutputStream;
0034: import java.io.Serializable;
0035:
0036: import java.rmi.ConnectException;
0037: import java.rmi.ConnectIOException;
0038: import java.rmi.MarshalException;
0039: import java.rmi.MarshalledObject;
0040: import java.rmi.Naming;
0041: import java.rmi.RMISecurityManager;
0042: import java.rmi.Remote;
0043: import java.rmi.RemoteException;
0044: import java.rmi.activation.ActivationDesc;
0045: import java.rmi.activation.ActivationException;
0046: import java.rmi.activation.ActivationGroup;
0047: import java.rmi.activation.ActivationGroupDesc;
0048: import java.rmi.activation.ActivationGroupID;
0049: import java.rmi.activation.ActivationID;
0050: import java.rmi.activation.ActivationInstantiator;
0051: import java.rmi.activation.ActivationMonitor;
0052: import java.rmi.activation.ActivationSystem;
0053: import java.rmi.activation.Activator;
0054: import java.rmi.activation.UnknownGroupException;
0055: import java.rmi.activation.UnknownObjectException;
0056: import java.rmi.activation.ActivationGroupDesc.CommandEnvironment;
0057: import java.rmi.registry.LocateRegistry;
0058: import java.rmi.registry.Registry;
0059: import java.rmi.server.ObjID;
0060: import java.rmi.server.RemoteObject;
0061: import java.rmi.server.RemoteServer;
0062: import java.rmi.server.RemoteStub;
0063:
0064: import java.security.AccessController;
0065: import java.security.PrivilegedAction;
0066: import java.security.PrivilegedExceptionAction;
0067:
0068: import java.util.ArrayList;
0069: import java.util.Arrays;
0070: import java.util.Enumeration;
0071: import java.util.Hashtable;
0072: import java.util.logging.Level;
0073:
0074: import org.apache.harmony.rmi.common.GetBooleanPropAction;
0075: import org.apache.harmony.rmi.common.GetLongPropAction;
0076: import org.apache.harmony.rmi.common.GetStringPropAction;
0077: import org.apache.harmony.rmi.common.RMIConstants;
0078: import org.apache.harmony.rmi.common.RMILog;
0079: import org.apache.harmony.rmi.common.RMIProperties;
0080: import org.apache.harmony.rmi.internal.nls.Messages;
0081: import org.apache.harmony.rmi.remoteref.UnicastServerRef;
0082: import org.apache.harmony.rmi.server.ExportManager;
0083: import org.apache.harmony.rmi.transport.RMIObjectOutputStream;
0084:
0085: /**
0086: * Represents rmid - RMI Activation Daemon. Implements
0087: * all 3 remote interfaces that are essential for Activation:
0088: * <code>ActivationSystem</code>, <code>ActivationMonitor</code>
0089: * and <code>Activator</code>. This is done to avoid
0090: * the multiplication of references pointing to Hashtables that keep
0091: * information about ActivationGroupIDs and ActivationIDs and their
0092: * mappings to ActivationGroupDescriptors and ActivationDescriptors.
0093: *
0094: * RMID is partially crash proof, which means it saves its state into two
0095: * files: snapshot.rmid and delta.rmid. snapshot.rmid contains the
0096: * snapshot of the structure that contains information about Activation
0097: * Groups and Activatable Objects registered in this RMID and delta.rmid
0098: * reflects the changes occurred since last snapshot.
0099: *
0100: * The objects that are saved in Snapshot:
0101: * <UL>
0102: * <LI>ActivationID: UID uid, String refType, UnicastRef2 RemoteRef</LI>
0103: * <LI>ActivationDesc: ActivationGroupID groupID, String className, String
0104: * location, MarshalledObject data, boolean restart</LI>
0105: * <LI>ActivationGroupID: ActivationSystem system, UID uid</LI>
0106: * <LI>ActivationGroupDesc: String className, String location,
0107: * MarshalledObject data, ActivationGroupDesc.CommandEnvironment env,
0108: * Properties props</LI>
0109: * </UL>
0110: *
0111: * @author Victor A. Martynov
0112: * @version $Revision: 1.1.2.8 $
0113: */
0114: public class Rmid extends RemoteServer implements ActivationSystem,
0115: ActivationMonitor, Activator, RmidMBean {
0116:
0117: private static final long serialVersionUID = -4936383024184263236L;
0118:
0119: /**
0120: * Standard logger for RMI Activation.
0121: *
0122: * @see org.apache.harmony.rmi.common.RMILog#getActivationLog()
0123: */
0124: private static RMILog rLog = RMILog.getActivationLog();
0125:
0126: /**
0127: * Internal registry in which the Activation System is registered.
0128: */
0129: private static Registry internalRegistry = null;
0130:
0131: /**
0132: * Port for internal registry.
0133: *
0134: * @see java.rmi.activation.ActivationSystem#SYSTEM_PORT
0135: */
0136: private static int port = ActivationSystem.SYSTEM_PORT;
0137:
0138: /**
0139: * The stub for <code>this </code> object.
0140: */
0141: private Remote this Stub;
0142:
0143: /**
0144: * Indicates whether this instance of RMID should start monitor.
0145: */
0146: private static boolean startMonitor = false;
0147:
0148: /**
0149: * The instance of RmidMonitor of this Rmid.
0150: */
0151: private static RmidMonitor rmidMonitor = null;
0152:
0153: /**
0154: * Mapping from ActivationID to its ActivationGroupID.
0155: */
0156: public static Hashtable groupIDByActivationID;
0157:
0158: /**
0159: * Mapping from ActivationGroupID to ActivationGroupInfo.
0160: */
0161: static Hashtable groupInfoByGroupId;
0162:
0163: /**
0164: * The timeout that is given to the ActivationGroup VM to
0165: * start(milliseconds).
0166: *
0167: * @see org.apache.harmony.rmi.common.RMIConstants#DEFAULT_ACTIVATION_EXECTIMEOUT
0168: * @see org.apache.harmony.rmi.common.RMIProperties#ACTIVATION_EXECTIMEOUT_PROP
0169: */
0170: private static long groupStartTimeout = RMIConstants.DEFAULT_ACTIVATION_EXECTIMEOUT;
0171:
0172: /**
0173: * Represents the interval between the snapshots of the RMID
0174: * current state.
0175: *
0176: * @see org.apache.harmony.rmi.common.RMIConstants#DEFAULT_SNAPSHOTINTERVAL
0177: * @see org.apache.harmony.rmi.common.RMIProperties#ACTIVATION_SNAPSHOTINTERVAL_PROP
0178: */
0179: private static long snapshotInterval = RMIConstants.DEFAULT_SNAPSHOTINTERVAL;
0180:
0181: /**
0182: * Indicates whether the debug information about logging - snapshots and
0183: * deltas of the RMID state - should be printed.
0184: *
0185: * @see org.apache.harmony.rmi.common.RMIProperties#ACTIVATION_LOG_DEBUG_PROP
0186: */
0187: private static boolean loggingDebug = false;
0188:
0189: /**
0190: * The maximum amount of activation groups(VMs).
0191: *
0192: * @see org.apache.harmony.rmi.common.RMIConstants#MAX_CONCURRENT_STARTING_GROUPS
0193: * @see org.apache.harmony.rmi.common.RMIProperties#MAXSTARTGROUP_PROP
0194: */
0195: private static long maxConcurrentStartingGroups = RMIConstants.MAX_CONCURRENT_STARTING_GROUPS;
0196:
0197: /**
0198: * Indicates whether common activation debug information should be printed.
0199: * @see org.apache.harmony.rmi.common.RMIProperties#ACTIVATION_DEBUGEXEC_PROP
0200: */
0201: private static boolean activationDebug;
0202:
0203: /**
0204: * Arguments passed to every activation group VM of this Activation System.
0205: * These arguments are passed in the RMID command line using "-C" option.
0206: */
0207: private static String[] groupArgs = null;
0208:
0209: /**
0210: * Represents the amount of deltas that
0211: * happened after last snapshot. When this value exceeds
0212: * snapshotInterval the snapshot is made and this
0213: * variable is reset to 0.
0214: */
0215: private static int deltasCounter = 0;
0216:
0217: /**
0218: * The flag that indicates that the RMID is in restore phase. No
0219: * changes that are made to the RMID database during this flag is set
0220: * are recorded in DELTA_FILE.
0221: */
0222: private static boolean restoreLock = false;
0223:
0224: /**
0225: * This variable represents the amount of groups that can be started
0226: * immediately. The initial value of this variable is
0227: * maxConcurrentStartingGroups and when a process of group start is
0228: * initiated this value is decremented. As soon as group finishes its
0229: * starting procedures the value is increased.
0230: */
0231: private static long startingGroups = maxConcurrentStartingGroups;
0232:
0233: /**
0234: * The log level of RMID persistence state activities.
0235: */
0236: private static Level persistenceDebugLevel = RMILog.SILENT;
0237:
0238: /**
0239: * The log level of the general debugging information.
0240: */
0241: public static Level commonDebugLevel = RMILog.SILENT;
0242:
0243: /**
0244: * The folder to hold RMID logging information: snapshot and delta files.
0245: *
0246: * @see org.apache.harmony.rmi.common.RMIConstants#DEFAULT_LOG_FOLDER
0247: */
0248: private static String logFolder = RMIConstants.DEFAULT_LOG_FOLDER;
0249:
0250: private class Lock {
0251: }
0252:
0253: private Object lock = new Lock();
0254:
0255: /**
0256: * The name of the monitor class for RMID.
0257: *
0258: * @see RmidMonitor
0259: * @see org.apache.harmony.rmi.common.RMIConstants#DEFAULT_ACTIVATION_MONITOR_CLASS_NAME
0260: * @see org.apache.harmony.rmi.common.RMIProperties#ACTIVATION_MONITOR_CLASS_NAME_PROP
0261: */
0262: static String monitorClassName;
0263:
0264: /**
0265: * Initializes activation system. Called in {@link #main(String[]) main}.
0266: */
0267: private Rmid(int port) {
0268: try {
0269: /*
0270: * The process of starting RMID should not be interrupted by any
0271: * incoming calls so we put this whole process into synchronized
0272: * block on the global lock object.
0273: */
0274: synchronized (lock) {
0275: internalRegistry = LocateRegistry.createRegistry(port);
0276: // rmi.log.38=Registry created: {0}
0277: rLog.log(commonDebugLevel, Messages.getString(
0278: "rmi.log.38", //$NON-NLS-1$
0279: internalRegistry));
0280: // rmi.log.39=Creating Activation System on port {0}.
0281: rLog.log(commonDebugLevel, Messages.getString(
0282: "rmi.log.39", //$NON-NLS-1$
0283: port));
0284:
0285: UnicastServerRef usr = new UnicastServerRef(port, null,
0286: null, new ObjID(
0287: RMIConstants.ACTIVATION_SYSTEM_ID));
0288:
0289: this Stub = ExportManager.exportObject(this , usr, false);
0290: // rmi.log.3A=stub's ref = {0}
0291: rLog.log(commonDebugLevel, Messages.getString(
0292: "rmi.log.3A", //$NON-NLS-1$
0293: ((RemoteObject) this Stub).getRef()));
0294: this .ref = ((RemoteStub) this Stub).getRef();
0295:
0296: String activationSystemURL = "rmi://:" + port //$NON-NLS-1$
0297: + "/java.rmi.activation.ActivationSystem"; //$NON-NLS-1$
0298: // rmi.log.3B=URL = {0}
0299: rLog.log(commonDebugLevel, Messages.getString(
0300: "rmi.log.3B", activationSystemURL)); //$NON-NLS-1$
0301: // rmi.log.3C=Stub = {0}
0302: rLog.log(commonDebugLevel, Messages.getString(
0303: "rmi.log.3C", this Stub)); //$NON-NLS-1$
0304: Naming.rebind(activationSystemURL, this Stub);
0305: // rmi.log.3D=Rebind was successful.
0306: rLog.log(commonDebugLevel, Messages
0307: .getString("rmi.log.3D")); //$NON-NLS-1$
0308:
0309: groupIDByActivationID = new Hashtable();
0310: groupInfoByGroupId = new Hashtable();
0311:
0312: if (startMonitor) {
0313: rmidMonitor = RmidMonitorFactory
0314: .getRmidMonitor(monitorClassName);
0315: // rmi.log.3E=RmidMonitor created: {0}
0316: rLog.log(commonDebugLevel, Messages.getString(
0317: "rmi.log.3E", //$NON-NLS-1$
0318: rmidMonitor));
0319: /*
0320: * Failed to obtain RmidMonitor.
0321: */
0322: if (rmidMonitor == null) {
0323: startMonitor = false;
0324: }
0325: }
0326:
0327: restore();
0328: }
0329: } catch (Throwable t) {
0330: // rmi.log.3F=Exception in RMID: {0}
0331: rLog.log(commonDebugLevel, Messages.getString(
0332: "rmi.log.3F", t)); //$NON-NLS-1$
0333: t.printStackTrace();
0334: System.exit(1);
0335: }
0336: }
0337:
0338: /**
0339: * Waits until the startup procedure of RMID is completed.
0340: */
0341: private void waitStartup() {
0342: synchronized (lock) {
0343: //This block was intentionally left empty.
0344: }
0345: }
0346:
0347: /**
0348: * Main method to start activation system.
0349: *
0350: * @see RMIConstants#RMID_USAGE
0351: */
0352: public static void main(String args[]) {
0353:
0354: /* Setting the security manager. */
0355: if (System.getSecurityManager() == null) {
0356: System.setSecurityManager(new RMISecurityManager());
0357: }
0358:
0359: /*
0360: * Reading properties.
0361: */
0362: groupStartTimeout = ((Long) AccessController
0363: .doPrivileged(new GetLongPropAction(
0364: RMIProperties.ACTIVATION_EXECTIMEOUT_PROP,
0365: groupStartTimeout))).longValue();
0366: snapshotInterval = ((Long) AccessController
0367: .doPrivileged(new GetLongPropAction(
0368: RMIProperties.ACTIVATION_SNAPSHOTINTERVAL_PROP,
0369: snapshotInterval))).longValue();
0370: loggingDebug = ((Boolean) AccessController
0371: .doPrivileged(new GetBooleanPropAction(
0372: RMIProperties.ACTIVATION_LOG_DEBUG_PROP,
0373: loggingDebug))).booleanValue();
0374: maxConcurrentStartingGroups = ((Long) AccessController
0375: .doPrivileged(new GetLongPropAction(
0376: RMIProperties.MAXSTARTGROUP_PROP,
0377: maxConcurrentStartingGroups))).longValue();
0378: activationDebug = ((Boolean) AccessController
0379: .doPrivileged(new GetBooleanPropAction(
0380: RMIProperties.ACTIVATION_DEBUGEXEC_PROP, false)))
0381: .booleanValue();
0382: monitorClassName = (String) AccessController
0383: .doPrivileged(new GetStringPropAction(
0384: RMIProperties.ACTIVATION_MONITOR_CLASS_NAME_PROP,
0385: RMIConstants.DEFAULT_ACTIVATION_MONITOR_CLASS_NAME));
0386:
0387: if (loggingDebug) {
0388: persistenceDebugLevel = RMILog.VERBOSE;
0389: }
0390:
0391: if (activationDebug) {
0392: commonDebugLevel = RMILog.VERBOSE;
0393: }
0394: // rmi.log.40=\nThe following properties were set on RMID:
0395: rLog
0396: .log(
0397: commonDebugLevel,
0398: Messages.getString("rmi.log.40") + "\n" //$NON-NLS-1$ //$NON-NLS-2$
0399: + RMIProperties.ACTIVATION_EXECTIMEOUT_PROP
0400: + " = " + groupStartTimeout + "\n" //$NON-NLS-1$ //$NON-NLS-2$
0401: + RMIProperties.ACTIVATION_SNAPSHOTINTERVAL_PROP
0402: + " = " + snapshotInterval + "\n" //$NON-NLS-1$ //$NON-NLS-2$
0403: + RMIProperties.ACTIVATION_LOG_DEBUG_PROP
0404: + " = " //$NON-NLS-1$
0405: + loggingDebug
0406: + "\n" //$NON-NLS-1$
0407: + RMIProperties.MAXSTARTGROUP_PROP
0408: + " = " //$NON-NLS-1$
0409: + maxConcurrentStartingGroups
0410: + "\n" //$NON-NLS-1$
0411: + RMIProperties.ACTIVATION_DEBUGEXEC_PROP
0412: + " = " //$NON-NLS-1$
0413: + activationDebug
0414: + "\n" //$NON-NLS-1$
0415: + RMIProperties.ACTIVATION_MONITOR_CLASS_NAME_PROP
0416: + " = " + monitorClassName); //$NON-NLS-1$
0417:
0418: /*
0419: * The ArrayList for temporary holding of "-C" options.
0420: */
0421: ArrayList tmpGroupArgs = new ArrayList();
0422:
0423: /*
0424: * Parsing command line arguments.
0425: */
0426: for (int i = 0; i < args.length; i++) {
0427:
0428: String argument = args[i];
0429:
0430: if (argument.equals("-port")) { //$NON-NLS-1$
0431: if (i + 1 >= args.length) {
0432: // rmi.console.02=Insufficient arguments: port should be specified.
0433: System.out.println(Messages
0434: .getString("rmi.console.02")); //$NON-NLS-1$
0435: printUsage();
0436: System.exit(1);
0437: }
0438:
0439: try {
0440: port = Integer.parseInt(args[i + 1]);
0441: } catch (NumberFormatException nfe) {
0442: // rmi.console.03=Malformed port number.
0443: System.out.println(Messages
0444: .getString("rmi.console.03")); //$NON-NLS-1$
0445: printUsage();
0446: System.exit(1);
0447: }
0448: i++;
0449: } else if (argument.equals("-log")) { //$NON-NLS-1$
0450: if (i + 1 >= args.length) {
0451: // rmi.console.04=Insufficient arguments: log folder should be specified.
0452: System.out.println(Messages
0453: .getString("rmi.console.04")); //$NON-NLS-1$
0454: printUsage();
0455: System.exit(1);
0456: }
0457: logFolder = args[i + 1];
0458: i++;
0459: } else if (argument.equals("-stop")) { //$NON-NLS-1$
0460: try {
0461: ActivationSystem system = ActivationGroup
0462: .getSystem();
0463: system.shutdown();
0464: // rmi.log.41=RMID was shut down
0465: rLog.log(commonDebugLevel, Messages
0466: .getString("rmi.log.41")); //$NON-NLS-1$
0467: return;
0468: } catch (Throwable t) {
0469: t.printStackTrace();
0470: System.exit(1);
0471: }
0472: } else if (argument.equals("-C")) { //$NON-NLS-1$
0473: tmpGroupArgs.add(args[i].substring(2));
0474: } else if (argument.equals("-help")) { //$NON-NLS-1$
0475: printUsage();
0476: return;
0477: } else if (argument.equals("-monitor")) { //$NON-NLS-1$
0478: // rmi.log.42=Monitor option selected.
0479: rLog.log(commonDebugLevel, Messages
0480: .getString("rmi.log.42")); //$NON-NLS-1$
0481: startMonitor = true;
0482: } else {
0483: /*
0484: * Illegal option found.
0485: */
0486: // rmi.console.05=Illegal option: {0}
0487: System.out.println(Messages.getString(
0488: "rmi.console.05", argument)); //$NON-NLS-1$
0489: printUsage();
0490: System.exit(1);
0491: }
0492: }
0493:
0494: /*
0495: * Extracting collected "-C" options from ArrayList.
0496: */
0497: groupArgs = (String[]) tmpGroupArgs
0498: .toArray(new String[tmpGroupArgs.size()]);
0499:
0500: /*
0501: * Adding separator at the end of log folder.
0502: */
0503: if (!logFolder.endsWith(File.separator)) {
0504: logFolder = logFolder + File.separator;
0505: }
0506:
0507: final File dir = new File(logFolder);
0508:
0509: /*
0510: * Creating log folder.
0511: */
0512: AccessController.doPrivileged(new PrivilegedAction() {
0513: public Object run() {
0514: if (!dir.exists() && !dir.mkdir()) {
0515: //rmi.console.06=Cannot create log folder: {0}
0516: System.out.println(Messages.getString(
0517: "rmi.console.06", //$NON-NLS-1$
0518: logFolder));
0519: System.exit(1);
0520: }
0521: return null;
0522: }
0523: });
0524:
0525: try {
0526: Rmid rmid = new Rmid(port);
0527:
0528: // rmi.log.43=RMID instance created: {0}
0529: rLog.log(commonDebugLevel, Messages.getString(
0530: "rmi.log.43", rmid)); //$NON-NLS-1$
0531: Thread.sleep(Long.MAX_VALUE);
0532: } catch (Throwable t) {
0533: // rmi.log.44=Exception: {0}
0534: rLog.log(commonDebugLevel, Messages.getString(
0535: "rmi.log.44", t)); //$NON-NLS-1$
0536: t.printStackTrace();
0537: System.exit(1);
0538: }
0539: }
0540:
0541: /**
0542: * Prints the usage syntax for RMID.
0543: */
0544: private static void printUsage() {
0545: System.out.println(RMIConstants.RMID_USAGE);
0546: }
0547:
0548: /* *********************************************************************
0549: *
0550: * Next methods belong to ActivationSystem remote interface.
0551: *
0552: *********************************************************************/
0553:
0554: public ActivationGroupID registerGroup(ActivationGroupDesc agdesc)
0555: throws ActivationException {
0556: waitStartup();
0557: ActivationGroupID agid = new ActivationGroupID(this );
0558: ActivationGroupInfo agi = new ActivationGroupInfo(agid, agdesc);
0559: if (groupInfoByGroupId.containsKey(agid)) {
0560: // rmi.2E=This group is already registered.
0561: throw new ActivationException(Messages.getString("rmi.2E")); //$NON-NLS-1$
0562: }
0563: groupInfoByGroupId.put(agid, agi);
0564: if (!restoreLock) {
0565: writeDelta(Delta.PUT, "group", agid, agdesc); //$NON-NLS-1$
0566: // rmi.log.45=Delta was saved:
0567: rLog.log(persistenceDebugLevel, Messages
0568: .getString("rmi.log.45") //$NON-NLS-1$
0569: + Delta.PUT + "," + "group" + ", " + agid + ", " //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
0570: + agdesc);
0571: }
0572:
0573: return agid;
0574: }
0575:
0576: public ActivationMonitor activeGroup(ActivationGroupID gID,
0577: ActivationInstantiator group, long incarnation)
0578: throws UnknownGroupException, ActivationException {
0579: waitStartup();
0580: // rmi.log.46=Rmid.activeGroup: {0}, {1}, {2}
0581: rLog.log(commonDebugLevel, Messages.getString("rmi.log.46", //$NON-NLS-1$
0582: new Object[] { gID, group, incarnation }));
0583: // rmi.log.47=groupID2groupInfo_H = {0}
0584: rLog.log(commonDebugLevel, Messages.getString("rmi.log.47", //$NON-NLS-1$
0585: groupInfoByGroupId));
0586:
0587: ActivationGroupInfo agi = (ActivationGroupInfo) groupInfoByGroupId
0588: .get(gID);
0589: // rmi.log.48=Rmid.activeGroup group info = {0}
0590: rLog.log(commonDebugLevel, Messages
0591: .getString("rmi.log.48", agi));//$NON-NLS-1$
0592:
0593: if (agi == null) {
0594: // rmi.2F=Group is not registered: {0}
0595: throw new UnknownGroupException(Messages.getString(
0596: "rmi.2F", gID)); //$NON-NLS-1$
0597: } else if (agi.isActive()) {
0598: // rmi.30=Group is already active: {0}
0599: throw new ActivationException(Messages.getString(
0600: "rmi.30", gID)); //$NON-NLS-1$
0601: }
0602:
0603: // rmi.log.49=ready to execute agi.active()
0604: rLog.log(commonDebugLevel, Messages.getString("rmi.log.49")); //$NON-NLS-1$
0605:
0606: agi.active(group, incarnation);
0607: // rmi.log.4A=Rmid.activeGroup finished.
0608: rLog.log(commonDebugLevel, Messages.getString("rmi.log.4A")); //$NON-NLS-1$
0609:
0610: return this ;
0611: }
0612:
0613: /**
0614: * This method is absent in Java Remote Method Invocation
0615: * specification.
0616: *
0617: * @param aID
0618: * @throws UnknownObjectException if <code>ActivationID</code>
0619: * is not registered
0620: * @throws ActivationException for general failure
0621: * @throws RemoteException if remote call fails
0622: */
0623: public ActivationDesc getActivationDesc(ActivationID aID)
0624: throws UnknownObjectException {
0625: waitStartup();
0626: ActivationGroupID agid = (ActivationGroupID) groupIDByActivationID
0627: .get(aID);
0628: ActivationGroupInfo info = (ActivationGroupInfo) groupInfoByGroupId
0629: .get(agid);
0630: ActivationDesc adesc = info.getActivationDesc(aID);
0631:
0632: if (adesc == null) {
0633: // rmi.31=No ActivationDesc for ActivationID {0}
0634: throw new UnknownObjectException(Messages.getString(
0635: "rmi.31", aID)); //$NON-NLS-1$
0636: }
0637: return adesc;
0638: }
0639:
0640: /**
0641: * This method is absent in Java Remote Method Invocation
0642: * specification.
0643: *
0644: * @throws UnknownGroupException - if agid is not registered
0645: * @throws ActivationException - for general failure
0646: * @throws RemoteException - if remote call fails
0647: */
0648: public ActivationGroupDesc getActivationGroupDesc(
0649: ActivationGroupID agid) throws UnknownObjectException {
0650: waitStartup();
0651: ActivationGroupInfo agi = (ActivationGroupInfo) groupInfoByGroupId
0652: .get(agid);
0653: if (agi == null) {
0654: // rmi.32=No ActivationGroupDesc for ActivationGroupID {0}
0655: throw new UnknownObjectException(Messages.getString(
0656: "rmi.32", agid)); //$NON-NLS-1$
0657: }
0658: return agi.getActivationGroupDesc();
0659: }
0660:
0661: public ActivationID registerObject(ActivationDesc adesc) {
0662: waitStartup();
0663: // rmi.log.4B=ActivationSystemImpl.registerObject():
0664: rLog.log(commonDebugLevel, Messages.getString("rmi.log.4B")); //$NON-NLS-1$
0665: ActivationGroupID agid = adesc.getGroupID();
0666: // rmi.log.4C=agid : {0}
0667: rLog.log(commonDebugLevel, Messages.getString(
0668: "rmi.log.4C", agid)); //$NON-NLS-1$
0669: // rmi.log.4D=Activator stub = {0}
0670: rLog.log(commonDebugLevel, Messages.getString(
0671: "rmi.log.4D", this Stub)); //$NON-NLS-1$
0672: ActivationID aid = new ActivationID((Activator) this Stub);
0673: // rmi.log.4E=aid : {0}
0674: rLog.log(commonDebugLevel, Messages
0675: .getString("rmi.log.4E", aid)); //$NON-NLS-1$
0676: // rmi.log.4C=agid : {0}
0677: rLog.log(commonDebugLevel, Messages.getString(
0678: "rmi.log.4C", agid)); //$NON-NLS-1$
0679:
0680: ActivationGroupInfo info = (ActivationGroupInfo) groupInfoByGroupId
0681: .get(agid);
0682: // rmi.log.50=ActivationGroupInfo = {0}
0683: rLog.log(commonDebugLevel, Messages.getString(
0684: "rmi.log.50", info)); //$NON-NLS-1$
0685:
0686: info.registerObject(aid, adesc);
0687: // rmi.log.51=Activation desc was added.
0688: rLog.log(commonDebugLevel, Messages.getString("rmi.log.51")); //$NON-NLS-1$
0689: return aid;
0690:
0691: }
0692:
0693: public ActivationDesc setActivationDesc(ActivationID id,
0694: ActivationDesc desc) {
0695: waitStartup();
0696: ActivationGroupID agid = (ActivationGroupID) groupIDByActivationID
0697: .get(id);
0698: ActivationGroupInfo agi = (ActivationGroupInfo) groupInfoByGroupId
0699: .get(agid);
0700: return agi.setActivationDesc(id, desc);
0701: }
0702:
0703: public ActivationGroupDesc setActivationGroupDesc(
0704: ActivationGroupID id, ActivationGroupDesc desc) {
0705: waitStartup();
0706: ActivationGroupInfo agi = (ActivationGroupInfo) groupInfoByGroupId
0707: .get(id);
0708: return agi.setActivationGroupDesc(id, desc);
0709: }
0710:
0711: public void shutdown() {
0712: synchronized (lock) {
0713: // rmi.log.52=The Rmid is going to shutdown
0714: rLog
0715: .log(commonDebugLevel, Messages
0716: .getString("rmi.log.52")); //$NON-NLS-1$
0717:
0718: Enumeration enumeration = groupInfoByGroupId.elements();
0719: while (enumeration.hasMoreElements()) {
0720: try {
0721: ActivationGroupInfo agi = (ActivationGroupInfo) enumeration
0722: .nextElement();
0723: agi.shutdown();
0724: } catch (Throwable t) {
0725: // rmi.log.53=Exception in Rmid.shutdown: {0}
0726: rLog.log(commonDebugLevel, Messages.getString(
0727: "rmi.log.53", t)); //$NON-NLS-1$
0728: t.printStackTrace();
0729: }
0730: }
0731: // rmi.log.54=...... Done.
0732: rLog
0733: .log(commonDebugLevel, Messages
0734: .getString("rmi.log.54")); //$NON-NLS-1$
0735: System.exit(0);
0736: }
0737: }
0738:
0739: public void unregisterGroup(ActivationGroupID id)
0740: throws ActivationException, UnknownGroupException,
0741: RemoteException {
0742: waitStartup();
0743: ActivationGroupInfo agi = (ActivationGroupInfo) groupInfoByGroupId
0744: .remove(id);
0745: if (agi == null) {
0746: // rmi.34=Attempt to unregister unknown group {0}
0747: throw new UnknownGroupException(Messages.getString(
0748: "rmi.34", id)); //$NON-NLS-1$
0749: }
0750: agi.unregister();
0751: }
0752:
0753: /**
0754: * @param aID the ActivationID of the object that should be removed.
0755: */
0756: public void unregisterObject(ActivationID aID) {
0757: waitStartup();
0758: ActivationGroupID gID = (ActivationGroupID) groupIDByActivationID
0759: .get(aID);
0760: ActivationGroupInfo gInfo = (ActivationGroupInfo) groupInfoByGroupId
0761: .get(gID);
0762: gInfo.unregisterObject(aID);
0763: }
0764:
0765: /* *********************************************************************
0766: *
0767: * Next methods belong to ActivationMonitor remote interface.
0768: *
0769: *********************************************************************/
0770:
0771: public void activeObject(ActivationID id, MarshalledObject obj)
0772: throws RemoteException, UnknownObjectException {
0773: waitStartup();
0774:
0775: // rmi.log.56=Rmid.activeObject: {0}; {1}
0776: rLog.log(commonDebugLevel, Messages.getString("rmi.log.56", //$NON-NLS-1$
0777: id, obj));
0778: ActivationGroupID agid = (ActivationGroupID) groupIDByActivationID
0779: .get(id);
0780: // rmi.log.57=agid = {0}
0781: rLog.log(commonDebugLevel, Messages.getString(
0782: "rmi.log.57", agid)); //$NON-NLS-1$
0783:
0784: ActivationGroupInfo agi = (ActivationGroupInfo) groupInfoByGroupId
0785: .get(agid);
0786: // rmi.log.58=agi = {0}
0787: rLog.log(commonDebugLevel, Messages
0788: .getString("rmi.log.58", agi)); //$NON-NLS-1$
0789:
0790: ObjectInfo oi = (ObjectInfo) agi.objectInfoByActivationID
0791: .get(id);
0792: // rmi.log.59=oi= {0}
0793: rLog
0794: .log(commonDebugLevel, Messages.getString(
0795: "rmi.log.59", oi)); //$NON-NLS-1$
0796:
0797: oi.active();
0798: // rmi.log.5A=Rmid.activeObject finished.
0799: rLog.log(commonDebugLevel, Messages.getString("rmi.log.5A")); //$NON-NLS-1$
0800: }
0801:
0802: public void inactiveGroup(ActivationGroupID id, long incarnation) {
0803: waitStartup();
0804:
0805: ActivationGroupInfo agi = (ActivationGroupInfo) groupInfoByGroupId
0806: .get(id);
0807: agi.inactive(incarnation);
0808: }
0809:
0810: public void inactiveObject(ActivationID aID) {
0811: waitStartup();
0812: ActivationGroupID gID = (ActivationGroupID) groupIDByActivationID
0813: .get(aID);
0814: ActivationGroupInfo gInfo = (ActivationGroupInfo) groupInfoByGroupId
0815: .get(gID);
0816: gInfo.inactiveObject(aID);
0817: }
0818:
0819: /* *********************************************************************
0820: *
0821: * Next methods belong to Activator remote interface.
0822: *
0823: *********************************************************************/
0824:
0825: public MarshalledObject activate(ActivationID id, boolean force)
0826: throws ActivationException, UnknownObjectException,
0827: RemoteException {
0828: waitStartup();
0829: // rmi.log.5B=ActivatorImpl.activate({0}; {1})
0830: rLog.log(commonDebugLevel, Messages.getString("rmi.log.5B", //$NON-NLS-1$
0831: id, force));
0832:
0833: ActivationGroupID agid = (ActivationGroupID) groupIDByActivationID
0834: .get(id);
0835: // rmi.log.57=agid = {0}
0836: rLog.log(commonDebugLevel, Messages.getString(
0837: "rmi.log.57", agid)); //$NON-NLS-1$
0838: ActivationGroupInfo info = (ActivationGroupInfo) groupInfoByGroupId
0839: .get(agid);
0840: // rmi.log.5C=info = {0}
0841: rLog.log(commonDebugLevel, Messages.getString(
0842: "rmi.log.5C", info)); //$NON-NLS-1$
0843:
0844: return info.activateObject(id, force);
0845: }
0846:
0847: /**
0848: * This class holds all the information needed about ActivationGroup.
0849: * It contains the following information: ActivationGroupID
0850: * ActivationGroupDesc and the array of activatable objects within this
0851: * group. The ActivationSystem holds the array of such objects.
0852: */
0853: private class ActivationGroupInfo {
0854:
0855: private ActivationGroupID agid;
0856:
0857: private ActivationGroupDesc agdesc;
0858:
0859: private Hashtable objectInfoByActivationID;
0860:
0861: private long incarnation;
0862:
0863: private boolean isActive;
0864:
0865: private ActivationInstantiator activationInstantiator;
0866:
0867: private Process process;
0868:
0869: public ActivationGroupInfo(ActivationGroupID agid,
0870: ActivationGroupDesc agdesc) {
0871: this .agdesc = agdesc;
0872: this .agid = agid;
0873: objectInfoByActivationID = new Hashtable();
0874: incarnation = 0;
0875: isActive = false;
0876:
0877: if (startMonitor) {
0878: rmidMonitor.addGroup(agid);
0879: }
0880: }
0881:
0882: public synchronized void inactiveObject(ActivationID aID) {
0883: ObjectInfo oi = (ObjectInfo) objectInfoByActivationID
0884: .get(aID);
0885: oi.inactive();
0886: }
0887:
0888: public synchronized void unregisterObject(ActivationID aID) {
0889: objectInfoByActivationID.remove(aID);
0890: groupIDByActivationID.remove(aID);
0891:
0892: if (startMonitor) {
0893: rmidMonitor.removeObject(aID);
0894: }
0895: }
0896:
0897: public synchronized ActivationDesc setActivationDesc(
0898: ActivationID id, ActivationDesc desc) {
0899: ObjectInfo oi = (ObjectInfo) objectInfoByActivationID
0900: .get(id);
0901: ActivationDesc oldDesc = oi.getActivationDesc();
0902: oi.setActivationDesc(desc);
0903: return oldDesc;
0904: }
0905:
0906: public synchronized ActivationGroupDesc setActivationGroupDesc(
0907: ActivationGroupID id, ActivationGroupDesc desc) {
0908: ActivationGroupDesc oldDesc = agdesc;
0909: agdesc = desc;
0910: return oldDesc;
0911: }
0912:
0913: public synchronized void registerObject(ActivationID id,
0914: ActivationDesc desc) {
0915:
0916: groupIDByActivationID.put(id, agid);
0917:
0918: ObjectInfo oi = new ObjectInfo(id, desc);
0919:
0920: objectInfoByActivationID.put(id, oi);
0921:
0922: if (!restoreLock) {
0923: writeDelta(Delta.PUT, "object", id, desc); //$NON-NLS-1$
0924: // rmi.log.5D=New delta was generated.
0925: rLog.log(persistenceDebugLevel, Messages
0926: .getString("rmi.log.5D")); //$NON-NLS-1$
0927: }
0928: }
0929:
0930: public synchronized MarshalledObject activateObject(
0931: ActivationID id, boolean force)
0932: throws ActivationException, RemoteException {
0933:
0934: // rmi.log.5E=GroupInfo: id={0}; force={1}
0935: rLog.log(commonDebugLevel, Messages.getString("rmi.log.5E", //$NON-NLS-1$
0936: id, force));
0937:
0938: if (!isActive) {
0939: activateGroup();
0940: // rmi.log.5F=Group was activated.
0941: rLog.log(commonDebugLevel, Messages
0942: .getString("rmi.log.5F")); //$NON-NLS-1$
0943: } else {
0944: // rmi.log.60=Group was reused.
0945: rLog.log(commonDebugLevel, Messages
0946: .getString("rmi.log.60")); //$NON-NLS-1$
0947: }
0948:
0949: ObjectInfo oi = (ObjectInfo) objectInfoByActivationID
0950: .get(id);
0951: // rmi.log.61=activation_instantiator = {0}
0952: rLog.log(commonDebugLevel, Messages.getString("rmi.log.61", //$NON-NLS-1$
0953: activationInstantiator));
0954:
0955: Exception signalException = null;
0956: try {
0957: return oi.activate(activationInstantiator);
0958: } catch (ConnectException ce) {
0959: } catch (ConnectIOException cioe) {
0960: } catch (MarshalException me) {
0961: } catch (Exception e) {
0962: signalException = e;
0963: }
0964:
0965: if (signalException == null) {
0966: // rmi.log.62=The group seems to be dead: Killing process, reactivating group.
0967: rLog.log(commonDebugLevel, Messages
0968: .getString("rmi.log.62")); //$NON-NLS-1$
0969:
0970: if (process != null) {
0971: process.destroy();
0972: }
0973: isActive = false;
0974: activationInstantiator = null;
0975: activateGroup();
0976: return oi.activate(activationInstantiator);
0977: }
0978: // rmi.35=Exception:
0979: throw new ActivationException(
0980: Messages.getString("rmi.35"), signalException); //$NON-NLS-1$
0981: }
0982:
0983: public synchronized void activateGroup() {
0984:
0985: /*
0986: * Constructing an appropriate commandline to start activation
0987: * group.
0988: *
0989: */
0990: String args[];
0991: ArrayList al = new ArrayList();
0992: CommandEnvironment ce = agdesc.getCommandEnvironment();
0993:
0994: if (ce != null) {
0995:
0996: String[] options = ce.getCommandOptions();
0997: String cmd = ce.getCommandPath();
0998: if (cmd != null) {
0999: al.add(cmd);
1000: } else {
1001: al.add("java"); //$NON-NLS-1$
1002: }
1003: al.addAll(Arrays.asList(options));
1004: } else {
1005:
1006: /*
1007: * Getting properties that affect group VM execution.
1008: */
1009: String javaVmNameVal = (String) AccessController
1010: .doPrivileged(new GetStringPropAction(
1011: "java.vm.name")); //$NON-NLS-1$
1012:
1013: String javaHomeVal = (String) AccessController
1014: .doPrivileged(new GetStringPropAction(
1015: "java.home")); //$NON-NLS-1$
1016:
1017: String javaClassPathVal = (String) AccessController
1018: .doPrivileged(new GetStringPropAction(
1019: "java.class.path")); //$NON-NLS-1$
1020:
1021: String policy = (String) AccessController
1022: .doPrivileged(new GetStringPropAction(
1023: "java.security.policy")); //$NON-NLS-1$
1024:
1025: String bootClassPathVal = (String) AccessController
1026: .doPrivileged(new GetStringPropAction(
1027: (javaVmNameVal.equals("J9") //$NON-NLS-1$
1028: ? "org.apache.harmony.boot.class.path" //$NON-NLS-1$
1029: : "sun.boot.class.path"))); //$NON-NLS-1$
1030:
1031: String executable = new File(new File(javaHomeVal,
1032: "bin"), "java").getPath(); //$NON-NLS-1$ //$NON-NLS-2$
1033:
1034: // Add name of Java executable to run.
1035: al.add(executable);
1036:
1037: if (bootClassPathVal != null) {
1038: al.add("-Xbootclasspath:" + bootClassPathVal); //$NON-NLS-1$
1039: }
1040:
1041: if (javaClassPathVal != null) {
1042: al.add("-classpath"); //$NON-NLS-1$
1043: al.add(javaClassPathVal);
1044: }
1045:
1046: if (policy != null) {
1047: // Apply security policy.
1048: al.add("-Djava.security.policy=" + policy); //$NON-NLS-1$
1049: }
1050: }
1051:
1052: /*
1053: * Passing the "-C" options to the ActivationGroup VM.
1054: */
1055: for (int i = 0; i < groupArgs.length; i++) {
1056: // rmi.log.63=Option was passed through '-C': {0}
1057: rLog.log(commonDebugLevel, Messages.getString(
1058: "rmi.log.63", //$NON-NLS-1$
1059: groupArgs[i]));
1060: al.add(groupArgs[i]);
1061: }
1062:
1063: al
1064: .add("org.apache.harmony.rmi.activation.ActivationGroupImpl"); //$NON-NLS-1$
1065: args = (String[]) al.toArray(new String[al.size()]);
1066: // rmi.log.64=args = {0}
1067: rLog.log(commonDebugLevel, Messages.getString(
1068: "rmi.log.64", Arrays.asList(args))); //$NON-NLS-1$
1069:
1070: try {
1071: final String[] argsLocal = args;
1072: process = (Process) AccessController
1073: .doPrivileged(new PrivilegedExceptionAction() {
1074: public Object run() throws IOException {
1075: return Runtime.getRuntime().exec(
1076: argsLocal);
1077: }
1078: });
1079:
1080: startingGroups--;
1081: InputStream in = process.getInputStream();
1082: InputStream err = process.getErrorStream();
1083:
1084: new DebugThread(in).start();
1085: new DebugThread(err).start();
1086:
1087: // rmi.log.65=ActivationGroup started: {0}
1088: rLog.log(commonDebugLevel, Messages.getString(
1089: "rmi.log.65", //$NON-NLS-1$
1090: process));
1091: incarnation++;
1092:
1093: OutputStream os = process.getOutputStream();
1094: RMIObjectOutputStream oos = new RMIObjectOutputStream(
1095: new BufferedOutputStream(os));
1096:
1097: oos.writeObject(agid);
1098:
1099: // rmi.log.66=Agid written: {0}
1100: rLog.log(commonDebugLevel, Messages.getString(
1101: "rmi.log.66", agid)); //$NON-NLS-1$
1102: oos.writeObject(agdesc);
1103: // rmi.log.67=Agdesc written: {0}
1104: rLog.log(commonDebugLevel, Messages.getString(
1105: "rmi.log.67", agdesc)); //$NON-NLS-1$
1106:
1107: oos.writeLong(incarnation);
1108: // rmi.log.68=incarnation written: {0}
1109: rLog.log(commonDebugLevel, Messages.getString(
1110: "rmi.log.68", //$NON-NLS-1$
1111: incarnation));
1112:
1113: oos.flush();
1114: // rmi.log.69=flushed
1115: rLog.log(commonDebugLevel, Messages
1116: .getString("rmi.log.69")); //$NON-NLS-1$
1117:
1118: oos.close();
1119: os.close();
1120: // rmi.log.6A=closed
1121: rLog.log(commonDebugLevel, Messages
1122: .getString("rmi.log.6A")); //$NON-NLS-1$
1123:
1124: if (activationInstantiator == null) {
1125: try {
1126: this .wait(groupStartTimeout);
1127: } catch (InterruptedException t) {
1128: }
1129: }
1130: startingGroups++;
1131: } catch (Throwable t) {
1132: // rmi.log.6B=Cannot start ActivationGroup.\n Exception: {0}
1133: rLog.log(commonDebugLevel, Messages.getString(
1134: "rmi.log.6B", t)); //$NON-NLS-1$
1135: t.printStackTrace();
1136: }
1137: }
1138:
1139: /**
1140: * Callback from ActivationGroup.createGroup that the groups was
1141: * created.
1142: */
1143: public synchronized void active(ActivationInstantiator ai,
1144: long incarnation) {
1145: // rmi.log.6C=ActivationGroupInfo.activeGroup[ActInst={0}; incarn={1}]
1146: rLog.log(commonDebugLevel, Messages.getString(
1147: "rmi.log.6C", ai, //$NON-NLS-1$
1148: incarnation));
1149: activationInstantiator = ai;
1150: notify();
1151:
1152: if (this .incarnation != incarnation) {
1153: // rmi.33=Different incarnations of this group happened.
1154: throw new RuntimeException(Messages.getString("rmi.33")); //$NON-NLS-1$
1155: }
1156: activationInstantiator = ai;
1157: isActive = true;
1158:
1159: if (startMonitor) {
1160: rmidMonitor.activeGroup(agid);
1161: }
1162: // rmi.log.6D=ActivationGroupInfo.activeGroup finished.
1163: rLog
1164: .log(commonDebugLevel, Messages
1165: .getString("rmi.log.6D")); //$NON-NLS-1$
1166: }
1167:
1168: public ActivationGroupDesc getActivationGroupDesc() {
1169: return agdesc;
1170: }
1171:
1172: public boolean isActive() {
1173: return isActive;
1174: }
1175:
1176: public ActivationDesc getActivationDesc(ActivationID aid) {
1177: return (ActivationDesc) ((ObjectInfo) objectInfoByActivationID
1178: .get(aid)).getActivationDesc();
1179: }
1180:
1181: /**
1182: * Shut the activation group down.
1183: *
1184: * @return The exit value of activation group's VM.
1185: */
1186: public synchronized int shutdown() {
1187: if (process != null) {
1188: process.destroy();
1189: int val = process.exitValue();
1190: process = null;
1191: return val;
1192: }
1193: return 0;
1194: }
1195:
1196: public synchronized void unregister() {
1197: Enumeration keys = objectInfoByActivationID.keys();
1198:
1199: while (keys.hasMoreElements()) {
1200: ActivationID id = (ActivationID) keys.nextElement();
1201:
1202: objectInfoByActivationID.remove(id);
1203: groupIDByActivationID.remove(id);
1204: }
1205: }
1206:
1207: public synchronized void inactive(long incarnation) {
1208: isActive = false;
1209: }
1210:
1211: public String toString() {
1212: return "GroupInfo[ ActivationGroupID = " + agid + "]"; //$NON-NLS-1$ //$NON-NLS-2$
1213: }
1214: }
1215:
1216: /**
1217: * Structure to hold just 1 activated object.
1218: */
1219: private class ObjectInfo {
1220:
1221: boolean isActive;
1222:
1223: private ActivationDesc desc;
1224:
1225: private ActivationID id;
1226:
1227: MarshalledObject cachedInstance = null;
1228:
1229: public ObjectInfo(ActivationID id, ActivationDesc desc) {
1230: this .id = id;
1231: this .desc = desc;
1232: isActive = false;
1233:
1234: if (startMonitor) {
1235: rmidMonitor.addObject(id, desc.getGroupID());
1236: }
1237: }
1238:
1239: public synchronized MarshalledObject activate(
1240: ActivationInstantiator ai) throws ActivationException,
1241: RemoteException {
1242:
1243: // rmi.log.6E=ObjectInfo.activate started. Act Inst = {0}
1244: rLog.log(commonDebugLevel, Messages.getString(
1245: "rmi.log.6E", ai)); //$NON-NLS-1$
1246:
1247: if (cachedInstance != null) {
1248: // rmi.log.6F=Subsequent call to activate, returning cached instance.
1249: rLog.log(commonDebugLevel, Messages
1250: .getString("rmi.log.6F")); //$NON-NLS-1$
1251: return cachedInstance;
1252: }
1253:
1254: MarshalledObject mo = ai.newInstance(id, desc);
1255: // rmi.log.70=ObjectInfo.activate completed: {0}
1256: rLog.log(commonDebugLevel, Messages.getString(
1257: "rmi.log.70", mo)); //$NON-NLS-1$
1258:
1259: return mo;
1260: }
1261:
1262: public ActivationDesc getActivationDesc() {
1263: return desc;
1264: }
1265:
1266: public synchronized void setActivationDesc(ActivationDesc desc) {
1267: this .desc = desc;
1268: }
1269:
1270: public void active() {
1271: if (startMonitor) {
1272: rmidMonitor.activeObject(id);
1273: }
1274: }
1275:
1276: public void inactive() {
1277: /*
1278: * When the object is being deactivated, the cached instance of
1279: * its stub becomes invalid.
1280: */
1281: cachedInstance = null;
1282:
1283: if (startMonitor) {
1284: rmidMonitor.inactiveObject(id);
1285: }
1286: }
1287: }
1288:
1289: /**
1290: * DebugThread - the thread that consumes the contents of the given
1291: * InputStream and prints it to console. Usually it is used to read
1292: * information from error and input streams of the ActivationGroup.
1293: */
1294: private class DebugThread extends Thread {
1295: InputStream is = null;
1296:
1297: public DebugThread(InputStream is) {
1298: this .is = is;
1299: }
1300:
1301: public void run() {
1302: try {
1303: byte tmp[] = new byte[1000];
1304:
1305: while (true) {
1306: int c = is.read(tmp);
1307: if (c == -1)
1308: break;
1309: byte buf[] = new byte[c];
1310: System.arraycopy(tmp, 0, buf, 0, c);
1311: if (c != 0)
1312: System.out.print(new String(buf));
1313: }
1314: } catch (Throwable t) {
1315: }
1316: }
1317: }
1318:
1319: private synchronized void snapshot() {
1320: try {
1321: File f = new File(logFolder
1322: + RMIConstants.DEFAULT_SNAPSHOT_FILE);
1323: FileOutputStream fos = new FileOutputStream(f, false);
1324: ObjectOutputStream out = new ObjectOutputStream(fos);
1325: out.writeObject(new Snapshot());
1326: out.close();
1327: fos.close();
1328: } catch (Throwable t) {
1329: t.printStackTrace();
1330: throw new RuntimeException(t);
1331: }
1332: }
1333:
1334: private synchronized void writeDelta(final int op,
1335: final String name, final Object key, final Object val) {
1336: deltasCounter++;
1337:
1338: AccessController.doPrivileged(new PrivilegedAction() {
1339:
1340: public Object run() {
1341: if (deltasCounter < snapshotInterval) {
1342:
1343: try {
1344: File f = new File(logFolder
1345: + RMIConstants.DEFAULT_DELTA_FILE);
1346: FileOutputStream fos = new FileOutputStream(f,
1347: true);
1348: ObjectOutputStream out = new ObjectOutputStream(
1349: fos);
1350: out.writeObject(new Delta(op, name, key, val));
1351: out.close();
1352: fos.close();
1353: // rmi.log.71=Delta was written.
1354: rLog.log(persistenceDebugLevel, Messages
1355: .getString("rmi.log.71")); //$NON-NLS-1$
1356: } catch (Throwable t) {
1357: t.printStackTrace();
1358: System.exit(1);
1359: }
1360: } else {
1361: File df = new File(logFolder
1362: + RMIConstants.DEFAULT_DELTA_FILE);
1363: df.delete();
1364: snapshot();
1365: deltasCounter = 0;
1366:
1367: }
1368: return null;
1369: }
1370: });
1371: }
1372:
1373: private synchronized void restore() throws Exception {
1374: restoreLock = true;
1375: final File sf = new File(logFolder
1376: + RMIConstants.DEFAULT_SNAPSHOT_FILE);
1377: final File df = new File(logFolder
1378: + RMIConstants.DEFAULT_DELTA_FILE);
1379:
1380: try {
1381:
1382: AccessController
1383: .doPrivileged(new PrivilegedExceptionAction() {
1384: public Object run() throws Exception {
1385:
1386: if (sf.exists()) {
1387: FileInputStream fis = new FileInputStream(
1388: sf);
1389: ObjectInputStream in = new ObjectInputStream(
1390: fis);
1391: in.readObject();
1392: in.close();
1393: fis.close();
1394: }
1395:
1396: try {
1397: if (df.exists()) {
1398: FileInputStream fis = new FileInputStream(
1399: df);
1400: while (true) {
1401: ObjectInputStream in = new ObjectInputStream(
1402: fis);
1403: Delta d = (Delta) in
1404: .readObject();
1405: // rmi.log.72=A delta was restored: {0}
1406: rLog
1407: .log(
1408: persistenceDebugLevel,
1409: Messages
1410: .getString(
1411: "rmi.log.72", d)); //$NON-NLS-1$
1412: }
1413: }
1414: } catch (EOFException eofe) {
1415: // This section was intentionally left empty.
1416: // Indicates that End of File reached -
1417: //meaning all deltas were read.
1418: return null;
1419: }
1420: return null;
1421: }
1422: });
1423: } catch (Throwable t) {
1424: // rmi.log.73=Exception in restore: {0}
1425: rLog.log(persistenceDebugLevel, Messages.getString(
1426: "rmi.log.73", t)); //$NON-NLS-1$
1427: t.printStackTrace();
1428: /*
1429: * Returning Activation System into initial state:
1430: */
1431: groupIDByActivationID = new Hashtable();
1432: groupInfoByGroupId = new Hashtable();
1433: System.gc();
1434: }
1435:
1436: restoreLock = false;
1437: }
1438:
1439: class Delta implements Serializable {
1440:
1441: private static final long serialVersionUID = 103662164369676173L;
1442:
1443: private static final int PUT = 0;
1444:
1445: private static final int REMOVE = 1;
1446:
1447: public int op;
1448:
1449: public String name;
1450:
1451: public MarshalledObject mkey;
1452:
1453: public MarshalledObject mval;
1454:
1455: public Delta(int op, String name, Object key, Object val)
1456: throws Exception {
1457: this .op = op;
1458: this .name = name;
1459: mkey = new MarshalledObject(key);
1460: mval = new MarshalledObject(val);
1461: }
1462:
1463: public String toString() {
1464: try {
1465: return "Delta: " + op + "," + name + ", " + mkey.get() //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
1466: + ", " + mval.get(); //$NON-NLS-1$
1467: } catch (Throwable t) {
1468: t.printStackTrace();
1469: return "" + t; //$NON-NLS-1$
1470: }
1471: }
1472:
1473: private synchronized void writeObject(ObjectOutputStream out)
1474: throws IOException {
1475: out.writeInt(op);
1476: out.writeUTF(name);
1477: out.writeObject(mkey);
1478: out.writeObject(mval);
1479: }
1480:
1481: private synchronized void readObject(ObjectInputStream in)
1482: throws IOException, ClassNotFoundException {
1483: op = in.readInt();
1484: name = in.readUTF();
1485: mkey = (MarshalledObject) in.readObject();
1486: mval = (MarshalledObject) in.readObject();
1487: // rmi.log.75=Delta: Data read:
1488: rLog
1489: .log(
1490: persistenceDebugLevel,
1491: Messages.getString("rmi.log.75") + op //$NON-NLS-1$
1492: + ", " + name + ", " + mkey.get() + ", " + mval.get()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
1493:
1494: if (op == PUT) {
1495: if (name.equals("group")) { //$NON-NLS-1$
1496: ActivationGroupID agid = (ActivationGroupID) mkey
1497: .get();
1498: // rmi.log.76=Restore agid: {0}
1499: rLog.log(persistenceDebugLevel, Messages.getString(
1500: "rmi.log.76", //$NON-NLS-1$
1501: agid));
1502: ActivationGroupDesc agdesc = (ActivationGroupDesc) mval
1503: .get();
1504:
1505: ActivationGroupInfo agi = new ActivationGroupInfo(
1506: agid, agdesc);
1507: // rmi.log.77=Restore agi: {0}
1508: rLog.log(persistenceDebugLevel, Messages.getString(
1509: "rmi.log.77", agi)); //$NON-NLS-1$
1510: groupInfoByGroupId.put(agid, agi);
1511: // rmi.log.78=The data were put into groupID2groupInfo_H
1512: rLog.log(persistenceDebugLevel, Messages
1513: .getString("rmi.log.78")); //$NON-NLS-1$
1514: }
1515: if (name.equals("object")) { //$NON-NLS-1$
1516: // rmi.log.79=Trying to restore ActivationID:
1517: rLog.log(persistenceDebugLevel, Messages
1518: .getString("rmi.log.79")); //$NON-NLS-1$
1519: ActivationID aid = (ActivationID) mkey.get();
1520: // rmi.log.0F=aid = {0}
1521: rLog.log(persistenceDebugLevel, Messages.getString(
1522: "rmi.log.0F", aid)); //$NON-NLS-1$
1523: ActivationDesc adesc = (ActivationDesc) mval.get();
1524: // rmi.log.7A=adesc = {0}
1525: rLog.log(persistenceDebugLevel, Messages.getString(
1526: "rmi.log.7A", adesc)); //$NON-NLS-1$
1527:
1528: ActivationGroupID agid = adesc.getGroupID();
1529: // rmi.log.57=agid = {0}
1530: rLog.log(persistenceDebugLevel, Messages.getString(
1531: "rmi.log.57", agid)); //$NON-NLS-1$
1532:
1533: ActivationGroupInfo agi = (ActivationGroupInfo) groupInfoByGroupId
1534: .get(agid);
1535: // rmi.log.58=agi = {0}
1536: rLog.log(persistenceDebugLevel, Messages.getString(
1537: "rmi.log.58", agi)); //$NON-NLS-1$
1538:
1539: groupIDByActivationID.put(aid, agid);
1540:
1541: agi.registerObject(aid, adesc);
1542: // rmi.log.7D=Object was registered.
1543: rLog.log(persistenceDebugLevel, Messages
1544: .getString("rmi.log.7D")); //$NON-NLS-1$
1545: // rmi.log.7E=Object was put into hashtable.
1546: rLog.log(persistenceDebugLevel, Messages
1547: .getString("rmi.log.7E")); //$NON-NLS-1$
1548: }
1549: }
1550:
1551: if (op == REMOVE) {
1552: if (name.equals("object")) { //$NON-NLS-1$
1553: groupIDByActivationID.remove(mkey.get());
1554: }
1555:
1556: if (name.equals("group")) { //$NON-NLS-1$
1557: groupInfoByGroupId.remove(mkey.get());
1558: }
1559: }
1560: }
1561: }
1562:
1563: class Snapshot implements Serializable {
1564:
1565: private static final long serialVersionUID = 2006016754895450831L;
1566:
1567: private synchronized void writeObject(ObjectOutputStream out)
1568: throws IOException {
1569:
1570: Hashtable h0 = new Hashtable();
1571: Hashtable h1 = new Hashtable();
1572:
1573: Enumeration e0 = groupInfoByGroupId.keys();
1574: while (e0.hasMoreElements()) {
1575: ActivationGroupID agid = (ActivationGroupID) e0
1576: .nextElement();
1577: MarshalledObject mo_agid = new MarshalledObject(agid);
1578: ActivationGroupInfo agi = (ActivationGroupInfo) groupInfoByGroupId
1579: .get(agid);
1580: ActivationGroupDesc agdesc = agi
1581: .getActivationGroupDesc();
1582: h0.put(mo_agid, agdesc);
1583: Enumeration e1 = agi.objectInfoByActivationID.keys();
1584: while (e1.hasMoreElements()) {
1585: ActivationID aid = (ActivationID) e1.nextElement();
1586: ObjectInfo oi = (ObjectInfo) agi.objectInfoByActivationID
1587: .get(aid);
1588: ActivationDesc adesc = oi.getActivationDesc();
1589: h1.put(aid, adesc);
1590: }
1591: }
1592: out.writeObject(h0);
1593: out.writeObject(h1);
1594: }
1595:
1596: private synchronized void readObject(ObjectInputStream in)
1597: throws IOException, ClassNotFoundException {
1598: Hashtable h0 = (Hashtable) in.readObject();
1599: Hashtable h1 = (Hashtable) in.readObject();
1600:
1601: // rmi.log.7F=Restore:
1602: rLog.log(persistenceDebugLevel, Messages
1603: .getString("rmi.log.7F")); //$NON-NLS-1$
1604: // rmi.log.80=h0 = {0}
1605: rLog.log(persistenceDebugLevel, Messages.getString(
1606: "rmi.log.80", h0)); //$NON-NLS-1$
1607: // rmi.log.81=h1 = {0}
1608: rLog.log(persistenceDebugLevel, Messages.getString(
1609: "rmi.log.81", h1)); //$NON-NLS-1$
1610:
1611: Enumeration e0 = h0.keys();
1612: while (e0.hasMoreElements()) {
1613:
1614: MarshalledObject mo_agid = (MarshalledObject) e0
1615: .nextElement();
1616: ActivationGroupID agid = (ActivationGroupID) mo_agid
1617: .get();
1618: // rmi.log.76=Restore agid: {0}
1619: rLog.log(persistenceDebugLevel, Messages.getString(
1620: "rmi.log.76", agid)); //$NON-NLS-1$
1621:
1622: ActivationGroupDesc agdesc = (ActivationGroupDesc) h0
1623: .get(mo_agid);
1624:
1625: // rmi.log.82=Restore agdesc: {0}
1626: rLog.log(persistenceDebugLevel, Messages.getString(
1627: "rmi.log.82", //$NON-NLS-1$
1628: agdesc));
1629: ActivationGroupInfo agi = new ActivationGroupInfo(agid,
1630: agdesc);
1631: // rmi.log.77=Restore agi: {0}
1632: rLog.log(persistenceDebugLevel, Messages
1633: .getString("rmi.log.77") + agi); //$NON-NLS-1$
1634: groupInfoByGroupId.put(agid, agi);
1635: // rmi.log.78=The data were put into groupID2groupInfo_H
1636: rLog.log(persistenceDebugLevel, Messages
1637: .getString("rmi.log.78")); //$NON-NLS-1$
1638: }
1639:
1640: Enumeration e1 = h1.keys();
1641: while (e1.hasMoreElements()) {
1642: ActivationID aid = (ActivationID) e1.nextElement();
1643: ActivationDesc adesc = (ActivationDesc) h1.get(aid);
1644: ActivationGroupID agid = adesc.getGroupID();
1645: ActivationGroupInfo agi = (ActivationGroupInfo) groupInfoByGroupId
1646: .get(agid);
1647: agi.registerObject(aid, adesc);
1648: groupIDByActivationID.put(aid, agid);
1649: }
1650: }
1651: }
1652: }
|