Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/tools/jconsole/LocalVirtualMachine.java
38918 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;3031// Sun specific32import com.sun.tools.attach.VirtualMachine;33import com.sun.tools.attach.VirtualMachineDescriptor;34import com.sun.tools.attach.AttachNotSupportedException;3536// Sun private37import sun.management.ConnectorAddressLink;38import sun.jvmstat.monitor.HostIdentifier;39import sun.jvmstat.monitor.MonitoredHost;40import sun.jvmstat.monitor.MonitoredVm;41import sun.jvmstat.monitor.MonitoredVmUtil;42import sun.jvmstat.monitor.MonitorException;43import sun.jvmstat.monitor.VmIdentifier;4445public class LocalVirtualMachine {46private String address;47private String commandLine;48private String displayName;49private int vmid;50private boolean isAttachSupported;5152public LocalVirtualMachine(int vmid, String commandLine, boolean canAttach, String connectorAddress) {53this.vmid = vmid;54this.commandLine = commandLine;55this.address = connectorAddress;56this.isAttachSupported = canAttach;57this.displayName = getDisplayName(commandLine);58}5960private static String getDisplayName(String commandLine) {61// trim the pathname of jar file if it's a jar62String[] res = commandLine.split(" ", 2);63if (res[0].endsWith(".jar")) {64File jarfile = new File(res[0]);65String displayName = jarfile.getName();66if (res.length == 2) {67displayName += " " + res[1];68}69return displayName;70}71return commandLine;72}7374public int vmid() {75return vmid;76}7778public boolean isManageable() {79return (address != null);80}8182public boolean isAttachable() {83return isAttachSupported;84}8586public void startManagementAgent() throws IOException {87if (address != null) {88// already started89return;90}9192if (!isAttachable()) {93throw new IOException("This virtual machine \"" + vmid +94"\" does not support dynamic attach.");95}9697loadManagementAgent();98// fails to load or start the management agent99if (address == null) {100// should never reach here101throw new IOException("Fails to find connector address");102}103}104105public String connectorAddress() {106// return null if not available or no JMX agent107return address;108}109110public String displayName() {111return displayName;112}113114public String toString() {115return commandLine;116}117118// This method returns the list of all virtual machines currently119// running on the machine120public static Map<Integer, LocalVirtualMachine> getAllVirtualMachines() {121Map<Integer, LocalVirtualMachine> map =122new HashMap<Integer, LocalVirtualMachine>();123getMonitoredVMs(map);124getAttachableVMs(map);125return map;126}127128private static void getMonitoredVMs(Map<Integer, LocalVirtualMachine> map) {129MonitoredHost host;130Set<Integer> vms;131try {132host = MonitoredHost.getMonitoredHost(new HostIdentifier((String)null));133vms = host.activeVms();134} catch (java.net.URISyntaxException | MonitorException x) {135throw new InternalError(x.getMessage(), x);136}137for (Object vmid: vms) {138if (vmid instanceof Integer) {139int pid = ((Integer) vmid).intValue();140String name = vmid.toString(); // default to pid if name not available141boolean attachable = false;142String address = null;143try {144MonitoredVm mvm = host.getMonitoredVm(new VmIdentifier(name));145// use the command line as the display name146name = MonitoredVmUtil.commandLine(mvm);147attachable = MonitoredVmUtil.isAttachable(mvm);148address = ConnectorAddressLink.importFrom(pid);149mvm.detach();150} catch (Exception x) {151// ignore152}153map.put((Integer) vmid,154new LocalVirtualMachine(pid, name, attachable, address));155}156}157}158159private static final String LOCAL_CONNECTOR_ADDRESS_PROP =160"com.sun.management.jmxremote.localConnectorAddress";161162private static void getAttachableVMs(Map<Integer, LocalVirtualMachine> map) {163List<VirtualMachineDescriptor> vms = VirtualMachine.list();164for (VirtualMachineDescriptor vmd : vms) {165try {166Integer vmid = Integer.valueOf(vmd.id());167if (!map.containsKey(vmid)) {168boolean attachable = false;169String address = null;170try {171VirtualMachine vm = VirtualMachine.attach(vmd);172attachable = true;173Properties agentProps = vm.getAgentProperties();174address = (String) agentProps.get(LOCAL_CONNECTOR_ADDRESS_PROP);175vm.detach();176} catch (AttachNotSupportedException x) {177// not attachable178} catch (IOException x) {179// ignore180}181map.put(vmid, new LocalVirtualMachine(vmid.intValue(),182vmd.displayName(),183attachable,184address));185}186} catch (NumberFormatException e) {187// do not support vmid different than pid188}189}190}191192public static LocalVirtualMachine getLocalVirtualMachine(int vmid) {193Map<Integer, LocalVirtualMachine> map = getAllVirtualMachines();194LocalVirtualMachine lvm = map.get(vmid);195if (lvm == null) {196// Check if the VM is attachable but not included in the list197// if it's running with a different security context.198// For example, Windows services running199// local SYSTEM account are attachable if you have Adminstrator200// privileges.201boolean attachable = false;202String address = null;203String name = String.valueOf(vmid); // default display name to pid204try {205VirtualMachine vm = VirtualMachine.attach(name);206attachable = true;207Properties agentProps = vm.getAgentProperties();208address = (String) agentProps.get(LOCAL_CONNECTOR_ADDRESS_PROP);209vm.detach();210lvm = new LocalVirtualMachine(vmid, name, attachable, address);211} catch (AttachNotSupportedException x) {212// not attachable213if (JConsole.isDebug()) {214x.printStackTrace();215}216} catch (IOException x) {217// ignore218if (JConsole.isDebug()) {219x.printStackTrace();220}221}222}223return lvm;224}225226// load the management agent into the target VM227private void loadManagementAgent() throws IOException {228VirtualMachine vm = null;229String name = String.valueOf(vmid);230try {231vm = VirtualMachine.attach(name);232} catch (AttachNotSupportedException x) {233IOException ioe = new IOException(x.getMessage());234ioe.initCause(x);235throw ioe;236}237238vm.startLocalManagementAgent();239240// get the connector address241Properties agentProps = vm.getAgentProperties();242address = (String) agentProps.get(LOCAL_CONNECTOR_ADDRESS_PROP);243244vm.detach();245}246}247248249