/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import javax.management.*;
// The SwingPropertyChangeSupport will fire events on the EDT
new SwingPropertyChangeSupport(this, true);
private volatile boolean isDead = true;
private boolean hasPlatformMXBeans = false;
private boolean hasHotSpotDiagnosticMXBean= false;
private boolean hasCompilationMXBean = false;
private boolean supportsLockUsage = false;
// REVISIT: VMPanel and other places relying using getUrl().
// set only if it's created for local monitoring
// set only if it's created from a given URL via the Advanced tab
new SslRMIClientSocketFactory();
private boolean vmConnector = false;
private boolean sslRegistry = false;
private boolean sslStub = false;
"com.sun.management:type=HotSpotDiagnostic";
this.displayName = connectionName;
// Monitor self
} else {
// Create an RMI connector client and connect it to
// the RMI connector server
"/jmxrmi";
vmConnector = true;
registryPort = port;
}
}
this.advancedUrl = url;
this.displayName = connectionName;
}
}
}
// Check remote stub is from the expected class.
//
throw new SecurityException(
} else {
throw new SecurityException(
"Expecting a dynamic proxy instance with a " +
RemoteObjectInvocationHandler.class.getName() +
" invocation handler!");
} else {
}
}
}
// Check RemoteRef in stub is from the expected class
// "sun.rmi.server.UnicastRef2".
//
throw new SecurityException(
" remote reference in stub!");
}
// Check RMIClientSocketFactory in stub is from the expected class
// "javax.rmi.ssl.SslRMIClientSocketFactory".
//
throw new SecurityException(
" RMI client socket factory in stub!");
}
}
"javax.management.remote.rmi.RMIServerImpl_Stub";
static {
// FIXME: RMIServerImpl_Stub is generated at build time
// after jconsole is built. We need to investigate if
// the Makefile can be fixed to build jconsole in the
// right order. As a workaround for now, we dynamically
// load RMIServerImpl_Stub class instead of statically
// referencing it.
try {
} catch (ClassNotFoundException e) {
// should never reach here
}
}
// Get the reference to the RMI Registry and lookup RMIServer stub
//
try {
registry =
try {
} catch (NotBoundException nbe) {
throw (IOException)
}
sslRegistry = true;
} catch (IOException e) {
registry =
try {
} catch (NotBoundException nbe) {
throw (IOException)
}
sslRegistry = false;
}
// Perform the checks for secure stub
//
try {
sslStub = true;
} catch (SecurityException e) {
sslStub = false;
}
}
/**
* Returns true if the underlying RMI registry is SSL-protected.
*
* @exception UnsupportedOperationException If this {@code ProxyClient}
* does not denote a JMX connector for a JMX VM agent.
*/
public boolean isSslRmiRegistry() {
// Check for VM connector
//
if (!isVmConnector()) {
throw new UnsupportedOperationException(
"ProxyClient.isSslRmiRegistry() is only supported if this " +
"ProxyClient is a JMX connector for a JMX VM agent");
}
return sslRegistry;
}
/**
* Returns true if the retrieved RMI stub is SSL-protected.
*
* @exception UnsupportedOperationException If this {@code ProxyClient}
* does not denote a JMX connector for a JMX VM agent.
*/
public boolean isSslRmiStub() {
// Check for VM connector
//
if (!isVmConnector()) {
throw new UnsupportedOperationException(
"ProxyClient.isSslRmiStub() is only supported if this " +
"ProxyClient is a JMX connector for a JMX VM agent");
}
return sslStub;
}
/**
* Returns true if this {@code ProxyClient} denotes
* a JMX connector for a JMX VM agent.
*/
public boolean isVmConnector() {
return vmConnector;
}
this.connectionState = state;
}
return this.connectionState;
}
void flush() {
}
}
try {
} catch (Exception e) {
e.printStackTrace();
}
}
}
// Monitor self
} else {
// Monitor another process
if (!lvm.isManageable()) {
if (!lvm.isManageable()) {
// FIXME: what to throw
}
}
}
}
if (requireRemoteSSL) {
}
// Need to pass in credentials ?
if (isVmConnector()) {
// Check for SSL config on reconnection only
}
} else {
}
} else {
if (isVmConnector()) {
// Check for SSL config on reconnection only
}
} else {
}
}
}
this.isDead = false;
try {
this.hasHotSpotDiagnosticMXBean =
// check if it has 6.0 new APIs
if (this.hasPlatformMXBeans) {
// look for findDeadlockedThreads operations;
this.supportsLockUsage = true;
break;
}
}
}
} catch (MalformedObjectNameException e) {
// should not reach here
throw new InternalError(e.getMessage());
} catch (IntrospectionException e) {
throw ie;
} catch (InstanceNotFoundException e) {
throw ie;
} catch (ReflectionException e) {
throw ie;
}
if (hasPlatformMXBeans) {
// WORKAROUND for bug 5056632
// Check if the access role is correct by getting a RuntimeMXBean
}
}
/**
* Gets a proxy client for a given local virtual machine.
*/
throws IOException {
if (proxyClient == null) {
}
return proxyClient;
}
}
}
/**
* Gets a proxy client for a given JMXServiceURL.
*/
throws IOException {
if (proxyClient == null) {
}
return proxyClient;
}
} else {
return url;
}
}
}
/**
* Gets a proxy client for a given "hostname:port".
*/
throws IOException {
if (proxyClient == null) {
}
return proxyClient;
}
} else {
return name;
}
}
port + ":" +
}
return connectionName;
}
return displayName;
}
if (!isConnected()) {
} else {
return displayName;
}
}
return mbsc;
}
return server;
}
return advancedUrl;
}
return hostName;
}
public int getPort() {
return port;
}
public int getVmid() {
}
return userName;
}
return password;
}
public void disconnect() {
// Reset remote stub
// Close MBeanServer connection
try {
} catch (IOException e) {
// Ignore ???
}
}
// Reset platform MBean references
memoryMBean = null;
runtimeMBean = null;
threadMBean = null;
// Set connection state to DISCONNECTED
if (!isDead) {
isDead = true;
}
}
/**
* Returns the list of domains in which any MBean is
* currently registered.
*/
return server.getDomains();
}
/**
* Returns a map of MBeans with ObjectName as the key and MBeanInfo value
* of a given domain. If domain is <tt>null</tt>, all MBeans
* are returned. If no MBean found, an empty map is returned.
*
*/
throws IOException {
try {
} catch (MalformedObjectNameException e) {
// should not reach here
assert(false);
}
}
if (object instanceof ObjectName) {
try {
} catch (IntrospectionException e) {
// TODO: should log the error
} catch (InstanceNotFoundException e) {
// TODO: should log the error
} catch (ReflectionException e) {
// TODO: should log the error
}
}
}
return result;
}
/**
* Returns a list of attributes of a named MBean.
*
*/
throws IOException {
try {
} catch (InstanceNotFoundException e) {
// TODO: A MBean may have been unregistered.
// need to set up listener to listen for MBeanServerNotification.
} catch (ReflectionException e) {
// TODO: should log the error
}
return list;
}
/**
* Set the value of a specific attribute of a named MBean.
*/
throws InvalidAttributeValueException,
try {
} catch (InstanceNotFoundException e) {
// TODO: A MBean may have been unregistered.
} catch (AttributeNotFoundException e) {
assert(false);
} catch (ReflectionException e) {
// TODO: should log the error
}
}
/**
* Invokes an operation of a named MBean.
*
* @throws MBeanException Wraps an exception thrown by
* the MBean's invoked method.
*/
throws IOException, MBeanException {
try {
} catch (InstanceNotFoundException e) {
// TODO: A MBean may have been unregistered.
} catch (ReflectionException e) {
// TODO: should log the error
}
return result;
}
ClassLoadingMXBean.class);
}
return classLoadingMBean;
}
CompilationMXBean.class);
}
return compilationMBean;
}
throws IOException {
// TODO: How to deal with changes to the list??
if (memoryPoolProxies == null) {
try {
} catch (MalformedObjectNameException e) {
// should not reach here
assert(false);
}
memoryPoolProxies.add(p);
}
}
}
return memoryPoolProxies;
}
throws IOException {
// TODO: How to deal with changes to the list??
if (garbageCollectorMBeans == null) {
try {
} catch (MalformedObjectNameException e) {
// should not reach here
assert(false);
}
GarbageCollectorMXBean.class);
}
}
}
return garbageCollectorMBeans;
}
MemoryMXBean.class);
}
return memoryMBean;
}
RuntimeMXBean.class);
}
return runtimeMBean;
}
ThreadMXBean.class);
}
return threadMBean;
}
OperatingSystemMXBean.class);
}
return operatingSystemMBean;
}
try {
if (sunOperatingSystemMXBean == null) {
"com.sun.management.OperatingSystemMXBean")) {
}
}
} catch (InstanceNotFoundException e) {
return null;
} catch (MalformedObjectNameException e) {
return null; // should never reach here
}
return sunOperatingSystemMXBean;
}
HotSpotDiagnosticMXBean.class);
}
return hotspotDiagnosticMXBean;
}
throws IOException {
return newPlatformMXBeanProxy(server,
}
// Return thread IDs of deadlocked threads or null if any.
// It finds deadlocks involving only monitors if it's a Tiger VM.
// Otherwise, it finds deadlocks involving both monitors and
// the concurrent locks.
return tm.findDeadlockedThreads();
} else {
return tm.findMonitorDeadlockedThreads();
}
}
public synchronized void markAsDead() {
disconnect();
}
public boolean isDead() {
return isDead;
}
boolean isConnected() {
return !isDead();
}
boolean hasPlatformMXBeans() {
return this.hasPlatformMXBeans;
}
boolean hasHotSpotDiagnosticMXBean() {
return this.hasHotSpotDiagnosticMXBean;
}
boolean isLockUsageSupported() {
return supportsLockUsage;
}
}
}
}
}
// Search for the WeakPCL holding this listener (if any)
break;
}
}
}
}
/**
* The PropertyChangeListener is handled via a WeakReference
* so as not to pin down the listener.
*/
implements PropertyChangeListener {
super(referent);
}
// The referent listener was GC'ed, we're no longer
// interested in PropertyChanges, remove the listener.
dispose();
} else {
}
}
private void dispose() {
removePropertyChangeListener(this);
}
}
//
// Snapshot MBeanServerConnection:
//
// This is an object that wraps an existing MBeanServerConnection and adds
// caching to it, as follows:
//
// - The first time an attribute is called in a given MBean, the result is
// cached. Every subsequent time getAttribute is called for that attribute
// the cached result is returned.
//
// - Before every call to VMPanel.update() or when the Refresh button in the
// Attributes table is pressed down the attributes cache is flushed. Then
// any subsequent call to getAttribute will retrieve all the values for
// the attributes that are known to the cache.
//
// - The attributes cache uses a learning approach and only the attributes
// that are in the cache will be retrieved between two subsequent updates.
//
public interface SnapshotMBeanServerConnection
extends MBeanServerConnection {
/**
* Flush all cached values of attributes.
*/
public void flush();
}
public static class Snapshot {
private Snapshot() {
}
public static SnapshotMBeanServerConnection
Snapshot.class.getClassLoader(),
new Class[] {SnapshotMBeanServerConnection.class},
ih);
}
}
@SuppressWarnings("serial")
private static final class NameValueMap
}
synchronized void flush() {
cachedValues = newMap();
}
throws Throwable {
flush();
return null;
} else {
try {
} catch (InvocationTargetException e) {
throw e.getCause();
}
}
}
throws MBeanException, InstanceNotFoundException,
return value;
}
// Not in cache, presumably because it was omitted from the
// getAttributes result because of an exception. Following
// call will probably provoke the same exception.
}
}
}
return list;
}
return values;
}
}
values = new NameValueMap();
}
return values;
}
return new HashMap<K, V>();
}
}
}