0001: /*******************************************************************************
0002: * Copyright (c) 2000, 2006 IBM Corporation and others.
0003: * All rights reserved. This program and the accompanying materials
0004: * are made available under the terms of the Eclipse Public License v1.0
0005: * which accompanies this distribution, and is available at
0006: * http://www.eclipse.org/legal/epl-v10.html
0007: *
0008: * Contributors:
0009: * IBM Corporation - initial API and implementation
0010: *******************************************************************************/package org.eclipse.jdi.internal;
0011:
0012: import java.io.ByteArrayOutputStream;
0013: import java.io.DataInputStream;
0014: import java.io.DataOutputStream;
0015: import java.io.IOException;
0016: import java.lang.reflect.Field;
0017: import java.lang.reflect.Modifier;
0018: import java.util.ArrayList;
0019: import java.util.HashMap;
0020: import java.util.Iterator;
0021: import java.util.List;
0022: import java.util.Map;
0023: import java.util.Set;
0024:
0025: import org.eclipse.jdi.Bootstrap;
0026: import org.eclipse.jdi.internal.connect.PacketReceiveManager;
0027: import org.eclipse.jdi.internal.connect.PacketSendManager;
0028: import org.eclipse.jdi.internal.event.EventQueueImpl;
0029: import org.eclipse.jdi.internal.jdwp.JdwpCommandPacket;
0030: import org.eclipse.jdi.internal.jdwp.JdwpObjectID;
0031: import org.eclipse.jdi.internal.jdwp.JdwpReferenceTypeID;
0032: import org.eclipse.jdi.internal.jdwp.JdwpReplyPacket;
0033: import org.eclipse.jdi.internal.request.EventRequestManagerImpl;
0034:
0035: import com.ibm.icu.text.MessageFormat;
0036: import com.sun.jdi.BooleanValue;
0037: import com.sun.jdi.ByteValue;
0038: import com.sun.jdi.CharValue;
0039: import com.sun.jdi.DoubleValue;
0040: import com.sun.jdi.FloatValue;
0041: import com.sun.jdi.IntegerValue;
0042: import com.sun.jdi.LongValue;
0043: import com.sun.jdi.ObjectCollectedException;
0044: import com.sun.jdi.ShortValue;
0045: import com.sun.jdi.StringReference;
0046: import com.sun.jdi.VMDisconnectedException;
0047: import com.sun.jdi.VirtualMachine;
0048: import com.sun.jdi.VoidValue;
0049: import com.sun.jdi.connect.spi.Connection;
0050: import com.sun.jdi.event.EventQueue;
0051: import com.sun.jdi.request.EventRequestManager;
0052:
0053: /**
0054: * This class implements the corresponding interfaces
0055: * declared by the JDI specification. See the com.sun.jdi package
0056: * for more information.
0057: *
0058: */
0059: public class VirtualMachineImpl extends MirrorImpl implements
0060: VirtualMachine, org.eclipse.jdi.hcr.VirtualMachine,
0061: org.eclipse.jdi.VirtualMachine {
0062: /** Result flags for Classes Have Changed command. */
0063: public static final byte HCR_RELOAD_SUCCESS = 0;
0064: public static final byte HCR_RELOAD_FAILURE = 1;
0065: public static final byte HCR_RELOAD_IGNORED = 2;
0066:
0067: /* Indexes in HCR capabilities list.*/
0068: private static final int HCR_CAN_RELOAD_CLASSES = 0;
0069: private static final int HCR_CAN_GET_CLASS_VERSION = 1;
0070: private static final int HCR_CAN_DO_RETURN = 2;
0071: private static final int HCR_CAN_REENTER_ON_EXIT = 3;
0072:
0073: protected static final String JAVA_STRATUM_NAME = "Java"; //$NON-NLS-1$
0074:
0075: /** Timeout value for requests to VM if not overriden for a particular VM. */
0076: private int fRequestTimeout;
0077: /** Mapping of command codes to strings. */
0078:
0079: private static Map fgHCRResultMap = null;
0080:
0081: /** EventRequestManager that creates event objects on request. */
0082: private EventRequestManagerImpl fEventReqMgr;
0083: /** EventQueue that returns EventSets from the Virtual Manager. */
0084: private EventQueueImpl fEventQueue;
0085:
0086: /** If a launchingconnector is used, we store the process. */
0087: private Process fLaunchedProcess;
0088:
0089: /**
0090: * The following field contains cached Mirrors.
0091: * Note that these are optional: their only purpose is to speed up the debugger by
0092: * being able to use the stored results of JDWP calls.
0093: */
0094: private ValueCache fCachedReftypes = new ValueCache();
0095: private ValueCache fCachedObjects = new ValueCache();
0096:
0097: /** The following are the stored results of JDWP calls. */
0098: private String fVersionDescription = null; // Text information on the VM version.
0099: private int fJdwpMajorVersion;
0100: private int fJdwpMinorVersion;
0101: private String fVMVersion; // Target VM JRE version, as in the java.version property.
0102: private String fVMName; // Target VM name, as in the java.vm.name property.
0103: private boolean fGotIDSizes = false;
0104: private int fFieldIDSize;
0105: private int fMethodIDSize;
0106: private int fObjectIDSize;
0107: private int fReferenceTypeIDSize;
0108: private int fFrameIDSize;
0109:
0110: private boolean fGotCapabilities = false;
0111: private boolean fCanWatchFieldModification;
0112: private boolean fCanWatchFieldAccess;
0113: private boolean fCanGetBytecodes;
0114: private boolean fCanGetSyntheticAttribute;
0115: private boolean fCanGetOwnedMonitorInfo;
0116: private boolean fCanGetCurrentContendedMonitor;
0117: private boolean fCanGetMonitorInfo;
0118: private boolean fCanRedefineClasses;
0119: private boolean fCanAddMethod;
0120: private boolean fCanUnrestrictedlyRedefineClasses;
0121: private boolean fCanPopFrames;
0122: private boolean fCanUseInstanceFilters;
0123: private boolean fCanGetSourceDebugExtension;
0124: private boolean fCanRequestVMDeathEvent;
0125: private boolean fCanSetDefaultStratum;
0126: private boolean fCanGetInstanceInfo;
0127: private boolean fCanGetConstantPool;
0128: private boolean fCanUseSourceNameFilters;
0129: private boolean fCanForceEarlyReturn;
0130: private boolean fCanRequestMonitorEvents;
0131: private boolean fCanGetMonitorFrameInfo;
0132: private boolean[] fHcrCapabilities = null;
0133:
0134: /*
0135: * singletons for primitive types
0136: */
0137: private BooleanTypeImpl fBooleanType;
0138: private ByteTypeImpl fByteType;
0139: private CharTypeImpl fCharType;
0140: private DoubleTypeImpl fDoubleType;
0141: private FloatTypeImpl fFloatType;
0142: private IntegerTypeImpl fIntegerType;
0143: private LongTypeImpl fLongType;
0144: private ShortTypeImpl fShortType;
0145:
0146: /**
0147: * Disconnected flag
0148: */
0149: private boolean fIsDisconnected = false;
0150:
0151: /**
0152: * The name of the current default stratum.
0153: */
0154: private String fDefaultStratum;
0155: private PacketReceiveManager fPacketReceiveManager;
0156: private PacketSendManager fPacketSendManager;
0157:
0158: /**
0159: * Creates a new Virtual Machine.
0160: */
0161: public VirtualMachineImpl(Connection connection) {
0162: super ("VirtualMachine"); //$NON-NLS-1$
0163: fEventReqMgr = new EventRequestManagerImpl(this );
0164: fEventQueue = new EventQueueImpl(this );
0165: fRequestTimeout = ((VirtualMachineManagerImpl) Bootstrap
0166: .virtualMachineManager()).getGlobalRequestTimeout();
0167:
0168: fPacketReceiveManager = new PacketReceiveManager(connection,
0169: this );
0170: Thread receiveThread = new Thread(fPacketReceiveManager,
0171: JDIMessages.VirtualMachineImpl_0);
0172: receiveThread.setDaemon(true);
0173: fPacketReceiveManager.setPartnerThread(receiveThread);
0174: receiveThread.start();
0175:
0176: fPacketSendManager = new PacketSendManager(connection);
0177: Thread sendThread = new Thread(fPacketSendManager,
0178: JDIMessages.VirtualMachineImpl_1);
0179: sendThread.setDaemon(true);
0180: fPacketReceiveManager.setPartnerThread(sendThread);
0181: sendThread.start();
0182: }
0183:
0184: /**
0185: * @return Returns size of JDWP ID.
0186: */
0187: public final int fieldIDSize() {
0188: return fFieldIDSize;
0189: }
0190:
0191: /**
0192: * @return Returns size of JDWP ID.
0193: */
0194: public final int methodIDSize() {
0195: return fMethodIDSize;
0196: }
0197:
0198: /**
0199: * @return Returns size of JDWP ID.
0200: */
0201: public final int objectIDSize() {
0202: return fObjectIDSize;
0203: }
0204:
0205: /**
0206: * @return Returns size of JDWP ID.
0207: */
0208: public final int referenceTypeIDSize() {
0209: return fReferenceTypeIDSize;
0210: }
0211:
0212: /**
0213: * @return Returns size of JDWP ID.
0214: */
0215: public final int frameIDSize() {
0216: return fFrameIDSize;
0217: }
0218:
0219: /**
0220: * @return Returns cached mirror object, or null if method is not in cache.
0221: */
0222: public ReferenceTypeImpl getCachedMirror(JdwpReferenceTypeID ID) {
0223: return (ReferenceTypeImpl) fCachedReftypes.get(ID);
0224: }
0225:
0226: /**
0227: * @return Returns cached mirror object, or null if method is not in cache.
0228: */
0229: public ObjectReferenceImpl getCachedMirror(JdwpObjectID ID) {
0230: return (ObjectReferenceImpl) fCachedObjects.get(ID);
0231: }
0232:
0233: /**
0234: * Adds mirror object to cache.
0235: */
0236: public void addCachedMirror(ReferenceTypeImpl mirror) {
0237: fCachedReftypes.put(mirror.getRefTypeID(), mirror);
0238: // tbd: It is now yet possible to only ask for unload events for
0239: // classes that we know of due to a limitation in the J9 VM.
0240: // eventRequestManagerImpl().enableInternalClasUnloadEvent(mirror);
0241: }
0242:
0243: /**
0244: * Adds mirror object to cache.
0245: */
0246: public void addCachedMirror(ObjectReferenceImpl mirror) {
0247: fCachedObjects.put(mirror.getObjectID(), mirror);
0248: }
0249:
0250: /**
0251: * Flushes all stored Jdwp results.
0252: */
0253: public void flushStoredJdwpResults() {
0254: // All known classes also become invalid.
0255: Iterator iter = fCachedReftypes.values().iterator();
0256: while (iter.hasNext()) {
0257: ReferenceTypeImpl refType = (ReferenceTypeImpl) iter.next();
0258: refType.flushStoredJdwpResults();
0259: }
0260:
0261: fVersionDescription = null;
0262: fGotIDSizes = false;
0263: fHcrCapabilities = null;
0264: }
0265:
0266: /*
0267: * Removes a known class.
0268: * A class/interface is known if we have ever received its ReferenceTypeID and we have
0269: * not received an unload event for it.
0270: */
0271: public final void removeKnownRefType(String signature) {
0272: List refTypeList = classesBySignature(signature);
0273: if (refTypeList.isEmpty())
0274: return;
0275:
0276: // If we have only one known class for this signature, we known that this is the class
0277: // to be removed.
0278: if (refTypeList.size() == 1) {
0279: ReferenceTypeImpl refType = (ReferenceTypeImpl) refTypeList
0280: .get(0);
0281: refType.flushStoredJdwpResults();
0282: fCachedReftypes.remove(refType.getRefTypeID());
0283: return;
0284: }
0285:
0286: // We have more than one known class for the signature, let's find the unloaded one(s).
0287: Iterator iter = refTypeList.iterator();
0288: while (iter.hasNext()) {
0289: ReferenceTypeImpl refType = (ReferenceTypeImpl) iter.next();
0290: boolean prepared = false;
0291: try {
0292: prepared = refType.isPrepared();
0293: } catch (ObjectCollectedException exception) {
0294: // The type is unloaded. Fall through
0295: }
0296: if (!prepared) {
0297: refType.flushStoredJdwpResults();
0298: iter.remove();
0299: fCachedReftypes.remove(refType.getRefTypeID());
0300: }
0301: }
0302: }
0303:
0304: /*
0305: * @exception Throws UnsupportedOperationException if VM does not support J9 HCR.
0306: */
0307: public void checkHCRSupported()
0308: throws UnsupportedOperationException {
0309: if (!isHCRSupported())
0310: throw new UnsupportedOperationException(
0311: MessageFormat
0312: .format(
0313: JDIMessages.VirtualMachineImpl_Target_VM__0__does_not_support_Hot_Code_Replacement_1,
0314: new String[] { name() }));
0315: }
0316:
0317: /*
0318: * Returns whether J9 HCR is supported
0319: */
0320: public boolean isHCRSupported()
0321: throws UnsupportedOperationException {
0322: return name().equals("j9"); //$NON-NLS-1$
0323: }
0324:
0325: /*
0326: * @return Returns Manager for receiving packets from the Virtual Machine.
0327: */
0328: public final PacketReceiveManager packetReceiveManager() {
0329: return fPacketReceiveManager;
0330: }
0331:
0332: /*
0333: * @return Returns Manager for sending packets to the Virtual Machine.
0334: */
0335: public final PacketSendManager packetSendManager() {
0336: /*
0337: * Before we send out first bytes to the VM by JDI calls, we need some initial requests:
0338: * - Get the sizes of the IDs (fieldID, method ID etc.) that the VM uses;
0339: * - Request class prepare and unload events. We used these to cache classes/interfaces and map their signatures.
0340: */
0341: if (!fGotIDSizes) {
0342: getIDSizes();
0343: if (!fGotIDSizes) { // We can't do much without them.
0344: disconnectVM();
0345: throw new VMDisconnectedException(
0346: JDIMessages.VirtualMachineImpl_Failed_to_get_ID_sizes_2);
0347: }
0348:
0349: // tbd: This call should be moved to addKnownRefType() when it can be made specific
0350: // for a referencetype.
0351: eventRequestManagerImpl().enableInternalClasUnloadEvent();
0352: }
0353:
0354: return fPacketSendManager;
0355: }
0356:
0357: /**
0358: * Returns all loaded types (classes, interfaces, and array types).
0359: * For each loaded type in the target VM a ReferenceType will be placed in the returned list.
0360: */
0361: public List allClasses() {
0362: // Note that this information should not be cached.
0363: initJdwpRequest();
0364: try {
0365: boolean withGenericSignature = virtualMachineImpl()
0366: .isJdwpVersionGreaterOrEqual(1, 5);
0367: int jdwpCommand = withGenericSignature ? JdwpCommandPacket.VM_ALL_CLASSES_WITH_GENERIC
0368: : JdwpCommandPacket.VM_ALL_CLASSES;
0369: JdwpReplyPacket replyPacket = requestVM(jdwpCommand);
0370: defaultReplyErrorHandler(replyPacket.errorCode());
0371: DataInputStream replyData = replyPacket.dataInStream();
0372: int nrOfElements = readInt("elements", replyData); //$NON-NLS-1$
0373: List elements = new ArrayList(nrOfElements);
0374: for (int i = 0; i < nrOfElements; i++) {
0375: ReferenceTypeImpl elt = ReferenceTypeImpl
0376: .readWithTypeTagAndSignature(this ,
0377: withGenericSignature, replyData);
0378: if (elt == null) {
0379: continue;
0380: }
0381: readInt(
0382: "status", ReferenceTypeImpl.classStatusStrings(), replyData); //$NON-NLS-1$
0383: elements.add(elt);
0384: }
0385: return elements;
0386: } catch (IOException e) {
0387: defaultIOExceptionHandler(e);
0388: return null;
0389: } finally {
0390: handledJdwpRequest();
0391: }
0392:
0393: }
0394:
0395: /**
0396: * @return Returns an iterator over all loaded classes.
0397: */
0398: protected final Iterator allRefTypes() {
0399: return allClasses().iterator();
0400: }
0401:
0402: /**
0403: * @return Returns an iterator over all cached classes.
0404: */
0405: protected final Iterator allCachedRefTypes() {
0406: return fCachedReftypes.values().iterator();
0407: }
0408:
0409: /**
0410: * Returns a list of the currently running threads.
0411: * For each running thread in the target VM, a ThreadReference that mirrors it is placed in the list.
0412: */
0413: public List allThreads() {
0414: // Note that this information should not be cached.
0415: initJdwpRequest();
0416: try {
0417: JdwpReplyPacket replyPacket = requestVM(JdwpCommandPacket.VM_ALL_THREADS);
0418: defaultReplyErrorHandler(replyPacket.errorCode());
0419: DataInputStream replyData = replyPacket.dataInStream();
0420: int nrOfElements = readInt("elements", replyData); //$NON-NLS-1$
0421: List elements = new ArrayList(nrOfElements);
0422: for (int i = 0; i < nrOfElements; i++) {
0423: ThreadReferenceImpl elt = ThreadReferenceImpl.read(
0424: this , replyData);
0425: if (elt == null) {
0426: continue;
0427: }
0428: elements.add(elt);
0429: }
0430: return elements;
0431: } catch (IOException e) {
0432: defaultIOExceptionHandler(e);
0433: return null;
0434: } finally {
0435: handledJdwpRequest();
0436: }
0437: }
0438:
0439: /**
0440: * Retrieve this VM's capabilities.
0441: */
0442: public void getCapabilities() {
0443: if (fGotCapabilities)
0444: return;
0445:
0446: int command = JdwpCommandPacket.VM_CAPABILITIES;
0447: if (isJdwpVersionGreaterOrEqual(1, 4)) {
0448: command = JdwpCommandPacket.VM_CAPABILITIES_NEW;
0449: }
0450:
0451: initJdwpRequest();
0452: try {
0453: JdwpReplyPacket replyPacket = requestVM(command);
0454: defaultReplyErrorHandler(replyPacket.errorCode());
0455: DataInputStream replyData = replyPacket.dataInStream();
0456:
0457: fCanWatchFieldModification = readBoolean(
0458: "watch field modification", replyData); //$NON-NLS-1$
0459: fCanWatchFieldAccess = readBoolean(
0460: "watch field access", replyData); //$NON-NLS-1$
0461: fCanGetBytecodes = readBoolean("get bytecodes", replyData); //$NON-NLS-1$
0462: fCanGetSyntheticAttribute = readBoolean(
0463: "synth. attr", replyData); //$NON-NLS-1$
0464: fCanGetOwnedMonitorInfo = readBoolean(
0465: "owned monitor info", replyData); //$NON-NLS-1$
0466: fCanGetCurrentContendedMonitor = readBoolean(
0467: "curr. contended monitor", replyData); //$NON-NLS-1$
0468: fCanGetMonitorInfo = readBoolean("monitor info", replyData); //$NON-NLS-1$
0469: if (command == JdwpCommandPacket.VM_CAPABILITIES_NEW) {
0470: // extended capabilities
0471: fCanRedefineClasses = readBoolean(
0472: "redefine classes", replyData); //$NON-NLS-1$
0473: fCanAddMethod = readBoolean("add method", replyData); //$NON-NLS-1$
0474: fCanUnrestrictedlyRedefineClasses = readBoolean(
0475: "unrestrictedly redefine classes", replyData); //$NON-NLS-1$
0476: fCanPopFrames = readBoolean("pop frames", replyData); //$NON-NLS-1$
0477: fCanUseInstanceFilters = readBoolean(
0478: "use instance filters", replyData); //$NON-NLS-1$
0479: fCanGetSourceDebugExtension = readBoolean(
0480: "get source debug extension", replyData); //$NON-NLS-1$
0481: fCanRequestVMDeathEvent = readBoolean(
0482: "request vm death", replyData); //$NON-NLS-1$
0483: fCanSetDefaultStratum = readBoolean(
0484: "set default stratum", replyData); //$NON-NLS-1$
0485: fCanGetInstanceInfo = readBoolean(
0486: "instance info", replyData); //$NON-NLS-1$
0487: fCanRequestMonitorEvents = readBoolean(
0488: "request monitor events", replyData); //$NON-NLS-1$
0489: fCanGetMonitorFrameInfo = readBoolean(
0490: "monitor frame info", replyData); //$NON-NLS-1$
0491: fCanUseSourceNameFilters = readBoolean(
0492: "source name filters", replyData); //$NON-NLS-1$
0493: fCanGetConstantPool = readBoolean(
0494: "constant pool", replyData); //$NON-NLS-1$
0495: fCanForceEarlyReturn = readBoolean(
0496: "force early return", replyData); //$NON-NLS-1$
0497: } else {
0498: fCanRedefineClasses = false;
0499: fCanAddMethod = false;
0500: fCanUnrestrictedlyRedefineClasses = false;
0501: fCanPopFrames = false;
0502: fCanUseInstanceFilters = false;
0503: fCanGetSourceDebugExtension = false;
0504: fCanRequestVMDeathEvent = false;
0505: fCanSetDefaultStratum = false;
0506: fCanGetInstanceInfo = false;
0507: fCanGetConstantPool = false;
0508: fCanUseSourceNameFilters = false;
0509: fCanForceEarlyReturn = false;
0510: fCanRequestMonitorEvents = false;
0511: fCanGetMonitorFrameInfo = false;
0512: }
0513: fGotCapabilities = true;
0514: } catch (IOException e) {
0515: fGotIDSizes = false;
0516: defaultIOExceptionHandler(e);
0517: } finally {
0518: handledJdwpRequest();
0519: }
0520: }
0521:
0522: /**
0523: * @see com.sun.jdi.VirtualMachine#canForceEarlyReturn()
0524: * @since 3.3
0525: */
0526: public boolean canForceEarlyReturn() {
0527: getCapabilities();
0528: return fCanForceEarlyReturn;
0529: }
0530:
0531: /**
0532: * @return Returns true if this implementation supports the retrieval of a method's bytecodes.
0533: */
0534: public boolean canGetBytecodes() {
0535: getCapabilities();
0536: return fCanGetBytecodes;
0537: }
0538:
0539: /**
0540: * @return Returns true if this implementation supports the retrieval of the monitor for which a thread is currently waiting.
0541: */
0542: public boolean canGetCurrentContendedMonitor() {
0543: getCapabilities();
0544: return fCanGetCurrentContendedMonitor;
0545: }
0546:
0547: /**
0548: * @see com.sun.jdi.VirtualMachine#canGetInstanceInfo()
0549: * @since 3.3
0550: */
0551: public boolean canGetInstanceInfo() {
0552: getCapabilities();
0553: return fCanGetInstanceInfo;
0554: }
0555:
0556: /**
0557: * @see com.sun.jdi.VirtualMachine#canGetMethodReturnValues()
0558: * @since 3.3
0559: */
0560: public boolean canGetMethodReturnValues() {
0561: return isJdwpVersionGreaterOrEqual(1, 6);
0562: }
0563:
0564: /**
0565: * @return Returns true if this implementation supports the retrieval of the monitor information for an object.
0566: */
0567: public boolean canGetMonitorInfo() {
0568: getCapabilities();
0569: return fCanGetMonitorInfo;
0570: }
0571:
0572: /**
0573: * @see com.sun.jdi.VirtualMachine#canGetMonitorFrameInfo()
0574: * @since 3.3
0575: */
0576: public boolean canGetMonitorFrameInfo() {
0577: getCapabilities();
0578: return fCanGetMonitorFrameInfo;
0579: }
0580:
0581: /**
0582: * @return Returns true if this implementation supports the retrieval of the monitors owned by a thread.
0583: */
0584: public boolean canGetOwnedMonitorInfo() {
0585: getCapabilities();
0586: return fCanGetOwnedMonitorInfo;
0587: }
0588:
0589: /**
0590: * @return Returns true if this implementation supports the query of the synthetic attribute of a method or field.
0591:
0592: */
0593: public boolean canGetSyntheticAttribute() {
0594: getCapabilities();
0595: return fCanGetSyntheticAttribute;
0596: }
0597:
0598: /**
0599: * @see com.sun.jdi.VirtualMachine#canRequestMonitorEvents()
0600: * @since 3.3
0601: */
0602: public boolean canRequestMonitorEvents() {
0603: getCapabilities();
0604: return fCanRequestMonitorEvents;
0605: }
0606:
0607: /**
0608: * @return Returns true if this implementation supports watchpoints for field access.
0609: */
0610: public boolean canWatchFieldAccess() {
0611: getCapabilities();
0612: return fCanWatchFieldAccess;
0613: }
0614:
0615: /**
0616: * @return Returns true if this implementation supports watchpoints for field modification.
0617: */
0618: public boolean canWatchFieldModification() {
0619: getCapabilities();
0620: return fCanWatchFieldModification;
0621: }
0622:
0623: /**
0624: * @return Returns the loaded reference types that match a given signature.
0625: */
0626: public List classesBySignature(String signature) {
0627: // Note that this information should not be cached.
0628: initJdwpRequest();
0629: try {
0630: ByteArrayOutputStream outBytes = new ByteArrayOutputStream();
0631: DataOutputStream outData = new DataOutputStream(outBytes);
0632: writeString(signature, "signature", outData); //$NON-NLS-1$
0633:
0634: JdwpReplyPacket replyPacket = requestVM(
0635: JdwpCommandPacket.VM_CLASSES_BY_SIGNATURE, outBytes);
0636: defaultReplyErrorHandler(replyPacket.errorCode());
0637: DataInputStream replyData = replyPacket.dataInStream();
0638: int nrOfElements = readInt("elements", replyData); //$NON-NLS-1$
0639: List elements = new ArrayList(nrOfElements);
0640: for (int i = 0; i < nrOfElements; i++) {
0641: ReferenceTypeImpl elt = ReferenceTypeImpl
0642: .readWithTypeTag(this , replyData);
0643: readInt(
0644: "status", ReferenceTypeImpl.classStatusStrings(), replyData); //$NON-NLS-1$
0645: if (elt == null) {
0646: continue;
0647: }
0648: elements.add(elt);
0649: }
0650: return elements;
0651: } catch (IOException e) {
0652: defaultIOExceptionHandler(e);
0653: return null;
0654: } finally {
0655: handledJdwpRequest();
0656: }
0657: }
0658:
0659: /**
0660: * @return Returns the loaded reference types that match a given name.
0661: */
0662: public List classesByName(String name) {
0663: String signature = TypeImpl.classNameToSignature(name);
0664: return classesBySignature(signature);
0665: }
0666:
0667: /**
0668: * Invalidates this virtual machine mirror.
0669: */
0670: public void dispose() {
0671: initJdwpRequest();
0672: try {
0673: requestVM(JdwpCommandPacket.VM_DISPOSE);
0674: disconnectVM();
0675: } catch (VMDisconnectedException e) {
0676: // The VM can exit before we receive the reply.
0677: } finally {
0678: handledJdwpRequest();
0679: }
0680: }
0681:
0682: /**
0683: * @return Returns EventQueue that returns EventSets from the Virtual Manager.
0684: */
0685: public EventQueue eventQueue() {
0686: return fEventQueue;
0687: }
0688:
0689: /**
0690: * @return Returns EventRequestManager that creates all event objects on request.
0691: */
0692: public EventRequestManager eventRequestManager() {
0693: return fEventReqMgr;
0694: }
0695:
0696: /**
0697: * @return Returns EventRequestManagerImpl that creates all event objects on request.
0698: */
0699: public EventRequestManagerImpl eventRequestManagerImpl() {
0700: return fEventReqMgr;
0701: }
0702:
0703: /**
0704: * Causes the mirrored VM to terminate with the given error code.
0705: */
0706: public void exit(int exitCode) {
0707: initJdwpRequest();
0708: try {
0709: ByteArrayOutputStream outBytes = new ByteArrayOutputStream();
0710: DataOutputStream outData = new DataOutputStream(outBytes);
0711: writeInt(exitCode, "exit code", outData); //$NON-NLS-1$
0712: requestVM(JdwpCommandPacket.VM_EXIT, outBytes);
0713: disconnectVM();
0714: } catch (VMDisconnectedException e) {
0715: // The VM can exit before we receive the reply.
0716: } catch (IOException e) {
0717: defaultIOExceptionHandler(e);
0718: } finally {
0719: handledJdwpRequest();
0720: }
0721: }
0722:
0723: /**
0724: * @return Returns newly created ByteValue for the given value.
0725: */
0726: public ByteValue mirrorOf(byte value) {
0727: return new ByteValueImpl(virtualMachineImpl(), new Byte(value));
0728: }
0729:
0730: /**
0731: * @return Returns newly created CharValue for the given value.
0732: */
0733: public CharValue mirrorOf(char value) {
0734: return new CharValueImpl(virtualMachineImpl(), new Character(
0735: value));
0736: }
0737:
0738: /**
0739: * @return Returns newly created DoubleValue for the given value.
0740: */
0741: public DoubleValue mirrorOf(double value) {
0742: return new DoubleValueImpl(virtualMachineImpl(), new Double(
0743: value));
0744: }
0745:
0746: /**
0747: * @return Returns newly created FloatValue for the given value.
0748: */
0749: public FloatValue mirrorOf(float value) {
0750: return new FloatValueImpl(virtualMachineImpl(),
0751: new Float(value));
0752: }
0753:
0754: /**
0755: * @return Returns newly created IntegerValue for the given value.
0756: */
0757: public IntegerValue mirrorOf(int value) {
0758: return new IntegerValueImpl(virtualMachineImpl(), new Integer(
0759: value));
0760: }
0761:
0762: /**
0763: * @return Returns newly created LongValue for the given value.
0764: */
0765: public LongValue mirrorOf(long value) {
0766: return new LongValueImpl(virtualMachineImpl(), new Long(value));
0767: }
0768:
0769: /**
0770: * @return Returns newly created ShortValue for the given value.
0771: */
0772: public ShortValue mirrorOf(short value) {
0773: return new ShortValueImpl(virtualMachineImpl(),
0774: new Short(value));
0775: }
0776:
0777: /**
0778: * @return Returns newly created BooleanValue for the given value.
0779: */
0780: public BooleanValue mirrorOf(boolean value) {
0781: return new BooleanValueImpl(virtualMachineImpl(), Boolean
0782: .valueOf(value));
0783: }
0784:
0785: /**
0786: * @return Returns newly created StringReference for the given value.
0787: */
0788: public StringReference mirrorOf(String value) {
0789: initJdwpRequest();
0790: try {
0791: ByteArrayOutputStream outBytes = new ByteArrayOutputStream();
0792: DataOutputStream outData = new DataOutputStream(outBytes);
0793: writeString(value, "string value", outData); //$NON-NLS-1$
0794:
0795: JdwpReplyPacket replyPacket = requestVM(
0796: JdwpCommandPacket.VM_CREATE_STRING, outBytes);
0797: defaultReplyErrorHandler(replyPacket.errorCode());
0798:
0799: DataInputStream replyData = replyPacket.dataInStream();
0800: StringReference result = StringReferenceImpl.read(this ,
0801: replyData);
0802: return result;
0803: } catch (IOException e) {
0804: defaultIOExceptionHandler(e);
0805: return null;
0806: } finally {
0807: handledJdwpRequest();
0808: }
0809: }
0810:
0811: /**
0812: * Returns a void value from the VM.
0813: *
0814: * @return
0815: */
0816: public VoidValue mirrorOfVoid() {
0817: return new VoidValueImpl(this );
0818: }
0819:
0820: /**
0821: * @return Returns the Process object for this virtual machine if launched by a LaunchingConnector.
0822: */
0823: public Process process() {
0824: return fLaunchedProcess;
0825: }
0826:
0827: /**
0828: * Sets Process object for this virtual machine if launched by a LaunchingConnector.
0829: */
0830: public void setLaunchedProcess(Process proc) {
0831: fLaunchedProcess = proc;
0832: }
0833:
0834: /**
0835: * Continues the execution of the application running in this virtual machine.
0836: */
0837: public void resume() {
0838: initJdwpRequest();
0839: try {
0840: resetThreadEventFlags();
0841: JdwpReplyPacket replyPacket = requestVM(JdwpCommandPacket.VM_RESUME);
0842: defaultReplyErrorHandler(replyPacket.errorCode());
0843: } finally {
0844: handledJdwpRequest();
0845: }
0846: }
0847:
0848: public void setDebugTraceMode(int traceFlags) {
0849: // We don't have trace info.
0850: }
0851:
0852: /**
0853: * Suspends all threads.
0854: */
0855: public void suspend() {
0856: initJdwpRequest();
0857: try {
0858: JdwpReplyPacket replyPacket = requestVM(JdwpCommandPacket.VM_SUSPEND);
0859: defaultReplyErrorHandler(replyPacket.errorCode());
0860: } finally {
0861: handledJdwpRequest();
0862: }
0863: }
0864:
0865: public List topLevelThreadGroups() {
0866: // Note that this information should not be cached.
0867: initJdwpRequest();
0868: try {
0869: JdwpReplyPacket replyPacket = requestVM(JdwpCommandPacket.VM_TOP_LEVEL_THREAD_GROUPS);
0870: defaultReplyErrorHandler(replyPacket.errorCode());
0871:
0872: DataInputStream replyData = replyPacket.dataInStream();
0873: int nrGroups = readInt("nr of groups", replyData); //$NON-NLS-1$
0874: ArrayList result = new ArrayList(nrGroups);
0875: for (int i = 0; i < nrGroups; i++) {
0876: ThreadGroupReferenceImpl threadGroup = ThreadGroupReferenceImpl
0877: .read(this , replyData);
0878: result.add(threadGroup);
0879: }
0880: return result;
0881: } catch (IOException e) {
0882: defaultIOExceptionHandler(e);
0883: return null;
0884: } finally {
0885: handledJdwpRequest();
0886: }
0887: }
0888:
0889: /**
0890: * @return Returns the name of the target VM as reported by the property java.vm.name.
0891: */
0892: public String name() {
0893: getVersionInfo();
0894: return fVMName;
0895: }
0896:
0897: /**
0898: * @return Returns the version of the Java Runtime Environment in the target VM as reported by the property java.version.
0899: */
0900: public String version() {
0901: getVersionInfo();
0902: return fVMVersion;
0903: }
0904:
0905: /**
0906: * @return Returns text information on the target VM and the debugger support that mirrors it.
0907: */
0908: public String description() {
0909: getVersionInfo();
0910: return fVersionDescription;
0911: }
0912:
0913: /**
0914: * Reset event flags of all threads.
0915: */
0916: private void resetThreadEventFlags() {
0917: Iterator iter = allThreads().iterator();
0918: ThreadReferenceImpl thread;
0919: while (iter.hasNext()) {
0920: thread = (ThreadReferenceImpl) iter.next();
0921: thread.resetEventFlags();
0922: }
0923: }
0924:
0925: /**
0926: * Request and fetch ID sizes of Virtual Machine.
0927: */
0928: private void getIDSizes() {
0929: if (fGotIDSizes)
0930: return;
0931:
0932: /*
0933: * fGotIDSizes must first be assigned true to prevent an invinite loop
0934: * because getIDSizes() calls requestVM which calls packetSendManager.
0935: */
0936: fGotIDSizes = true;
0937:
0938: // We use a different mirror to avoid having verbose output mixed with the initiating command.
0939: MirrorImpl mirror = new VoidValueImpl(this );
0940:
0941: mirror.initJdwpRequest();
0942: try {
0943: JdwpReplyPacket replyPacket = mirror
0944: .requestVM(JdwpCommandPacket.VM_ID_SIZES);
0945: mirror.defaultReplyErrorHandler(replyPacket.errorCode());
0946: DataInputStream replyData = replyPacket.dataInStream();
0947:
0948: fFieldIDSize = mirror.readInt("field ID size", replyData); //$NON-NLS-1$
0949: fMethodIDSize = mirror.readInt("method ID size", replyData); //$NON-NLS-1$
0950: fObjectIDSize = mirror.readInt("object ID size", replyData); //$NON-NLS-1$
0951: fReferenceTypeIDSize = mirror.readInt(
0952: "refType ID size", replyData); //$NON-NLS-1$
0953: fFrameIDSize = mirror.readInt("frame ID size", replyData); //$NON-NLS-1$
0954: } catch (IOException e) {
0955: fGotIDSizes = false;
0956: mirror.defaultIOExceptionHandler(e);
0957: } finally {
0958: mirror.handledJdwpRequest();
0959: }
0960: }
0961:
0962: /**
0963: * Retrieves version info of the VM.
0964: */
0965: public void getVersionInfo() {
0966: if (fVersionDescription != null)
0967: return;
0968:
0969: initJdwpRequest();
0970: try {
0971: JdwpReplyPacket replyPacket = requestVM(JdwpCommandPacket.VM_VERSION);
0972: defaultReplyErrorHandler(replyPacket.errorCode());
0973: DataInputStream replyData = replyPacket.dataInStream();
0974:
0975: fVersionDescription = readString(
0976: "version descr.", replyData); //$NON-NLS-1$
0977: fJdwpMajorVersion = readInt("major version", replyData); //$NON-NLS-1$
0978: fJdwpMinorVersion = readInt("minor version", replyData); //$NON-NLS-1$
0979: fVMVersion = readString("version", replyData); //$NON-NLS-1$
0980: fVMName = readString("name", replyData); //$NON-NLS-1$
0981:
0982: if ((fVMName != null) && fVMName.equals("KVM")) { //$NON-NLS-1$
0983: // KVM requires class preparation events in order
0984: // to resolve things correctly
0985: eventRequestManagerImpl()
0986: .enableInternalClassPrepareEvent();
0987: }
0988:
0989: } catch (IOException e) {
0990: fVersionDescription = null;
0991: defaultIOExceptionHandler(e);
0992: } finally {
0993: handledJdwpRequest();
0994: }
0995: }
0996:
0997: /**
0998: * Retrieves the HCR capabilities of the VM.
0999: */
1000: public void getHCRCapabilities() {
1001: if (fHcrCapabilities != null)
1002: return;
1003: fHcrCapabilities = new boolean[HCR_CAN_REENTER_ON_EXIT + 1];
1004:
1005: if (isHCRSupported()) {
1006: initJdwpRequest();
1007: try {
1008: JdwpReplyPacket replyPacket = requestVM(JdwpCommandPacket.HCR_CAPABILITIES);
1009: defaultReplyErrorHandler(replyPacket.errorCode());
1010: DataInputStream replyData = replyPacket.dataInStream();
1011:
1012: fHcrCapabilities[HCR_CAN_RELOAD_CLASSES] = readBoolean(
1013: "reload classes", replyData); //$NON-NLS-1$
1014: fHcrCapabilities[HCR_CAN_GET_CLASS_VERSION] = readBoolean(
1015: "get class version", replyData); //$NON-NLS-1$
1016: fHcrCapabilities[HCR_CAN_DO_RETURN] = readBoolean(
1017: "do return", replyData); //$NON-NLS-1$
1018: fHcrCapabilities[HCR_CAN_REENTER_ON_EXIT] = readBoolean(
1019: "reenter on exit", replyData); //$NON-NLS-1$
1020: } catch (IOException e) {
1021: fHcrCapabilities = null;
1022: defaultIOExceptionHandler(e);
1023: } finally {
1024: handledJdwpRequest();
1025: }
1026: } else {
1027: for (int i = 0; i < fHcrCapabilities.length; i++) {
1028: fHcrCapabilities[i] = false;
1029: }
1030: }
1031: }
1032:
1033: /**
1034: * @return Returns Whether VM can deal with the 'Classes have Changed' command.
1035: */
1036: public boolean canReloadClasses() {
1037: getHCRCapabilities();
1038: return fHcrCapabilities[HCR_CAN_RELOAD_CLASSES];
1039: }
1040:
1041: /**
1042: * @return Returns Whether VM can get the version of a given class file.
1043: */
1044: public boolean canGetClassFileVersion1() {
1045: getHCRCapabilities();
1046: return fHcrCapabilities[HCR_CAN_GET_CLASS_VERSION];
1047: }
1048:
1049: /**
1050: * @see com.sun.jdi.VirtualMachine#canGetClassFileVersion()
1051: * @since 3.3
1052: */
1053: public boolean canGetClassFileVersion() {
1054: return isJdwpVersionGreaterOrEqual(1, 6);
1055: }
1056:
1057: /**
1058: * @see com.sun.jdi.VirtualMachine#canGetConstantPool()
1059: * @since 3.3
1060: */
1061: public boolean canGetConstantPool() {
1062: getCapabilities();
1063: return fCanGetConstantPool;
1064: }
1065:
1066: /**
1067: * @return Returns Whether VM can do a return in the middle of executing a method.
1068: */
1069: public boolean canDoReturn() {
1070: getHCRCapabilities();
1071: return fHcrCapabilities[HCR_CAN_DO_RETURN];
1072: }
1073:
1074: /**
1075: * @return Returns Whether VM can reenter a method on exit.
1076: */
1077: public boolean canReenterOnExit() {
1078: getHCRCapabilities();
1079: return fHcrCapabilities[HCR_CAN_REENTER_ON_EXIT];
1080: }
1081:
1082: /**
1083: * Notify the VM that classes have changed due to Hot Code Replacement.
1084: * @return Returns RELOAD_SUCCESS, RELOAD_FAILURE or RELOAD_IGNORED.
1085: */
1086: public int classesHaveChanged(String[] names) {
1087: checkHCRSupported();
1088: // We convert the class/interface names to signatures.
1089: String[] signatures = new String[names.length];
1090:
1091: initJdwpRequest();
1092: try {
1093: ByteArrayOutputStream outBytes = new ByteArrayOutputStream();
1094: DataOutputStream outData = new DataOutputStream(outBytes);
1095: writeInt(names.length, "length", outData); //$NON-NLS-1$
1096: for (int i = 0; i < names.length; i++) {
1097: signatures[i] = TypeImpl.classNameToSignature(names[i]);
1098: writeString(signatures[i], "signature", outData); //$NON-NLS-1$
1099: }
1100:
1101: JdwpReplyPacket replyPacket = requestVM(
1102: JdwpCommandPacket.HCR_CLASSES_HAVE_CHANGED,
1103: outBytes);
1104: defaultReplyErrorHandler(replyPacket.errorCode());
1105: DataInputStream replyData = replyPacket.dataInStream();
1106:
1107: byte resultFlag = readByte(
1108: "result", resultHCRMap(), replyData); //$NON-NLS-1$
1109: switch (resultFlag) {
1110: case HCR_RELOAD_SUCCESS:
1111: return RELOAD_SUCCESS;
1112: case HCR_RELOAD_FAILURE:
1113: return RELOAD_FAILURE;
1114: case HCR_RELOAD_IGNORED:
1115: return RELOAD_IGNORED;
1116: }
1117: throw new InternalError(
1118: JDIMessages.VirtualMachineImpl_Invalid_result_flag_in_Classes_Have_Changed_response___3
1119: + resultFlag
1120: + JDIMessages.VirtualMachineImpl__4); //
1121: } catch (IOException e) {
1122: defaultIOExceptionHandler(e);
1123: return 0;
1124: } finally {
1125: handledJdwpRequest();
1126: }
1127: }
1128:
1129: /**
1130: * @return Returns description of Mirror object.
1131: */
1132: public String toString() {
1133: try {
1134: return name();
1135: } catch (Exception e) {
1136: return fDescription;
1137: }
1138: }
1139:
1140: /**
1141: * Retrieves constant mappings.
1142: */
1143: public static void getConstantMaps() {
1144: if (fgHCRResultMap != null) {
1145: return;
1146: }
1147:
1148: Field[] fields = VirtualMachineImpl.class.getDeclaredFields();
1149: fgHCRResultMap = new HashMap();
1150: for (int i = 0; i < fields.length; i++) {
1151: Field field = fields[i];
1152: if ((field.getModifiers() & Modifier.PUBLIC) == 0
1153: || (field.getModifiers() & Modifier.STATIC) == 0
1154: || (field.getModifiers() & Modifier.FINAL) == 0) {
1155: continue;
1156: }
1157:
1158: try {
1159: String name = field.getName();
1160: if (name.startsWith("HCR_RELOAD_")) { //$NON-NLS-1$
1161: Integer intValue = new Integer(field.getInt(null));
1162: name = name.substring(4);
1163: fgHCRResultMap.put(intValue, name);
1164: }
1165: } catch (IllegalAccessException e) {
1166: // Will not occur for own class.
1167: } catch (IllegalArgumentException e) {
1168: // Should not occur.
1169: // We should take care that all public static final constants
1170: // in this class are numbers that are convertible to int.
1171: }
1172: }
1173: }
1174:
1175: /**
1176: * @return Returns a map with string representations of tags.
1177: */
1178: public static Map resultHCRMap() {
1179: getConstantMaps();
1180: return fgHCRResultMap;
1181: }
1182:
1183: /**
1184: * Sets request timeout in ms.
1185: */
1186: public void setRequestTimeout(int timeout) {
1187: fRequestTimeout = timeout;
1188: }
1189:
1190: /**
1191: * @return Returns request timeout in ms.
1192: */
1193: public int getRequestTimeout() {
1194: return fRequestTimeout;
1195: }
1196:
1197: /**
1198: * Returns whether the JDWP version is greater
1199: * than or equal to the specified major/minor
1200: * version numbers.
1201: *
1202: * @return whether the JDWP version is greater
1203: * than or equal to the specified major/minor
1204: * version numbers
1205: */
1206: public boolean isJdwpVersionGreaterOrEqual(int major, int minor) {
1207: getVersionInfo();
1208: return (fJdwpMajorVersion > major)
1209: || (fJdwpMajorVersion == major && fJdwpMinorVersion >= minor);
1210: }
1211:
1212: public void redefineClasses(Map typesToBytes) {
1213: if (!canRedefineClasses()) {
1214: throw new UnsupportedOperationException();
1215: }
1216:
1217: initJdwpRequest();
1218: try {
1219: ByteArrayOutputStream outBytes = new ByteArrayOutputStream();
1220: DataOutputStream outData = new DataOutputStream(outBytes);
1221: writeInt(typesToBytes.size(), "classes", outData); //$NON-NLS-1$
1222:
1223: Set types = typesToBytes.keySet();
1224: Iterator iter = types.iterator();
1225: while (iter.hasNext()) {
1226: ReferenceTypeImpl type = (ReferenceTypeImpl) iter
1227: .next();
1228: type.write(this , outData);
1229: byte[] bytes = (byte[]) typesToBytes.get(type);
1230: writeInt(bytes.length, "classfile", outData); //$NON-NLS-1$
1231: for (int i = 0; i < bytes.length; i++) {
1232: writeByte(bytes[i], "classByte", outData); //$NON-NLS-1$
1233: }
1234: fCachedReftypes.remove(type.getRefTypeID()); // flush local cache of redefined types
1235: }
1236:
1237: JdwpReplyPacket reply = requestVM(
1238: JdwpCommandPacket.VM_REDEFINE_CLASSES, outBytes);
1239: switch (reply.errorCode()) {
1240: case JdwpReplyPacket.UNSUPPORTED_VERSION:
1241: throw new UnsupportedClassVersionError();
1242: case JdwpReplyPacket.INVALID_CLASS_FORMAT:
1243: throw new ClassFormatError();
1244: case JdwpReplyPacket.CIRCULAR_CLASS_DEFINITION:
1245: throw new ClassCircularityError();
1246: case JdwpReplyPacket.FAILS_VERIFICATION:
1247: throw new VerifyError();
1248: case JdwpReplyPacket.NAMES_DONT_MATCH:
1249: throw new NoClassDefFoundError();
1250: case JdwpReplyPacket.ADD_METHOD_NOT_IMPLEMENTED:
1251: throw new UnsupportedOperationException(
1252: JDIMessages.VirtualMachineImpl_Add_method_not_implemented_1);
1253: case JdwpReplyPacket.SCHEMA_CHANGE_NOT_IMPLEMENTED:
1254: throw new UnsupportedOperationException(
1255: JDIMessages.VirtualMachineImpl_Scheme_change_not_implemented_2);
1256: case JdwpReplyPacket.HIERARCHY_CHANGE_NOT_IMPLEMENTED:
1257: throw new UnsupportedOperationException(
1258: JDIMessages.VirtualMachineImpl_Hierarchy_change_not_implemented_3);
1259: case JdwpReplyPacket.DELETE_METHOD_NOT_IMPLEMENTED:
1260: throw new UnsupportedOperationException(
1261: JDIMessages.VirtualMachineImpl_Delete_method_not_implemented_4);
1262: case JdwpReplyPacket.CLASS_MODIFIERS_CHANGE_NOT_IMPLEMENTED:
1263: throw new UnsupportedOperationException(
1264: JDIMessages.VirtualMachineImpl_Class_modifiers_change_not_implemented_5);
1265: case JdwpReplyPacket.METHOD_MODIFIERS_CHANGE_NOT_IMPLEMENTED:
1266: throw new UnsupportedOperationException(
1267: JDIMessages.VirtualMachineImpl_Method_modifiers_change_not_implemented_6);
1268: default:
1269: defaultReplyErrorHandler(reply.errorCode());
1270: }
1271: } catch (IOException ioe) {
1272: defaultIOExceptionHandler(ioe);
1273: return;
1274: } finally {
1275: handledJdwpRequest();
1276: }
1277: }
1278:
1279: /*
1280: * @see VirtualMachine#canRedefineClasses()
1281: */
1282: public boolean canRedefineClasses() {
1283: getCapabilities();
1284: return fCanRedefineClasses;
1285: }
1286:
1287: /*
1288: * @see VirtualMachine#canUseInstanceFilters()
1289: */
1290: public boolean canUseInstanceFilters() {
1291: getCapabilities();
1292: return fCanUseInstanceFilters;
1293: }
1294:
1295: /*
1296: * @see VirtualMachine#canAddMethod()
1297: */
1298: public boolean canAddMethod() {
1299: getCapabilities();
1300: return fCanAddMethod;
1301: }
1302:
1303: /*
1304: * @see VirtualMachine#canUnrestrictedlyRedefineClasses()
1305: */
1306: public boolean canUnrestrictedlyRedefineClasses() {
1307: getCapabilities();
1308: return fCanUnrestrictedlyRedefineClasses;
1309: }
1310:
1311: /**
1312: * @see com.sun.jdi.VirtualMachine#canUseSourceNameFilters()
1313: * @since 3.3
1314: */
1315: public boolean canUseSourceNameFilters() {
1316: getCapabilities();
1317: return fCanUseSourceNameFilters;
1318: }
1319:
1320: /*
1321: * @see VirtualMachine#canPopFrames()
1322: */
1323: public boolean canPopFrames() {
1324: getCapabilities();
1325: return fCanPopFrames;
1326: }
1327:
1328: /*
1329: * @see VirtualMachine#canGetSourceDebugExtension()
1330: */
1331: public boolean canGetSourceDebugExtension() {
1332: getCapabilities();
1333: return fCanGetSourceDebugExtension;
1334: }
1335:
1336: /*
1337: * @see VirtualMachine#canRequestVMDeathEvent()
1338: */
1339: public boolean canRequestVMDeathEvent() {
1340: getCapabilities();
1341: return fCanRequestVMDeathEvent;
1342: }
1343:
1344: public boolean canSetDefaultStratum() {
1345: getCapabilities();
1346: return fCanSetDefaultStratum;
1347: }
1348:
1349: /*
1350: * @see VirtualMachine#setDefaultStratum(String)
1351: */
1352: public void setDefaultStratum(String stratum) {
1353: fDefaultStratum = stratum;
1354:
1355: if (!canSetDefaultStratum()) {
1356: // TODO: how to inform the user that the VM doesn't manage setDefaultStartum ?
1357: return;
1358: }
1359: if (stratum == null) {
1360: stratum = ""; //$NON-NLS-1$
1361: }
1362: initJdwpRequest();
1363: try {
1364: ByteArrayOutputStream outBytes = new ByteArrayOutputStream();
1365: DataOutputStream outData = new DataOutputStream(outBytes);
1366: writeString(stratum, "stratum ID", outData); //$NON-NLS-1$
1367:
1368: JdwpReplyPacket replyPacket = requestVM(
1369: JdwpCommandPacket.VM_SET_DEFAULT_STRATUM, outBytes);
1370: defaultReplyErrorHandler(replyPacket.errorCode());
1371:
1372: } catch (IOException e) {
1373: defaultIOExceptionHandler(e);
1374: } finally {
1375: handledJdwpRequest();
1376: }
1377: }
1378:
1379: /*
1380: * @see VirtualMachine#getDefaultStratum()
1381: */
1382: public String getDefaultStratum() {
1383: return fDefaultStratum;
1384: }
1385:
1386: /**
1387: * @see com.sun.jdi.VirtualMachine#instanceCounts(java.util.List)
1388: * @since 3.3
1389: */
1390: public long[] instanceCounts(List refTypes) {
1391: if (refTypes == null) {
1392: throw new NullPointerException(
1393: JDIMessages.VirtualMachineImpl_2);
1394: }
1395: int size = refTypes.size();
1396: if (size == 0) {
1397: if (isJdwpVersionGreaterOrEqual(1, 6)) {
1398: return new long[0];
1399: } else {
1400: throw new UnsupportedOperationException(
1401: JDIMessages.ReferenceTypeImpl_27);
1402: }
1403: }
1404: try {
1405: ByteArrayOutputStream outBytes = new ByteArrayOutputStream();
1406: DataOutputStream outData = new DataOutputStream(outBytes);
1407: writeInt(size, "size", outData); //$NON-NLS-1$
1408: for (int i = 0; i < size; i++) {
1409: ((ReferenceTypeImpl) refTypes.get(i)).getRefTypeID()
1410: .write(outData);
1411: }
1412: JdwpReplyPacket replyPacket = requestVM(
1413: JdwpCommandPacket.VM_INSTANCE_COUNTS, outBytes);
1414: switch (replyPacket.errorCode()) {
1415: case JdwpReplyPacket.INVALID_CLASS:
1416: case JdwpReplyPacket.INVALID_OBJECT:
1417: throw new ObjectCollectedException(
1418: JDIMessages.class_or_object_not_known);
1419: case JdwpReplyPacket.ILLEGAL_ARGUMENT:
1420: throw new IllegalArgumentException(
1421: JDIMessages.VirtualMachineImpl_count_less_than_zero);
1422: case JdwpReplyPacket.NOT_IMPLEMENTED:
1423: throw new UnsupportedOperationException(
1424: JDIMessages.ReferenceTypeImpl_27);
1425: case JdwpReplyPacket.VM_DEAD:
1426: throw new VMDisconnectedException(JDIMessages.vm_dead);
1427: }
1428: defaultReplyErrorHandler(replyPacket.errorCode());
1429:
1430: DataInputStream replyData = replyPacket.dataInStream();
1431: int counts = readInt("counts", replyData); //$NON-NLS-1$
1432: if (counts != size) {
1433: throw new InternalError(
1434: JDIMessages.VirtualMachineImpl_3);
1435: }
1436: long[] ret = new long[counts];
1437: for (int i = 0; i < counts; i++) {
1438: ret[i] = readLong("ref count", replyData); //$NON-NLS-1$
1439: }
1440: return ret;
1441: } catch (IOException e) {
1442: defaultIOExceptionHandler(e);
1443: return null;
1444: } finally {
1445: handledJdwpRequest();
1446: }
1447: }
1448:
1449: /**
1450: * Returns whether this VM is disconnected.
1451: *
1452: * @return whether this VM is disconnected
1453: */
1454: public boolean isDisconnected() {
1455: return fIsDisconnected;
1456: }
1457:
1458: /**
1459: * Sets whether this VM is disconnected.
1460: *
1461: * @param disconected whether this VM is disconnected
1462: */
1463: public synchronized void setDisconnected(boolean disconnected) {
1464: fIsDisconnected = disconnected;
1465: }
1466:
1467: /**
1468: * Return the boolean type for this VM.
1469: */
1470: protected BooleanTypeImpl getBooleanType() {
1471: if (fBooleanType == null) {
1472: fBooleanType = new BooleanTypeImpl(this );
1473: }
1474: return fBooleanType;
1475: }
1476:
1477: /**
1478: * Return the byte type for this VM.
1479: */
1480: protected ByteTypeImpl getByteType() {
1481: if (fByteType == null) {
1482: fByteType = new ByteTypeImpl(this );
1483: }
1484: return fByteType;
1485: }
1486:
1487: /**
1488: * Return the char type for this VM.
1489: */
1490: protected CharTypeImpl getCharType() {
1491: if (fCharType == null) {
1492: fCharType = new CharTypeImpl(this );
1493: }
1494: return fCharType;
1495: }
1496:
1497: /**
1498: * Return the double type for this VM.
1499: */
1500: protected DoubleTypeImpl getDoubleType() {
1501: if (fDoubleType == null) {
1502: fDoubleType = new DoubleTypeImpl(this );
1503: }
1504: return fDoubleType;
1505: }
1506:
1507: /**
1508: * Return the float type for this VM.
1509: */
1510: protected FloatTypeImpl getFloatType() {
1511: if (fFloatType == null) {
1512: fFloatType = new FloatTypeImpl(this );
1513: }
1514: return fFloatType;
1515: }
1516:
1517: /**
1518: * Return the integer type for this VM.
1519: */
1520: protected IntegerTypeImpl getIntegerType() {
1521: if (fIntegerType == null) {
1522: fIntegerType = new IntegerTypeImpl(this );
1523: }
1524: return fIntegerType;
1525: }
1526:
1527: /**
1528: * Return the long type for this VM.
1529: */
1530: protected LongTypeImpl getLongType() {
1531: if (fLongType == null) {
1532: fLongType = new LongTypeImpl(this );
1533: }
1534: return fLongType;
1535: }
1536:
1537: /**
1538: * Return the short type for this VM.
1539: */
1540: protected ShortTypeImpl getShortType() {
1541: if (fShortType == null) {
1542: fShortType = new ShortTypeImpl(this );
1543: }
1544: return fShortType;
1545: }
1546:
1547: /*
1548: * (non-Javadoc)
1549: * @see com.sun.jdi.VirtualMachine#canBeModified()
1550: */
1551: public boolean canBeModified() {
1552: return true;
1553: }
1554:
1555: }
|