Path: blob/master/src/jdk.jconsole/share/classes/sun/tools/jconsole/LocalVirtualMachine.java
40948 views
/*1* Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.tools.jconsole;2627import java.util.*;28import java.io.IOException;29import java.io.File;3031import com.sun.tools.attach.VirtualMachine;32import com.sun.tools.attach.VirtualMachineDescriptor;33import com.sun.tools.attach.AttachNotSupportedException;3435import jdk.internal.agent.ConnectorAddressLink;36import sun.jvmstat.monitor.HostIdentifier;37import sun.jvmstat.monitor.MonitoredHost;38import sun.jvmstat.monitor.MonitoredVm;39import sun.jvmstat.monitor.MonitoredVmUtil;40import sun.jvmstat.monitor.MonitorException;41import sun.jvmstat.monitor.VmIdentifier;4243public class LocalVirtualMachine {44private String address;45private String commandLine;46private String displayName;47private int vmid;48private boolean isAttachSupported;4950public LocalVirtualMachine(int vmid, String commandLine, boolean canAttach, String connectorAddress) {51this.vmid = vmid;52this.commandLine = commandLine;53this.address = connectorAddress;54this.isAttachSupported = canAttach;55this.displayName = getDisplayName(commandLine);56}5758private static String getDisplayName(String commandLine) {59// trim the pathname of jar file if it's a jar60String[] res = commandLine.split(" ", 2);61if (res[0].endsWith(".jar")) {62File jarfile = new File(res[0]);63String displayName = jarfile.getName();64if (res.length == 2) {65displayName += " " + res[1];66}67return displayName;68}69return commandLine;70}7172public int vmid() {73return vmid;74}7576public boolean isManageable() {77return (address != null);78}7980public boolean isAttachable() {81return isAttachSupported;82}8384public void startManagementAgent() throws IOException {85if (address != null) {86// already started87return;88}8990if (!isAttachable()) {91throw new IOException("This virtual machine \"" + vmid +92"\" does not support dynamic attach.");93}9495loadManagementAgent();96// fails to load or start the management agent97if (address == null) {98// should never reach here99throw new IOException("Fails to find connector address");100}101}102103public String connectorAddress() {104// return null if not available or no JMX agent105return address;106}107108public String displayName() {109return displayName;110}111112public String toString() {113return commandLine;114}115116// This method returns the list of all virtual machines currently117// running on the machine118public static Map<Integer, LocalVirtualMachine> getAllVirtualMachines() {119Map<Integer, LocalVirtualMachine> map =120new HashMap<Integer, LocalVirtualMachine>();121getMonitoredVMs(map);122getAttachableVMs(map);123return map;124}125126private static void getMonitoredVMs(Map<Integer, LocalVirtualMachine> map) {127MonitoredHost host;128Set<Integer> vms;129try {130host = MonitoredHost.getMonitoredHost(new HostIdentifier((String)null));131vms = host.activeVms();132} catch (java.net.URISyntaxException | MonitorException x) {133throw new InternalError(x.getMessage(), x);134}135for (Object vmid: vms) {136if (vmid instanceof Integer) {137int pid = ((Integer) vmid).intValue();138String name = vmid.toString(); // default to pid if name not available139boolean attachable = false;140String address = null;141try {142MonitoredVm mvm = host.getMonitoredVm(new VmIdentifier(name));143// use the command line as the display name144name = MonitoredVmUtil.commandLine(mvm);145attachable = MonitoredVmUtil.isAttachable(mvm);146address = ConnectorAddressLink.importFrom(pid);147mvm.detach();148} catch (Exception x) {149// ignore150}151map.put((Integer) vmid,152new LocalVirtualMachine(pid, name, attachable, address));153}154}155}156157private static final String LOCAL_CONNECTOR_ADDRESS_PROP =158"com.sun.management.jmxremote.localConnectorAddress";159160private static void getAttachableVMs(Map<Integer, LocalVirtualMachine> map) {161List<VirtualMachineDescriptor> vms = VirtualMachine.list();162for (VirtualMachineDescriptor vmd : vms) {163try {164Integer vmid = Integer.valueOf(vmd.id());165if (!map.containsKey(vmid)) {166boolean attachable = false;167String address = null;168try {169VirtualMachine vm = VirtualMachine.attach(vmd);170attachable = true;171Properties agentProps = vm.getAgentProperties();172address = (String) agentProps.get(LOCAL_CONNECTOR_ADDRESS_PROP);173vm.detach();174} catch (AttachNotSupportedException x) {175// not attachable176} catch (IOException x) {177// ignore178}179map.put(vmid, new LocalVirtualMachine(vmid.intValue(),180vmd.displayName(),181attachable,182address));183}184} catch (NumberFormatException e) {185// do not support vmid different than pid186}187}188}189190public static LocalVirtualMachine getLocalVirtualMachine(int vmid) {191Map<Integer, LocalVirtualMachine> map = getAllVirtualMachines();192LocalVirtualMachine lvm = map.get(vmid);193if (lvm == null) {194// Check if the VM is attachable but not included in the list195// if it's running with a different security context.196// For example, Windows services running197// local SYSTEM account are attachable if you have Adminstrator198// privileges.199boolean attachable = false;200String address = null;201String name = String.valueOf(vmid); // default display name to pid202try {203VirtualMachine vm = VirtualMachine.attach(name);204attachable = true;205Properties agentProps = vm.getAgentProperties();206address = (String) agentProps.get(LOCAL_CONNECTOR_ADDRESS_PROP);207vm.detach();208lvm = new LocalVirtualMachine(vmid, name, attachable, address);209} catch (AttachNotSupportedException x) {210// not attachable211if (JConsole.isDebug()) {212x.printStackTrace();213}214} catch (IOException x) {215// ignore216if (JConsole.isDebug()) {217x.printStackTrace();218}219}220}221return lvm;222}223224// load the management agent into the target VM225private void loadManagementAgent() throws IOException {226VirtualMachine vm = null;227String name = String.valueOf(vmid);228try {229vm = VirtualMachine.attach(name);230} catch (AttachNotSupportedException x) {231IOException ioe = new IOException(x.getMessage());232ioe.initCause(x);233throw ioe;234}235236vm.startLocalManagementAgent();237238// get the connector address239Properties agentProps = vm.getAgentProperties();240address = (String) agentProps.get(LOCAL_CONNECTOR_ADDRESS_PROP);241242vm.detach();243}244}245246247