Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/com/sun/tools/attach/VirtualMachine.java
38920 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 com.sun.tools.attach;2627import com.sun.tools.attach.spi.AttachProvider;28import java.util.ArrayList;29import java.util.List;30import java.util.Properties;31import java.io.IOException;323334/**35* A Java virtual machine.36*37* <p> A <code>VirtualMachine</code> represents a Java virtual machine to which this38* Java virtual machine has attached. The Java virtual machine to which it is39* attached is sometimes called the <i>target virtual machine</i>, or <i>target VM</i>.40* An application (typically a tool such as a managemet console or profiler) uses a41* VirtualMachine to load an agent into the target VM. For example, a profiler tool42* written in the Java Language might attach to a running application and load its43* profiler agent to profile the running application. </p>44*45* <p> A VirtualMachine is obtained by invoking the {@link #attach(String) attach} method46* with an identifier that identifies the target virtual machine. The identifier is47* implementation-dependent but is typically the process identifier (or pid) in48* environments where each Java virtual machine runs in its own operating system process.49* Alternatively, a <code>VirtualMachine</code> instance is obtained by invoking the50* {@link #attach(VirtualMachineDescriptor) attach} method with a {@link51* com.sun.tools.attach.VirtualMachineDescriptor VirtualMachineDescriptor} obtained52* from the list of virtual machine descriptors returned by the {@link #list list} method.53* Once a reference to a virtual machine is obtained, the {@link #loadAgent loadAgent},54* {@link #loadAgentLibrary loadAgentLibrary}, and {@link #loadAgentPath loadAgentPath}55* methods are used to load agents into target virtual machine. The {@link56* #loadAgent loadAgent} method is used to load agents that are written in the Java57* Language and deployed in a {@link java.util.jar.JarFile JAR file}. (See58* {@link java.lang.instrument} for a detailed description on how these agents59* are loaded and started). The {@link #loadAgentLibrary loadAgentLibrary} and60* {@link #loadAgentPath loadAgentPath} methods are used to load agents that61* are deployed either in a dynamic library or statically linked into the VM and make use of the <a62* href="../../../../../../../../technotes/guides/jvmti/index.html">JVM Tools63* Interface</a>. </p>64*65* <p> In addition to loading agents a VirtualMachine provides read access to the66* {@link java.lang.System#getProperties() system properties} in the target VM.67* This can be useful in some environments where properties such as68* <code>java.home</code>, <code>os.name</code>, or <code>os.arch</code> are69* used to construct the path to agent that will be loaded into the target VM.70*71* <p> The following example demonstrates how VirtualMachine may be used:</p>72*73* <pre>74*75* // attach to target VM76* VirtualMachine vm = VirtualMachine.attach("2177");77*78* // start management agent79* Properties props = new Properties();80* props.put("com.sun.management.jmxremote.port", "5000");81* vm.startManagementAgent(props);82*83* // detach84* vm.detach();85*86* </pre>87*88* <p> In this example we attach to a Java virtual machine that is identified by89* the process identifier <code>2177</code>. Then the JMX management agent is90* started in the target process using the supplied arguments. Finally, the91* client detaches from the target VM. </p>92*93* <p> A VirtualMachine is safe for use by multiple concurrent threads. </p>94*95* @since 1.696*/9798@jdk.Exported99public abstract class VirtualMachine {100private AttachProvider provider;101private String id;102private volatile int hash; // 0 => not computed103104/**105* Initializes a new instance of this class.106*107* @param provider108* The attach provider creating this class.109* @param id110* The abstract identifier that identifies the Java virtual machine.111*112* @throws NullPointerException113* If <code>provider</code> or <code>id</code> is <code>null</code>.114*/115protected VirtualMachine(AttachProvider provider, String id) {116if (provider == null) {117throw new NullPointerException("provider cannot be null");118}119if (id == null) {120throw new NullPointerException("id cannot be null");121}122this.provider = provider;123this.id = id;124}125126/**127* Return a list of Java virtual machines.128*129* <p> This method returns a list of Java {@link130* com.sun.tools.attach.VirtualMachineDescriptor} elements.131* The list is an aggregation of the virtual machine132* descriptor lists obtained by invoking the {@link133* com.sun.tools.attach.spi.AttachProvider#listVirtualMachines134* listVirtualMachines} method of all installed135* {@link com.sun.tools.attach.spi.AttachProvider attach providers}.136* If there are no Java virtual machines known to any provider137* then an empty list is returned.138*139* @return The list of virtual machine descriptors.140*/141public static List<VirtualMachineDescriptor> list() {142ArrayList<VirtualMachineDescriptor> l =143new ArrayList<VirtualMachineDescriptor>();144List<AttachProvider> providers = AttachProvider.providers();145for (AttachProvider provider: providers) {146l.addAll(provider.listVirtualMachines());147}148return l;149}150151/**152* Attaches to a Java virtual machine.153*154* <p> This method obtains the list of attach providers by invoking the155* {@link com.sun.tools.attach.spi.AttachProvider#providers()156* AttachProvider.providers()} method. It then iterates overs the list157* and invokes each provider's {@link158* com.sun.tools.attach.spi.AttachProvider#attachVirtualMachine(java.lang.String)159* attachVirtualMachine} method in turn. If a provider successfully160* attaches then the iteration terminates, and the VirtualMachine created161* by the provider that successfully attached is returned by this method.162* If the <code>attachVirtualMachine</code> method of all providers throws163* {@link com.sun.tools.attach.AttachNotSupportedException AttachNotSupportedException}164* then this method also throws <code>AttachNotSupportedException</code>.165* This means that <code>AttachNotSupportedException</code> is thrown when166* the identifier provided to this method is invalid, or the identifier167* corresponds to a Java virtual machine that does not exist, or none168* of the providers can attach to it. This exception is also thrown if169* {@link com.sun.tools.attach.spi.AttachProvider#providers()170* AttachProvider.providers()} returns an empty list. </p>171*172* @param id173* The abstract identifier that identifies the Java virtual machine.174*175* @return A VirtualMachine representing the target VM.176*177* @throws SecurityException178* If a security manager has been installed and it denies179* {@link com.sun.tools.attach.AttachPermission AttachPermission}180* <tt>("attachVirtualMachine")</tt>, or another permission181* required by the implementation.182*183* @throws AttachNotSupportedException184* If the <code>attachVirtualmachine</code> method of all installed185* providers throws <code>AttachNotSupportedException</code>, or186* there aren't any providers installed.187*188* @throws IOException189* If an I/O error occurs190*191* @throws NullPointerException192* If <code>id</code> is <code>null</code>.193*/194public static VirtualMachine attach(String id)195throws AttachNotSupportedException, IOException196{197if (id == null) {198throw new NullPointerException("id cannot be null");199}200List<AttachProvider> providers = AttachProvider.providers();201if (providers.size() == 0) {202throw new AttachNotSupportedException("no providers installed");203}204AttachNotSupportedException lastExc = null;205for (AttachProvider provider: providers) {206try {207return provider.attachVirtualMachine(id);208} catch (AttachNotSupportedException x) {209lastExc = x;210}211}212throw lastExc;213}214215/**216* Attaches to a Java virtual machine.217*218* <p> This method first invokes the {@link219* com.sun.tools.attach.VirtualMachineDescriptor#provider() provider()} method220* of the given virtual machine descriptor to obtain the attach provider. It221* then invokes the attach provider's {@link222* com.sun.tools.attach.spi.AttachProvider#attachVirtualMachine(VirtualMachineDescriptor)223* attachVirtualMachine} to attach to the target VM.224*225* @param vmd226* The virtual machine descriptor.227*228* @return A VirtualMachine representing the target VM.229*230* @throws SecurityException231* If a security manager has been installed and it denies232* {@link com.sun.tools.attach.AttachPermission AttachPermission}233* <tt>("attachVirtualMachine")</tt>, or another permission234* required by the implementation.235*236* @throws AttachNotSupportedException237* If the attach provider's <code>attachVirtualmachine</code>238* throws <code>AttachNotSupportedException</code>.239*240* @throws IOException241* If an I/O error occurs242*243* @throws NullPointerException244* If <code>vmd</code> is <code>null</code>.245*/246public static VirtualMachine attach(VirtualMachineDescriptor vmd)247throws AttachNotSupportedException, IOException248{249return vmd.provider().attachVirtualMachine(vmd);250}251252/**253* Detach from the virtual machine.254*255* <p> After detaching from the virtual machine, any further attempt to invoke256* operations on that virtual machine will cause an {@link java.io.IOException257* IOException} to be thrown. If an operation (such as {@link #loadAgent258* loadAgent} for example) is in progress when this method is invoked then259* the behaviour is implementation dependent. In other words, it is260* implementation specific if the operation completes or throws261* <tt>IOException</tt>.262*263* <p> If already detached from the virtual machine then invoking this264* method has no effect. </p>265*266* @throws IOException267* If an I/O error occurs268*/269public abstract void detach() throws IOException;270271/**272* Returns the provider that created this virtual machine.273*274* @return The provider that created this virtual machine.275*/276public final AttachProvider provider() {277return provider;278}279280/**281* Returns the identifier for this Java virtual machine.282*283* @return The identifier for this Java virtual machine.284*/285public final String id() {286return id;287}288289/**290* Loads an agent library.291*292* <p> A <a href="../../../../../../../../technotes/guides/jvmti/index.html">JVM293* TI</a> client is called an <i>agent</i>. It is developed in a native language.294* A JVM TI agent is deployed in a platform specific manner but it is typically the295* platform equivalent of a dynamic library. Alternatively, it may be statically linked into the VM.296* This method causes the given agent library to be loaded into the target297* VM (if not already loaded or if not statically linked into the VM).298* It then causes the target VM to invoke the <code>Agent_OnAttach</code> function299* or, for a statically linked agent named 'L', the <code>Agent_OnAttach_L</code> function300* as specified in the301* <a href="../../../../../../../../technotes/guides/jvmti/index.html"> JVM Tools302* Interface</a> specification. Note that the <code>Agent_OnAttach[_L]</code>303* function is invoked even if the agent library was loaded prior to invoking304* this method.305*306* <p> The agent library provided is the name of the agent library. It is interpreted307* in the target virtual machine in an implementation-dependent manner. Typically an308* implementation will expand the library name into an operating system specific file309* name. For example, on UNIX systems, the name <tt>L</tt> might be expanded to310* <tt>libL.so</tt>, and located using the search path specified by the311* <tt>LD_LIBRARY_PATH</tt> environment variable. If the agent named 'L' is312* statically linked into the VM then the VM must export a function named313* <code>Agent_OnAttach_L</code>.</p>314*315* <p> If the <code>Agent_OnAttach[_L]</code> function in the agent library returns316* an error then an {@link com.sun.tools.attach.AgentInitializationException} is317* thrown. The return value from the <code>Agent_OnAttach[_L]</code> can then be318* obtained by invoking the {@link319* com.sun.tools.attach.AgentInitializationException#returnValue() returnValue}320* method on the exception. </p>321*322* @param agentLibrary323* The name of the agent library.324*325* @param options326* The options to provide to the <code>Agent_OnAttach[_L]</code>327* function (can be <code>null</code>).328*329* @throws AgentLoadException330* If the agent library does not exist, the agent library is not331* statically linked with the VM, or the agent library cannot be332* loaded for another reason.333*334* @throws AgentInitializationException335* If the <code>Agent_OnAttach[_L]</code> function returns an error.336*337* @throws IOException338* If an I/O error occurs339*340* @throws NullPointerException341* If <code>agentLibrary</code> is <code>null</code>.342*343* @see com.sun.tools.attach.AgentInitializationException#returnValue()344*/345public abstract void loadAgentLibrary(String agentLibrary, String options)346throws AgentLoadException, AgentInitializationException, IOException;347348/**349* Loads an agent library.350*351* <p> This convenience method works as if by invoking:352*353* <blockquote><tt>354* {@link #loadAgentLibrary(String, String) loadAgentLibrary}(agentLibrary, null);355* </tt></blockquote>356*357* @param agentLibrary358* The name of the agent library.359*360* @throws AgentLoadException361* If the agent library does not exist, the agent library is not362* statically linked with the VM, or the agent library cannot be363* loaded for another reason.364*365* @throws AgentInitializationException366* If the <code>Agent_OnAttach[_L]</code> function returns an error.367*368* @throws IOException369* If an I/O error occurs370*371* @throws NullPointerException372* If <code>agentLibrary</code> is <code>null</code>.373*/374public void loadAgentLibrary(String agentLibrary)375throws AgentLoadException, AgentInitializationException, IOException376{377loadAgentLibrary(agentLibrary, null);378}379380/**381* Load a native agent library by full pathname.382*383* <p> A <a href="../../../../../../../../technotes/guides/jvmti/index.html">JVM384* TI</a> client is called an <i>agent</i>. It is developed in a native language.385* A JVM TI agent is deployed in a platform specific manner but it is typically the386* platform equivalent of a dynamic library. Alternatively, the native387* library specified by the agentPath parameter may be statically388* linked with the VM. The parsing of the agentPath parameter into389* a statically linked library name is done in a platform390* specific manner in the VM. For example, in UNIX, an agentPath parameter391* of <code>/a/b/libL.so</code> would name a library 'L'.392*393* See the JVM TI Specification for more details.394*395* This method causes the given agent library to be loaded into the target396* VM (if not already loaded or if not statically linked into the VM).397* It then causes the target VM to invoke the <code>Agent_OnAttach</code>398* function or, for a statically linked agent named 'L', the399* <code>Agent_OnAttach_L</code> function as specified in the400* <a href="../../../../../../../../technotes/guides/jvmti/index.html"> JVM Tools401* Interface</a> specification.402* Note that the <code>Agent_OnAttach[_L]</code>403* function is invoked even if the agent library was loaded prior to invoking404* this method.405*406* <p> The agent library provided is the absolute path from which to load the407* agent library. Unlike {@link #loadAgentLibrary loadAgentLibrary}, the library name408* is not expanded in the target virtual machine. </p>409*410* <p> If the <code>Agent_OnAttach[_L]</code> function in the agent library returns411* an error then an {@link com.sun.tools.attach.AgentInitializationException} is412* thrown. The return value from the <code>Agent_OnAttach[_L]</code> can then be413* obtained by invoking the {@link414* com.sun.tools.attach.AgentInitializationException#returnValue() returnValue}415* method on the exception. </p>416*417* @param agentPath418* The full path of the agent library.419*420* @param options421* The options to provide to the <code>Agent_OnAttach[_L]</code>422* function (can be <code>null</code>).423*424* @throws AgentLoadException425* If the agent library does not exist, the agent library is not426* statically linked with the VM, or the agent library cannot be427* loaded for another reason.428*429* @throws AgentInitializationException430* If the <code>Agent_OnAttach[_L]</code> function returns an error.431*432* @throws IOException433* If an I/O error occurs434*435* @throws NullPointerException436* If <code>agentPath</code> is <code>null</code>.437*438* @see com.sun.tools.attach.AgentInitializationException#returnValue()439*/440public abstract void loadAgentPath(String agentPath, String options)441throws AgentLoadException, AgentInitializationException, IOException;442443/**444* Load a native agent library by full pathname.445*446* <p> This convenience method works as if by invoking:447*448* <blockquote><tt>449* {@link #loadAgentPath(String, String) loadAgentPath}(agentLibrary, null);450* </tt></blockquote>451*452* @param agentPath453* The full path to the agent library.454*455* @throws AgentLoadException456* If the agent library does not exist, the agent library is not457* statically linked with the VM, or the agent library cannot be458* loaded for another reason.459*460* @throws AgentInitializationException461* If the <code>Agent_OnAttach[_L]</code> function returns an error.462*463* @throws IOException464* If an I/O error occurs465*466* @throws NullPointerException467* If <code>agentPath</code> is <code>null</code>.468*/469public void loadAgentPath(String agentPath)470throws AgentLoadException, AgentInitializationException, IOException471{472loadAgentPath(agentPath, null);473}474475476/**477* Loads an agent.478*479* <p> The agent provided to this method is a path name to a JAR file on the file480* system of the target virtual machine. This path is passed to the target virtual481* machine where it is interpreted. The target virtual machine attempts to start482* the agent as specified by the {@link java.lang.instrument} specification.483* That is, the specified JAR file is added to the system class path (of the target484* virtual machine), and the <code>agentmain</code> method of the agent class, specified485* by the <code>Agent-Class</code> attribute in the JAR manifest, is invoked. This486* method completes when the <code>agentmain</code> method completes.487*488* @param agent489* Path to the JAR file containing the agent.490*491* @param options492* The options to provide to the agent's <code>agentmain</code>493* method (can be <code>null</code>).494*495* @throws AgentLoadException496* If the agent does not exist, or cannot be started in the manner497* specified in the {@link java.lang.instrument} specification.498*499* @throws AgentInitializationException500* If the <code>agentmain</code> throws an exception501*502* @throws IOException503* If an I/O error occurs504*505* @throws NullPointerException506* If <code>agent</code> is <code>null</code>.507*/508public abstract void loadAgent(String agent, String options)509throws AgentLoadException, AgentInitializationException, IOException;510511/**512* Loads an agent.513*514* <p> This convenience method works as if by invoking:515*516* <blockquote><tt>517* {@link #loadAgent(String, String) loadAgent}(agent, null);518* </tt></blockquote>519*520* @param agent521* Path to the JAR file containing the agent.522*523* @throws AgentLoadException524* If the agent does not exist, or cannot be started in the manner525* specified in the {@link java.lang.instrument} specification.526*527* @throws AgentInitializationException528* If the <code>agentmain</code> throws an exception529*530* @throws IOException531* If an I/O error occurs532*533* @throws NullPointerException534* If <code>agent</code> is <code>null</code>.535*/536public void loadAgent(String agent)537throws AgentLoadException, AgentInitializationException, IOException538{539loadAgent(agent, null);540}541542/**543* Returns the current system properties in the target virtual machine.544*545* <p> This method returns the system properties in the target virtual546* machine. Properties whose key or value is not a <tt>String</tt> are547* omitted. The method is approximately equivalent to the invocation of the548* method {@link java.lang.System#getProperties System.getProperties}549* in the target virtual machine except that properties with a key or550* value that is not a <tt>String</tt> are not included.551*552* <p> This method is typically used to decide which agent to load into553* the target virtual machine with {@link #loadAgent loadAgent}, or554* {@link #loadAgentLibrary loadAgentLibrary}. For example, the555* <code>java.home</code> or <code>user.dir</code> properties might be556* use to create the path to the agent library or JAR file.557*558* @return The system properties559*560* @throws AttachOperationFailedException561* If the target virtual machine is unable to complete the562* attach operation. A more specific error message will be563* given by {@link AttachOperationFailedException#getMessage()}.564*565* @throws IOException566* If an I/O error occurs, a communication error for example,567* that cannot be identified as an error to indicate that the568* operation failed in the target VM.569*570* @see java.lang.System#getProperties571* @see #loadAgentLibrary572* @see #loadAgent573*/574public abstract Properties getSystemProperties() throws IOException;575576/**577* Returns the current <i>agent properties</i> in the target virtual578* machine.579*580* <p> The target virtual machine can maintain a list of properties on581* behalf of agents. The manner in which this is done, the names of the582* properties, and the types of values that are allowed, is implementation583* specific. Agent properties are typically used to store communication584* end-points and other agent configuration details. For example, a debugger585* agent might create an agent property for its transport address.586*587* <p> This method returns the agent properties whose key and value is a588* <tt>String</tt>. Properties whose key or value is not a <tt>String</tt>589* are omitted. If there are no agent properties maintained in the target590* virtual machine then an empty property list is returned.591*592* @return The agent properties593*594* @throws AttachOperationFailedException595* If the target virtual machine is unable to complete the596* attach operation. A more specific error message will be597* given by {@link AttachOperationFailedException#getMessage()}.598*599* @throws IOException600* If an I/O error occurs, a communication error for example,601* that cannot be identified as an error to indicate that the602* operation failed in the target VM.603*/604public abstract Properties getAgentProperties() throws IOException;605606/**607* Starts the JMX management agent in the target virtual machine.608*609* <p> The configuration properties are the same as those specified on610* the command line when starting the JMX management agent. In the same611* way as on the command line, you need to specify at least the612* {@code com.sun.management.jmxremote.port} property.613*614* <p> See the online documentation for <a615* href="../../../../../../../../technotes/guides/management/agent.html">616* Monitoring and Management Using JMX Technology</a> for further details.617*618* @param agentProperties619* A Properties object containing the configuration properties620* for the agent.621*622* @throws AttachOperationFailedException623* If the target virtual machine is unable to complete the624* attach operation. A more specific error message will be625* given by {@link AttachOperationFailedException#getMessage()}.626*627* @throws IOException628* If an I/O error occurs, a communication error for example,629* that cannot be identified as an error to indicate that the630* operation failed in the target VM.631*632* @throws IllegalArgumentException633* If keys or values in agentProperties are invalid.634*635* @throws NullPointerException636* If agentProperties is null.637*638* @since 1.8639*/640public abstract void startManagementAgent(Properties agentProperties) throws IOException;641642/**643* Starts the local JMX management agent in the target virtual machine.644*645* <p> See the online documentation for <a646* href="../../../../../../../../technotes/guides/management/agent.html">647* Monitoring and Management Using JMX Technology</a> for further details.648*649* @return The String representation of the local connector's service address.650* The value can be parsed by the651* {@link javax.management.remote.JMXServiceURL#JMXServiceURL(String)}652* constructor.653*654* @throws AttachOperationFailedException655* If the target virtual machine is unable to complete the656* attach operation. A more specific error message will be657* given by {@link AttachOperationFailedException#getMessage()}.658*659* @throws IOException660* If an I/O error occurs, a communication error for example,661* that cannot be identified as an error to indicate that the662* operation failed in the target VM.663*664* @since 1.8665*/666public abstract String startLocalManagementAgent() throws IOException;667668/**669* Returns a hash-code value for this VirtualMachine. The hash670* code is based upon the VirtualMachine's components, and satifies671* the general contract of the {@link java.lang.Object#hashCode()672* Object.hashCode} method.673*674* @return A hash-code value for this virtual machine675*/676public int hashCode() {677if (hash != 0) {678return hash;679}680hash = provider.hashCode() * 127 + id.hashCode();681return hash;682}683684/**685* Tests this VirtualMachine for equality with another object.686*687* <p> If the given object is not a VirtualMachine then this688* method returns <tt>false</tt>. For two VirtualMachines to689* be considered equal requires that they both reference the same690* provider, and their {@link VirtualMachineDescriptor#id() identifiers} are equal. </p>691*692* <p> This method satisfies the general contract of the {@link693* java.lang.Object#equals(Object) Object.equals} method. </p>694*695* @param ob The object to which this object is to be compared696*697* @return <tt>true</tt> if, and only if, the given object is698* a VirtualMachine that is equal to this699* VirtualMachine.700*/701public boolean equals(Object ob) {702if (ob == this)703return true;704if (!(ob instanceof VirtualMachine))705return false;706VirtualMachine other = (VirtualMachine)ob;707if (other.provider() != this.provider()) {708return false;709}710if (!other.id().equals(this.id())) {711return false;712}713return true;714}715716/**717* Returns the string representation of the <code>VirtualMachine</code>.718*/719public String toString() {720return provider.toString() + ": " + id;721}722}723724725