001: /*
002: * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025: package sun.tools.attach;
026:
027: import com.sun.tools.attach.VirtualMachineDescriptor;
028: import com.sun.tools.attach.VirtualMachine;
029: import com.sun.tools.attach.AttachPermission;
030: import com.sun.tools.attach.AttachNotSupportedException;
031: import com.sun.tools.attach.spi.AttachProvider;
032:
033: import java.io.IOException;
034: import java.util.List;
035: import java.util.Iterator;
036: import java.util.ArrayList;
037: import java.util.Set;
038: import java.net.URISyntaxException;
039:
040: import sun.jvmstat.monitor.HostIdentifier;
041: import sun.jvmstat.monitor.Monitor;
042: import sun.jvmstat.monitor.MonitoredHost;
043: import sun.jvmstat.monitor.MonitoredVm;
044: import sun.jvmstat.monitor.MonitoredVmUtil;
045: import sun.jvmstat.monitor.VmIdentifier;
046: import sun.jvmstat.monitor.MonitorException;
047:
048: /*
049: * Platform specific provider implementations extend this
050: */
051: public abstract class HotSpotAttachProvider extends AttachProvider {
052:
053: // perf count name for the JVM version
054: private static final String JVM_VERSION = "java.property.java.vm.version";
055:
056: public HotSpotAttachProvider() {
057: }
058:
059: public void checkAttachPermission() {
060: SecurityManager sm = System.getSecurityManager();
061: if (sm != null) {
062: sm.checkPermission(new AttachPermission(
063: "attachVirtualMachine"));
064: }
065: }
066:
067: /*
068: * This listVirtualMachines implementation is based on jvmstat. Can override
069: * this in platform implementations when there is a more efficient mechanism
070: * available.
071: */
072: public List<VirtualMachineDescriptor> listVirtualMachines() {
073: ArrayList<VirtualMachineDescriptor> result = new ArrayList<VirtualMachineDescriptor>();
074:
075: MonitoredHost host;
076: Set vms;
077: try {
078: host = MonitoredHost.getMonitoredHost(new HostIdentifier(
079: (String) null));
080: vms = host.activeVms();
081: } catch (Throwable t) {
082: if (t instanceof ExceptionInInitializerError) {
083: t = t.getCause();
084: }
085: if (t instanceof ThreadDeath) {
086: throw (ThreadDeath) t;
087: }
088: if (t instanceof SecurityException) {
089: return result;
090: }
091: throw new InternalError(); // shouldn't happen
092: }
093:
094: for (Object vmid : vms) {
095: if (vmid instanceof Integer) {
096: String pid = vmid.toString();
097: String name = pid; // default to pid if name not available
098: boolean isAttachable = false;
099: MonitoredVm mvm = null;
100: try {
101: mvm = host.getMonitoredVm(new VmIdentifier(pid));
102: try {
103: isAttachable = MonitoredVmUtil
104: .isAttachable(mvm);
105: // use the command line as the display name
106: name = MonitoredVmUtil.commandLine(mvm);
107: } catch (Exception e) {
108: }
109: if (isAttachable) {
110: result.add(new HotSpotVirtualMachineDescriptor(
111: this , pid, name));
112: }
113: } catch (Throwable t) {
114: if (t instanceof ThreadDeath) {
115: throw (ThreadDeath) t;
116: }
117: } finally {
118: if (mvm != null) {
119: mvm.detach();
120: }
121: }
122: }
123: }
124: return result;
125: }
126:
127: /**
128: * Test if a VM is attachable. If it's not attachable,
129: * an AttachNotSupportedException will be thrown. For example,
130: * 1.4.2 or 5.0 VM are not attachable. There are cases that
131: * we can't determine if a VM is attachable or not and this method
132: * will just return.
133: *
134: * This method uses the jvmstat counter to determine if a VM
135: * is attachable. If the target VM does not have a jvmstat
136: * share memory buffer, this method returns.
137: *
138: * @exception AttachNotSupportedException if it's not attachable
139: */
140: void testAttachable(String id) throws AttachNotSupportedException {
141: MonitoredVm mvm = null;
142: boolean isKernelVM = false;
143: try {
144: VmIdentifier vmid = new VmIdentifier(id);
145: MonitoredHost host = MonitoredHost.getMonitoredHost(vmid);
146: mvm = host.getMonitoredVm(vmid);
147:
148: if (MonitoredVmUtil.isAttachable(mvm)) {
149: // it's attachable; so return false
150: return;
151: }
152: isKernelVM = MonitoredVmUtil.isKernelVM(mvm);
153: } catch (Throwable t) {
154: if (t instanceof ThreadDeath) {
155: ThreadDeath td = (ThreadDeath) t;
156: throw td;
157: }
158: // we do not know what this id is
159: return;
160: } finally {
161: if (mvm != null) {
162: mvm.detach();
163: }
164: }
165:
166: // we're sure it's not attachable; throw exception
167: if (isKernelVM) {
168: throw new AttachNotSupportedException(
169: "Kernel VM does not support the attach mechanism");
170: } else {
171: throw new AttachNotSupportedException(
172: "The VM does not support the attach mechanism");
173: }
174: }
175:
176: /**
177: * A virtual machine descriptor to describe a HotSpot virtual machine.
178: */
179: static class HotSpotVirtualMachineDescriptor extends
180: VirtualMachineDescriptor {
181: HotSpotVirtualMachineDescriptor(AttachProvider provider,
182: String id, String displayName) {
183: super (provider, id, displayName);
184: }
185:
186: public boolean isAttachable() {
187: return true;
188: }
189: }
190: }
|