Jdk5JavaProcessManager.java
package org.cyclopsgroup.jmxterm.jdk5;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.apache.commons.lang3.Validate;
import org.cyclopsgroup.jmxterm.JavaProcess;
import org.cyclopsgroup.jmxterm.JavaProcessManager;
import org.cyclopsgroup.jmxterm.utils.WeakCastUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* JDK5 specific implementation of {@link JavaProcessManager}
*
* @author <a href="mailto:jiaqi.guo@gmail.com">Jiaqi Guo</a>
*/
public class Jdk5JavaProcessManager extends JavaProcessManager {
private static final String CLASS_HOST_IDENTIFIER = "sun.jvmstat.monitor.HostIdentifier";
private static final String CLASS_MONITORED_VM = "sun.jvmstat.monitor.MonitoredVm";
private static final String CLASS_MONITORED_VM_UTIL = "sun.jvmstat.monitor.MonitoredVmUtil";
private static final String CLASS_VM_IDENTIFIER = "sun.jvmstat.monitor.VmIdentifier";
private static final Logger LOG = LoggerFactory.getLogger(Jdk5JavaProcessManager.class);
private final ConnectorAddressLink connectorAddressLink;
private final Method getMonitoredVm;
private final MonitoredHost localhost;
private final Object localhostDelegate;
private final Class<?> monitoredVmType;
private final Method toCommandLine;
private final Constructor<?> vmIdentifierConstructor;
public Jdk5JavaProcessManager(ClassLoader classLoader) throws Exception {
Validate.notNull(classLoader, "ClassLoader can't be NULL");
connectorAddressLink =
WeakCastUtils.staticCast(
classLoader.loadClass(ConnectorAddressLink.ORIGINAL_CLASS_NAME),
ConnectorAddressLink.class);
Class<?> hic = classLoader.loadClass(CLASS_HOST_IDENTIFIER);
Object hi = hic.getConstructor(String.class).newInstance((String) null);
Class<?> mhc = classLoader.loadClass(MonitoredHost.ORIGINAL_CLASS_NAME);
Method getInstance = mhc.getMethod("getMonitoredHost", hic);
localhostDelegate = getInstance.invoke(null, hi);
localhost = WeakCastUtils.cast(localhostDelegate, MonitoredHost.class);
Class<?> monitoredVmUtilClass = classLoader.loadClass(CLASS_MONITORED_VM_UTIL);
monitoredVmType = classLoader.loadClass(CLASS_MONITORED_VM);
toCommandLine = monitoredVmUtilClass.getMethod("commandLine", monitoredVmType);
Class<?> vmIdentifierType = classLoader.loadClass(CLASS_VM_IDENTIFIER);
vmIdentifierConstructor = vmIdentifierType.getConstructor(String.class);
getMonitoredVm = mhc.getMethod("getMonitoredVm", vmIdentifierType);
}
@Override
public JavaProcess get(int pid) {
Validate.isTrue(pid > 0, "PID " + pid + " isn't valid");
Object vmid;
try {
vmid = vmIdentifierConstructor.newInstance(String.valueOf(pid));
Object vm = getMonitoredVm.invoke(localhostDelegate, vmid);
String cmd = (String) toCommandLine.invoke(null, vm);
return new Jdk5JavaProcess(pid, cmd, connectorAddressLink);
} catch (InstantiationException e) {
throw new RuntimeException("Couldn't get infomrmation about PID " + pid, e);
} catch (IllegalAccessException e) {
throw new RuntimeException("Couldn't get infomrmation about PID " + pid, e);
} catch (InvocationTargetException e) {
throw new RuntimeException("Couldn't get infomrmation about PID " + pid, e);
}
}
@Override
public List<JavaProcess> list() {
Set<Integer> pids = localhost.activeVms();
List<JavaProcess> result = new ArrayList<JavaProcess>(pids.size());
for (int pid : pids) {
try {
result.add(get(pid));
} catch (RuntimeException e) {
e.printStackTrace();
if (LOG.isDebugEnabled()) {
LOG.debug("Couldn't get PID" + pid, e);
}
}
}
return result;
}
}