This is the default class for MBean manipulation on the agent side. It
contains the methods necessary for the creation, registration, and
deletion of MBeans as well as the access methods for registered MBeans.
This is the core component of the JMX infrastructure.
Every MBean which is added to the MBean server becomes manageable: its attributes and operations
become remotely accessible through the connectors/adaptors connected to that MBean server.
A Java object cannot be registered in the MBean server unless it is a JMX compliant MBean.
| Method from com.sun.jmx.interceptor.DefaultMBeanServerInterceptor Detail: |
public void addNotificationListener(ObjectName name,
NotificationListener listener,
NotificationFilter filter,
Object handback) throws InstanceNotFoundException {
// ------------------------------
// ------------------------------
if (MBEANSERVER_LOGGER.isLoggable(Level.FINER)) {
MBEANSERVER_LOGGER.logp(Level.FINER,
DefaultMBeanServerInterceptor.class.getName(),
"addNotificationListener", "ObjectName = " + name);
}
DynamicMBean instance = getMBean(name);
checkMBeanPermission(instance, null, name, "addNotificationListener");
NotificationBroadcaster broadcaster =
getNotificationBroadcaster(name, instance,
NotificationBroadcaster.class);
// ------------------
// Check listener
// ------------------
if (listener == null) {
throw new RuntimeOperationsException(new
IllegalArgumentException("Null listener"),"Null listener");
}
NotificationListener listenerWrapper =
getListenerWrapper(listener, name, broadcaster, true);
broadcaster.addNotificationListener(listenerWrapper, filter, handback);
}
|
public void addNotificationListener(ObjectName name,
ObjectName listener,
NotificationFilter filter,
Object handback) throws InstanceNotFoundException {
// ------------------------------
// ------------------------------
// ----------------
// Get listener object
// ----------------
DynamicMBean instance = getMBean(listener);
Object resource = getResource(instance);
if (!(resource instanceof NotificationListener)) {
throw new RuntimeOperationsException(new
IllegalArgumentException(listener.getCanonicalName()),
"The MBean " + listener.getCanonicalName() +
"does not implement the NotificationListener interface") ;
}
// ----------------
// Add a listener on an MBean
// ----------------
if (MBEANSERVER_LOGGER.isLoggable(Level.FINER)) {
MBEANSERVER_LOGGER.logp(Level.FINER,
DefaultMBeanServerInterceptor.class.getName(),
"addNotificationListener",
"ObjectName = " + name + ", Listener = " + listener);
}
server.addNotificationListener(name,(NotificationListener) resource,
filter, handback) ;
}
|
public ObjectInstance createMBean(String className,
ObjectName name) throws MBeanRegistrationException, InstanceAlreadyExistsException, NotCompliantMBeanException, ReflectionException, MBeanException {
return createMBean(className, name, (Object[]) null, (String[]) null);
}
|
public ObjectInstance createMBean(String className,
ObjectName name,
ObjectName loaderName) throws InstanceNotFoundException, MBeanRegistrationException, InstanceAlreadyExistsException, NotCompliantMBeanException, ReflectionException, MBeanException {
return createMBean(className, name, loaderName, (Object[]) null,
(String[]) null);
}
|
public ObjectInstance createMBean(String className,
ObjectName name,
Object[] params,
String[] signature) throws MBeanRegistrationException, InstanceAlreadyExistsException, NotCompliantMBeanException, ReflectionException, MBeanException {
try {
return createMBean(className, name, null, true,
params, signature);
} catch (InstanceNotFoundException e) {
/* Can only happen if loaderName doesn't exist, but we just
passed null, so we shouldn't get this exception. */
throw EnvHelp.initCause(
new IllegalArgumentException("Unexpected exception: " + e), e);
}
}
|
public ObjectInstance createMBean(String className,
ObjectName name,
ObjectName loaderName,
Object[] params,
String[] signature) throws InstanceNotFoundException, MBeanRegistrationException, InstanceAlreadyExistsException, NotCompliantMBeanException, ReflectionException, MBeanException {
return createMBean(className, name, loaderName, false,
params, signature);
}
|
public Object getAttribute(ObjectName name,
String attribute) throws InstanceNotFoundException, ReflectionException, AttributeNotFoundException, MBeanException {
if (name == null) {
throw new RuntimeOperationsException(new
IllegalArgumentException("Object name cannot be null"),
"Exception occurred trying to invoke the getter on the MBean");
}
if (attribute == null) {
throw new RuntimeOperationsException(new
IllegalArgumentException("Attribute cannot be null"),
"Exception occurred trying to invoke the getter on the MBean");
}
name = nonDefaultDomain(name);
if (MBEANSERVER_LOGGER.isLoggable(Level.FINER)) {
MBEANSERVER_LOGGER.logp(Level.FINER,
DefaultMBeanServerInterceptor.class.getName(),
"getAttribute",
"Attribute = " + attribute + ", ObjectName = " + name);
}
final DynamicMBean instance = getMBean(name);
checkMBeanPermission(instance, attribute, name, "getAttribute");
try {
return instance.getAttribute(attribute);
} catch (AttributeNotFoundException e) {
throw e;
} catch (Throwable t) {
rethrowMaybeMBeanException(t);
throw new AssertionError(); // not reached
}
}
|
public AttributeList getAttributes(ObjectName name,
String[] attributes) throws InstanceNotFoundException, ReflectionException {
if (name == null) {
throw new RuntimeOperationsException(new
IllegalArgumentException("ObjectName name cannot be null"),
"Exception occurred trying to invoke the getter on the MBean");
}
if (attributes == null) {
throw new RuntimeOperationsException(new
IllegalArgumentException("Attributes cannot be null"),
"Exception occurred trying to invoke the getter on the MBean");
}
name = nonDefaultDomain(name);
if (MBEANSERVER_LOGGER.isLoggable(Level.FINER)) {
MBEANSERVER_LOGGER.logp(Level.FINER,
DefaultMBeanServerInterceptor.class.getName(),
"getAttributes", "ObjectName = " + name);
}
final DynamicMBean instance = getMBean(name);
final String[] allowedAttributes;
final SecurityManager sm = System.getSecurityManager();
if (sm == null)
allowedAttributes = attributes;
else {
final String classname = getClassName(instance);
// Check if the caller has the right to invoke 'getAttribute'
//
checkMBeanPermission(classname, null, name, "getAttribute");
// Check if the caller has the right to invoke 'getAttribute'
// on each specific attribute
//
List< String > allowedList =
new ArrayList< String >(attributes.length);
for (String attr : attributes) {
try {
checkMBeanPermission(classname, attr,
name, "getAttribute");
allowedList.add(attr);
} catch (SecurityException e) {
// OK: Do not add this attribute to the list
}
}
allowedAttributes = allowedList.toArray(new String[0]);
}
try {
return instance.getAttributes(allowedAttributes);
} catch (Throwable t) {
rethrow(t);
throw new AssertionError();
}
}
|
public ClassLoader getClassLoader(ObjectName loaderName) throws InstanceNotFoundException {
if (loaderName == null) {
checkMBeanPermission((String) null, null, null, "getClassLoader");
return server.getClass().getClassLoader();
}
DynamicMBean instance = getMBean(loaderName);
checkMBeanPermission(instance, null, loaderName, "getClassLoader");
Object resource = getResource(instance);
/* Check if the given MBean is a ClassLoader */
if (!(resource instanceof ClassLoader))
throw new InstanceNotFoundException(loaderName.toString() +
" is not a classloader");
return (ClassLoader) resource;
}
|
public ClassLoader getClassLoaderFor(ObjectName mbeanName) throws InstanceNotFoundException {
DynamicMBean instance = getMBean(mbeanName);
checkMBeanPermission(instance, null, mbeanName, "getClassLoaderFor");
return getResource(instance).getClass().getClassLoader();
}
|
public String getDefaultDomain() {
return domain;
}
|
public String[] getDomains() {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
// Check if the caller has the right to invoke 'getDomains'
//
checkMBeanPermission((String) null, null, null, "getDomains");
// Return domains
//
String[] domains = repository.getDomains();
// Check if the caller has the right to invoke 'getDomains'
// on each specific domain in the list.
//
List< String > result = new ArrayList< String >(domains.length);
for (int i = 0; i < domains.length; i++) {
try {
ObjectName domain = Util.newObjectName(domains[i] + ":x=x");
checkMBeanPermission((String) null, null, domain, "getDomains");
result.add(domains[i]);
} catch (SecurityException e) {
// OK: Do not add this domain to the list
}
}
// Make an array from result.
//
return result.toArray(new String[result.size()]);
} else {
return repository.getDomains();
}
}
|
public Integer getMBeanCount() {
return (repository.getCount());
}
|
public MBeanInfo getMBeanInfo(ObjectName name) throws IntrospectionException, InstanceNotFoundException, ReflectionException {
// ------------------------------
// ------------------------------
DynamicMBean moi = getMBean(name);
final MBeanInfo mbi;
try {
mbi = moi.getMBeanInfo();
} catch (RuntimeMBeanException e) {
throw e;
} catch (RuntimeErrorException e) {
throw e;
} catch (RuntimeException e) {
throw new RuntimeMBeanException(e,
"getMBeanInfo threw RuntimeException");
} catch (Error e) {
throw new RuntimeErrorException(e, "getMBeanInfo threw Error");
}
if (mbi == null)
throw new JMRuntimeException("MBean " + name +
"has no MBeanInfo");
checkMBeanPermission(mbi.getClassName(), null, name, "getMBeanInfo");
return mbi;
}
|
public ObjectInstance getObjectInstance(ObjectName name) throws InstanceNotFoundException {
name = nonDefaultDomain(name);
DynamicMBean instance = getMBean(name);
checkMBeanPermission(instance, null, name, "getObjectInstance");
final String className = getClassName(instance);
return new ObjectInstance(name, className);
}
|
public Object invoke(ObjectName name,
String operationName,
Object[] params,
String[] signature) throws InstanceNotFoundException, ReflectionException, MBeanException {
name = nonDefaultDomain(name);
DynamicMBean instance = getMBean(name);
checkMBeanPermission(instance, operationName, name, "invoke");
try {
return instance.invoke(operationName, params, signature);
} catch (Throwable t) {
rethrowMaybeMBeanException(t);
throw new AssertionError();
}
}
|
public boolean isInstanceOf(ObjectName name,
String className) throws InstanceNotFoundException {
DynamicMBean instance = getMBean(name);
checkMBeanPermission(instance, null, name, "isInstanceOf");
try {
if (instance instanceof DynamicMBean2) {
Object resource = ((DynamicMBean2) instance).getResource();
ClassLoader loader = resource.getClass().getClassLoader();
Class< ? > c = Class.forName(className, false, loader);
return c.isInstance(resource);
}
final String cn = getClassName(instance);
if (cn.equals(className))
return true;
final ClassLoader cl = instance.getClass().getClassLoader();
final Class< ? > classNameClass = Class.forName(className, false, cl);
if (classNameClass.isInstance(instance))
return true;
final Class< ? > instanceClass = Class.forName(cn, false, cl);
return classNameClass.isAssignableFrom(instanceClass);
} catch (Exception x) {
/* Could be SecurityException or ClassNotFoundException */
if (MBEANSERVER_LOGGER.isLoggable(Level.FINEST)) {
MBEANSERVER_LOGGER.logp(Level.FINEST,
DefaultMBeanServerInterceptor.class.getName(),
"isInstanceOf", "Exception calling isInstanceOf", x);
}
return false;
}
}
|
public boolean isRegistered(ObjectName name) {
if (name == null) {
throw new RuntimeOperationsException(
new IllegalArgumentException("Object name cannot be null"),
"Object name cannot be null");
}
name = nonDefaultDomain(name);
// /* Permission check */
// checkMBeanPermission(null, null, name, "isRegistered");
return (repository.contains(name));
}
|
public Set queryMBeans(ObjectName name,
QueryExp query) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
// Check if the caller has the right to invoke 'queryMBeans'
//
checkMBeanPermission((String) null, null, null, "queryMBeans");
// Perform query without "query".
//
Set< ObjectInstance > list = queryMBeansImpl(name, null);
// Check if the caller has the right to invoke 'queryMBeans'
// on each specific classname/objectname in the list.
//
Set< ObjectInstance > allowedList =
new HashSet< ObjectInstance >(list.size());
for (ObjectInstance oi : list) {
try {
checkMBeanPermission(oi.getClassName(), null,
oi.getObjectName(), "queryMBeans");
allowedList.add(oi);
} catch (SecurityException e) {
// OK: Do not add this ObjectInstance to the list
}
}
// Apply query to allowed MBeans only.
//
return filterListOfObjectInstances(allowedList, query);
} else {
// Perform query.
//
return queryMBeansImpl(name, query);
}
}
|
public Set queryNames(ObjectName name,
QueryExp query) {
Set< ObjectName > queryList;
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
// Check if the caller has the right to invoke 'queryNames'
//
checkMBeanPermission((String) null, null, null, "queryNames");
// Perform query without "query".
//
Set< ObjectInstance > list = queryMBeansImpl(name, null);
// Check if the caller has the right to invoke 'queryNames'
// on each specific classname/objectname in the list.
//
Set< ObjectInstance > allowedList =
new HashSet< ObjectInstance >(list.size());
for (ObjectInstance oi : list) {
try {
checkMBeanPermission(oi.getClassName(), null,
oi.getObjectName(), "queryNames");
allowedList.add(oi);
} catch (SecurityException e) {
// OK: Do not add this ObjectInstance to the list
}
}
// Apply query to allowed MBeans only.
//
Set< ObjectInstance > queryObjectInstanceList =
filterListOfObjectInstances(allowedList, query);
queryList = new HashSet< ObjectName >(queryObjectInstanceList.size());
for (ObjectInstance oi : queryObjectInstanceList) {
queryList.add(oi.getObjectName());
}
} else {
// Perform query.
//
queryList = queryNamesImpl(name, query);
}
return queryList;
}
|
public ObjectInstance registerMBean(Object object,
ObjectName name) throws MBeanRegistrationException, InstanceAlreadyExistsException, NotCompliantMBeanException {
// ------------------------------
// ------------------------------
Class theClass = object.getClass();
Introspector.checkCompliance(theClass);
final String infoClassName = getNewMBeanClassName(object);
checkMBeanPermission(infoClassName, null, name, "registerMBean");
checkMBeanTrustPermission(theClass);
return registerObject(infoClassName, object, name);
}
|
public void removeNotificationListener(ObjectName name,
NotificationListener listener) throws ListenerNotFoundException, InstanceNotFoundException {
removeNotificationListener(name, listener, null, null, true);
}
|
public void removeNotificationListener(ObjectName name,
ObjectName listener) throws ListenerNotFoundException, InstanceNotFoundException {
NotificationListener instance = getListener(listener);
if (MBEANSERVER_LOGGER.isLoggable(Level.FINER)) {
MBEANSERVER_LOGGER.logp(Level.FINER,
DefaultMBeanServerInterceptor.class.getName(),
"removeNotificationListener",
"ObjectName = " + name + ", Listener = " + listener);
}
server.removeNotificationListener(name, instance);
}
|
public void removeNotificationListener(ObjectName name,
NotificationListener listener,
NotificationFilter filter,
Object handback) throws ListenerNotFoundException, InstanceNotFoundException {
removeNotificationListener(name, listener, filter, handback, false);
}
|
public void removeNotificationListener(ObjectName name,
ObjectName listener,
NotificationFilter filter,
Object handback) throws ListenerNotFoundException, InstanceNotFoundException {
NotificationListener instance = getListener(listener);
if (MBEANSERVER_LOGGER.isLoggable(Level.FINER)) {
MBEANSERVER_LOGGER.logp(Level.FINER,
DefaultMBeanServerInterceptor.class.getName(),
"removeNotificationListener",
"ObjectName = " + name + ", Listener = " + listener);
}
server.removeNotificationListener(name, instance, filter, handback);
}
|
public void setAttribute(ObjectName name,
Attribute attribute) throws InstanceNotFoundException, InvalidAttributeValueException, ReflectionException, AttributeNotFoundException, MBeanException {
if (name == null) {
throw new RuntimeOperationsException(new
IllegalArgumentException("ObjectName name cannot be null"),
"Exception occurred trying to invoke the setter on the MBean");
}
if (attribute == null) {
throw new RuntimeOperationsException(new
IllegalArgumentException("Attribute cannot be null"),
"Exception occurred trying to invoke the setter on the MBean");
}
name = nonDefaultDomain(name);
if (MBEANSERVER_LOGGER.isLoggable(Level.FINER)) {
MBEANSERVER_LOGGER.logp(Level.FINER,
DefaultMBeanServerInterceptor.class.getName(),
"setAttribute", "ObjectName = " + name +
", Attribute = " + attribute.getName());
}
DynamicMBean instance = getMBean(name);
checkMBeanPermission(instance, attribute.getName(),
name, "setAttribute");
try {
instance.setAttribute(attribute);
} catch (AttributeNotFoundException e) {
throw e;
} catch (InvalidAttributeValueException e) {
throw e;
} catch (Throwable t) {
rethrowMaybeMBeanException(t);
throw new AssertionError();
}
}
|
public AttributeList setAttributes(ObjectName name,
AttributeList attributes) throws InstanceNotFoundException, ReflectionException {
if (name == null) {
throw new RuntimeOperationsException(new
IllegalArgumentException("ObjectName name cannot be null"),
"Exception occurred trying to invoke the setter on the MBean");
}
if (attributes == null) {
throw new RuntimeOperationsException(new
IllegalArgumentException("AttributeList cannot be null"),
"Exception occurred trying to invoke the setter on the MBean");
}
name = nonDefaultDomain(name);
final DynamicMBean instance = getMBean(name);
final AttributeList allowedAttributes;
final SecurityManager sm = System.getSecurityManager();
if (sm == null)
allowedAttributes = attributes;
else {
String classname = getClassName(instance);
// Check if the caller has the right to invoke 'setAttribute'
//
checkMBeanPermission(classname, null, name, "setAttribute");
// Check if the caller has the right to invoke 'setAttribute'
// on each specific attribute
//
allowedAttributes = new AttributeList(attributes.size());
for (Iterator i = attributes.iterator(); i.hasNext();) {
try {
Attribute attribute = (Attribute) i.next();
checkMBeanPermission(classname, attribute.getName(),
name, "setAttribute");
allowedAttributes.add(attribute);
} catch (SecurityException e) {
// OK: Do not add this attribute to the list
}
}
}
try {
return instance.setAttributes(allowedAttributes);
} catch (Throwable t) {
rethrow(t);
throw new AssertionError();
}
}
|
public void unregisterMBean(ObjectName name) throws InstanceNotFoundException, MBeanRegistrationException {
if (name == null) {
final RuntimeException wrapped =
new IllegalArgumentException("Object name cannot be null");
throw new RuntimeOperationsException(wrapped,
"Exception occurred trying to unregister the MBean");
}
name = nonDefaultDomain(name);
/* The semantics of preDeregister are tricky. If it throws an
exception, then the unregisterMBean fails. This allows an
MBean to refuse to be unregistered. If it returns
successfully, then the unregisterMBean can proceed. In
this case the preDeregister may have cleaned up some state,
and will not expect to be called a second time. So if two
threads try to unregister the same MBean at the same time
then one of them must wait for the other one to either (a)
call preDeregister and get an exception or (b) call
preDeregister successfully and unregister the MBean.
Suppose thread T1 is unregistering an MBean and thread T2
is trying to unregister the same MBean, so waiting for T1.
Then a deadlock is possible if the preDeregister for T1
ends up needing a lock held by T2. Given the semantics
just described, there does not seem to be any way to avoid
this. This will not happen to code where it is clear for
any given MBean what thread may unregister that MBean.
On the other hand we clearly do not want a thread that is
unregistering MBean A to have to wait for another thread
that is unregistering another MBean B (see bug 6318664). A
deadlock in this situation could reasonably be considered
gratuitous. So holding a global lock across the
preDeregister call would be bad.
So we have a set of ObjectNames that some thread is
currently unregistering. When a thread wants to unregister
a name, it must first check if the name is in the set, and
if so it must wait. When a thread successfully unregisters
a name it removes the name from the set and notifies any
waiting threads that the set has changed.
This implies that we must be very careful to ensure that
the name is removed from the set and waiters notified, no
matter what code path is taken. */
synchronized (beingUnregistered) {
while (beingUnregistered.contains(name)) {
try {
beingUnregistered.wait();
} catch (InterruptedException e) {
throw new MBeanRegistrationException(e, e.toString());
// pretend the exception came from preDeregister;
// in another execution sequence it could have
}
}
beingUnregistered.add(name);
}
try {
exclusiveUnregisterMBean(name);
} finally {
synchronized (beingUnregistered) {
beingUnregistered.remove(name);
beingUnregistered.notifyAll();
}
}
}
|