/* * ALMA - Atacama Large Millimiter Array * (c) Universidad Tecnica Federico Santa Maria, 2008 * Copyright by ESO (in the framework of the ALMA collaboration), * All rights reserved * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ package alma.acs.monitoring; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.net.InetAddress; import java.net.MalformedURLException; import javax.management.JMX; import javax.management.MBeanRegistrationException; import javax.management.MBeanServerConnection; import javax.management.MalformedObjectNameException; import javax.management.ObjectName; import javax.management.remote.JMXConnector; import javax.management.remote.JMXConnectorFactory; import javax.management.remote.JMXServiceURL; import com.sun.tools.attach.AgentInitializationException; import com.sun.tools.attach.AgentLoadException; import com.sun.tools.attach.AttachNotSupportedException; import com.sun.tools.attach.VirtualMachine; /** * Class used for connecting with a {@link RemoteThreads} MBean implementation. * The connection can be done with a local process, as well as with a process * running in a remote machine, with the RMI connector enabled on it. *
* For further details on the activation of the RMI connector, you can see
*
* http://java.sun.com/docs/books/tutorial/jmx/remote/jconsole.html
*
* @author rtobar
* @since ACS 7.0
*/
public class RemoteThreadsClient {
/**
* Default port used by the RMI client-side connector
*/
public static final int RMI_DEFAULT_PORT = 9999;
/**
* Property name for getting a local JMX connector
*/
private static final String LOCAL_CONNECTOR_ADDRESS =
"com.sun.management.jmxremote.localConnectorAddress";
private JMXServiceURL remoteURL = null;
private MBeanServerConnection remote = null;
private RemoteThreadsMBean rtmb = null;
private JMXConnector connector = null;
/**
* Gets a new RemoteThreadsClient
ready to be connected to the
* remote JVM indicated by the name of the launcher class (the one containing the
* public static void main(String[])
method).
* @param className The name of the launcher class of the remote process
* @throws RemoteThreadsException Is thrown in the following cases:
*
jps
program.RemoteThreadsClient
ready to be connected to the
* remote JVM indicated by the given PID
* @param pid The PID of the remote java process
* @throws RemoteThreadsException If:
* RemoteThreadsClient
ready to be connected to the
* remote JVM present in the given host address. It uses the {@link #RMI_DEFAULT_PORT}
* for connecting to the remote host.
* @param remoteHost The remote host where the remote JVM is placed
* @throws RemoteThreadsException If a malformed URL is produced with the given
* host address.
*/
public RemoteThreadsClient(InetAddress remoteHost) throws RemoteThreadsException {
try {
getServiceURL(remoteHost, RMI_DEFAULT_PORT);
} catch (MalformedURLException e) {
throw new RemoteThreadsException(e);
}
}
/**
* Gets a new RemoteThreadsClient
ready to be connected to the
* remote JVM present in the given host address and port.
* @param remoteHost The remote host where the remote JVM is placed
* @param remotePort The port to be used for the RMI connection
* @throws RemoteThreadsException If a malformed URL is produced with the given
* host address and port.
*/
public RemoteThreadsClient(InetAddress remoteHost, int remotePort) throws RemoteThreadsException {
if( remotePort <= 0 ) {
throw new RemoteThreadsException("Port must be grater than zero");
}
try {
getServiceURL(remoteHost,remotePort);
} catch (MalformedURLException e) {
throw new RemoteThreadsException(e);
}
}
/**
* Connects the object instance to the remote JVM agent and gets a direct connection
* with the MBeanServer in order to be able to get the remote MBean.
*
* @return If the connection has been sucessful or not
*/
public boolean connect() {
try {
connector = JMXConnectorFactory.connect(remoteURL);
} catch (IOException e) {
System.err.println("Can't connect to the remote URL");
return false;
}
try {
remote= connector.getMBeanServerConnection();
} catch (IOException e) {
System.err.println("Can't get a connection to the remote MBeanServer");
return false;
}
return true;
}
/**
* Closes the connection with the remote MBeanServer.
* @throws RemoteThreadsException If the connection has not been opened.
*/
public void close() throws RemoteThreadsException {
if( connector != null) {
try {
connector.close();
} catch (IOException e) {
System.err.println("Cannot close connection to the remote MBeanServer");
}
} else {
throw new RemoteThreadsException("The connection has not been opened");
}
}
/**
* Returns an object representing the MBean registered on the remote JVM agent. If the
* MBean has not been registered, then it is registered and then retreived.
* @return A {@link RemoteThreadsMBean} object representing the MBean registered
* on the remote JVM agent.
* @throws RemoteThreadsException If:
*