1 /*
   2  * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /*
  25  *
  26  *
  27  * A test "management tool" used by unit tests -
  28  *   LocalManagementTest.java, CustomLauncherTest.java
  29  *
  30  * Usage:    java TestManager <pid> <port>
  31  *
  32  * where <pid> is the process-id of the test application, and <port> is
  33  * TCP port is used to shutdown the application.
  34  */
  35 import javax.management.MBeanServerConnection;
  36 import javax.management.remote.JMXServiceURL;
  37 import javax.management.remote.JMXConnectorFactory;
  38 import javax.management.remote.JMXConnector;
  39 import java.lang.management.RuntimeMXBean;
  40 import static java.lang.management.ManagementFactory.*;
  41 import java.net.Socket;
  42 import java.net.InetSocketAddress;
  43 import java.io.File;
  44 import java.io.IOException;
  45 
  46 // Sun specific
  47 import com.sun.tools.attach.VirtualMachine;
  48 
  49 // Sun implementation specific
  50 import sun.management.ConnectorAddressLink;
  51 
  52 public class TestManager {
  53 
  54     /*
  55      * Starts the management agent in the target VM
  56      */
  57     private static void startManagementAgent(String pid) throws IOException {
  58         /*
  59          * JAR file normally in ${java.home}/jre/lib but may be in ${java.home}/lib
  60          * with development/non-images builds
  61          */
  62         String home = System.getProperty("java.home");
  63         String agent = home + File.separator + "jre" + File.separator + "lib"
  64                 + File.separator + "management-agent.jar";
  65         File f = new File(agent);
  66         if (!f.exists()) {
  67             agent = home + File.separator + "lib" + File.separator +
  68                 "management-agent.jar";
  69             f = new File(agent);
  70             if (!f.exists()) {
  71                 throw new RuntimeException("management-agent.jar missing");
  72             }
  73         }
  74         agent = f.getCanonicalPath();
  75 
  76         System.out.println("Loading " + agent + " into target VM ...");
  77 
  78         try {
  79             VirtualMachine.attach(pid).loadAgent(agent);
  80         } catch (Exception x) {
  81             throw new IOException(x.getMessage());
  82         }
  83     }
  84 
  85     private static void connect(String pid, String address) throws Exception {
  86         if (address == null) {
  87             throw new RuntimeException("Local connector address for " +
  88                                        pid + " is null");
  89         }
  90 
  91         System.out.println("Connect to process " + pid + " via: " + address);
  92 
  93         JMXServiceURL url = new JMXServiceURL(address);
  94         JMXConnector c = JMXConnectorFactory.connect(url);
  95         MBeanServerConnection server = c.getMBeanServerConnection();
  96 
  97         System.out.println("Connected.");
  98 
  99         RuntimeMXBean rt = newPlatformMXBeanProxy(server,
 100             RUNTIME_MXBEAN_NAME, RuntimeMXBean.class);
 101         System.out.println(rt.getName());
 102 
 103         // close the connection
 104         c.close();
 105     }
 106 
 107 
 108     private final static String LOCAL_CONNECTOR_ADDRESS_PROP =
 109         "com.sun.management.jmxremote.localConnectorAddress";
 110     public static void main(String[] args) throws Exception {
 111         String pid = args[0]; // pid as a string
 112         System.out.println("Starting TestManager for PID = " + pid);
 113         System.out.flush();
 114         VirtualMachine vm = VirtualMachine.attach(pid);
 115 
 116         String agentPropLocalConnectorAddress = (String)
 117             vm.getAgentProperties().get(LOCAL_CONNECTOR_ADDRESS_PROP);
 118 
 119         int vmid = Integer.parseInt(pid);
 120         String jvmstatLocalConnectorAddress =
 121             ConnectorAddressLink.importFrom(vmid);
 122 
 123         if (agentPropLocalConnectorAddress == null &&
 124             jvmstatLocalConnectorAddress == null) {
 125             // No JMX Connector address so attach to VM, and load
 126             // management-agent.jar
 127             startManagementAgent(pid);
 128             agentPropLocalConnectorAddress = (String)
 129                 vm.getAgentProperties().get(LOCAL_CONNECTOR_ADDRESS_PROP);
 130             jvmstatLocalConnectorAddress =
 131                 ConnectorAddressLink.importFrom(vmid);
 132         }
 133 
 134 
 135         // Test address obtained from agent properties
 136         System.out.println("Testing the connector address from agent properties");
 137         connect(pid, agentPropLocalConnectorAddress);
 138 
 139         // Test address obtained from jvmstat buffer
 140         System.out.println("Testing the connector address from jvmstat buffer");
 141         connect(pid, jvmstatLocalConnectorAddress);
 142 
 143         // Shutdown application
 144         int port = Integer.parseInt(args[1]);
 145         System.out.println("Shutdown process via TCP port: " + port);
 146         Socket s = new Socket();
 147         s.connect(new InetSocketAddress(port));
 148         s.close();
 149     }
 150 }