User: ejort
Date: 02/02/22 08:44:32
Modified: src/main/org/jboss/mx/server MBeanServerImpl.java
Added: src/main/org/jboss/mx/server ServerObjectInstance.java
Log:
Default Domain, Querying, Various Other Fixes
Revision Changes Path
1.16 +349 -137 jmx/src/main/org/jboss/mx/server/MBeanServerImpl.java
Index: MBeanServerImpl.java
===================================================================
RCS file: /cvsroot/jboss/jmx/src/main/org/jboss/mx/server/MBeanServerImpl.java,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- MBeanServerImpl.java 18 Feb 2002 20:10:54 -0000 1.15
+++ MBeanServerImpl.java 22 Feb 2002 16:44:32 -0000 1.16
@@ -6,6 +6,20 @@
*/
package org.jboss.mx.server;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.InvocationTargetException;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.AttributeNotFoundException;
@@ -15,6 +29,7 @@
import javax.management.IntrospectionException;
import javax.management.InvalidAttributeValueException;
import javax.management.ListenerNotFoundException;
+import javax.management.MalformedObjectNameException;
import javax.management.MBeanException;
import javax.management.MBeanInfo;
import javax.management.MBeanRegistration;
@@ -22,14 +37,12 @@
import javax.management.MBeanServer;
import javax.management.MBeanServerDelegate;
import javax.management.MBeanServerNotification;
-import javax.management.MalformedObjectNameException;
-import javax.management.NotCompliantMBeanException;
import javax.management.NotCompliantMBeanException;
import javax.management.NotificationBroadcaster;
-import javax.management.NotificationFilter;
import javax.management.NotificationListener;
-import javax.management.ObjectInstance;
+import javax.management.NotificationFilter;
import javax.management.ObjectName;
+import javax.management.ObjectInstance;
import javax.management.OperationsException;
import javax.management.QueryExp;
import javax.management.ReflectionException;
@@ -38,19 +51,11 @@
import javax.management.RuntimeOperationsException;
import javax.management.loading.DefaultLoaderRepository;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-
import org.jboss.mx.capability.MBeanCapability;
import org.jboss.mx.interceptor.MBeanInvoker;
import org.jboss.mx.interceptor.MBeanTarget;
import org.jboss.mx.loading.LoaderRepository;
+import org.jboss.mx.logging.Logger;
import org.jboss.mx.server.registry.BasicMBeanRegistry;
import org.jboss.mx.server.registry.MBeanEntry;
import org.jboss.mx.server.registry.MBeanRegistry;
@@ -84,7 +89,8 @@
* @see org.jboss.mx.modelmbean.XMBean
*
* @author <a href="mailto:[EMAIL PROTECTED]">Juha Lindfors</a>.
- * @version $Revision: 1.15 $
+ * @author <a href="mailto:[EMAIL PROTECTED]">Adrian Brock</a>.
+ * @version $Revision: 1.16 $
*/
public class MBeanServerImpl
implements MBeanServer, ServerConstants
@@ -123,6 +129,18 @@
*/
protected LoaderRepository loaderRepository =
LoaderRepository.getDefaultLoaderRepository();
+ // Static --------------------------------------------------------
+
+ /**
+ * Magic token to protect reserved domain
+ */
+ protected static String JMImplementation = "JMImplementation";
+
+ /**
+ * The logger
+ */
+ private static Logger log = Logger.getLogger(MBeanServerImpl.class);
+
// Constructors --------------------------------------------------
/**
* Creates an MBean server implementation with a given default domain name and
@@ -133,12 +151,13 @@
public MBeanServerImpl(String defaultDomain)
{
this.defaultDomain = defaultDomain;
- this.registry = new BasicMBeanRegistry();
+ this.registry = new BasicMBeanRegistry(defaultDomain);
this.delegate = new MBeanServerDelegate();
try
{
- registerMBean(delegate, new ObjectName(MBEAN_SERVER_DELEGATE));
+ registerMBean(delegate, new ObjectName(MBEAN_SERVER_DELEGATE),
+ JMImplementation);
}
catch (MalformedObjectNameException e)
{
@@ -172,9 +191,7 @@
{
handleInstantiateExceptions(t, className);
- // FIXME: log it
- System.out.println("Unhandled exception: " + t.toString());
- t.printStackTrace();
+ log.error("Unhandled exception instantiating class: " + className, t);
return null;
}
@@ -202,9 +219,7 @@
{
handleInstantiateExceptions(t, className);
- // FIXME: log it
- System.out.println("Unhandled exception: " + t.toString());
- t.printStackTrace();
+ log.error("Unhandled exception instantiating class: " + className, t);
return null;
}
@@ -316,100 +331,49 @@
throws ReflectionException, InstanceAlreadyExistsException,
MBeanRegistrationException, MBeanException, NotCompliantMBeanException
{
Object mbean = instantiate(className);
- return registerMBean(mbean, name);
+ return registerMBean(mbean, name, null);
}
public ObjectInstance createMBean(String className, ObjectName name, ObjectName
loaderName)
throws ReflectionException, InstanceAlreadyExistsException,
MBeanRegistrationException, MBeanException, NotCompliantMBeanException,
InstanceNotFoundException
{
Object mbean = instantiate(className, loaderName);
- return registerMBean(mbean, name);
+ return registerMBean(mbean, name, null);
}
public ObjectInstance createMBean(String className, ObjectName name, Object[]
params, String[] signature)
throws ReflectionException, InstanceAlreadyExistsException,
MBeanRegistrationException, MBeanException, NotCompliantMBeanException
{
Object mbean = instantiate(className, params, signature);
- return registerMBean(mbean, name);
+ return registerMBean(mbean, name, null);
}
public ObjectInstance createMBean(String className, ObjectName name, ObjectName
loaderName, Object[] params, String[] signature)
throws ReflectionException, InstanceAlreadyExistsException,
MBeanRegistrationException, MBeanException, NotCompliantMBeanException,
InstanceNotFoundException
{
Object mbean = instantiate(className, loaderName, params, signature);
- return registerMBean(mbean, name);
+ return registerMBean(mbean, name, null);
}
public ObjectInstance registerMBean(Object object, ObjectName name)
- throws InstanceAlreadyExistsException, MBeanRegistrationException,
NotCompliantMBeanException
+ throws InstanceAlreadyExistsException,
+ MBeanRegistrationException,
+ NotCompliantMBeanException
{
-
- MBeanEntry entry = null;
- boolean registrationDone = true;
-
- MBeanCapability mbcap = MBeanCapability.of(object.getClass());
- MBeanRegistration registrationInterface = mbcap.getMBeanRegistration(object);
-
- if (null != registrationInterface)
- {
- try
- {
- ObjectName mbeanName = registrationInterface.preRegister(this, name);
- if (name == null)
- name = mbeanName;
- }
- catch (Throwable t)
- {
- // FIXME: logging
- System.out.println("Registration Failed:");
- t.printStackTrace();
- registrationDone = false;
- }
- }
-
- if (registrationDone)
- {
- if (isRegistered(name))
- {
- registrationInterface.postRegister(new Boolean(false));
- throw new InstanceAlreadyExistsException("MBean " + name + " already
registered.");
- }
-
- MBeanTarget target = new MBeanTarget(mbcap.getMBean(object));
- MBeanInvoker invoker = new MBeanInvoker(target);
-
- entry = new MBeanEntry(name, invoker, object);
-
- registry.add(entry);
-
- if (object instanceof ClassLoader)
- loaderRepository.addClassLoader((ClassLoader)object);
-
- delegate.sendNotification(
- new MBeanServerNotification(
- MBeanServerNotification.REGISTRATION_NOTIFICATION,
- delegate,
- registrationNotificationSequence++,
- name
- )
- );
- }
-
- if (registrationInterface != null)
- registrationInterface.postRegister(new Boolean(registrationDone));
-
- return (registrationDone)
- ? new ObjectInstance(name, entry.getResourceClassName())
- : null;
+ return registerMBean(object, name, null);
}
- public void unregisterMBean(ObjectName name) throws InstanceNotFoundException,
MBeanRegistrationException
+ public void unregisterMBean(ObjectName name)
+ throws InstanceNotFoundException, MBeanRegistrationException
{
- // FIXME: security for unregister (mbean delegate)
+ name = qualifyName(name);
+ if (name.getDomain().equals(JMImplementation))
+ throw new RuntimeOperationsException(new IllegalArgumentException(
+ "Not allowed to unregister: " + name.toString()));
+
Object resource = registry.get(name).getResourceInstance();
MBeanRegistration registrationInterface = null;
- boolean unregisterSuccessful = true;
if (resource instanceof MBeanRegistration)
{
@@ -418,15 +382,18 @@
{
registrationInterface.preDeregister();
}
- catch (Throwable t)
+ catch (Exception e)
{
- return;
+ throw new MBeanRegistrationException(e, "preDeregister");
}
}
- registry.remove(name);
+ // Remove any classloader
+ if (resource instanceof ClassLoader)
+ loaderRepository.removeClassLoader((ClassLoader)resource);
- // FIXME: if CL, remove from class loader repository
+ // It is no longer registered
+ registry.remove(name);
delegate.sendNotification(
new MBeanServerNotification(
@@ -441,22 +408,59 @@
registrationInterface.postDeregister();
}
- public ObjectInstance getObjectInstance(ObjectName name) throws
InstanceNotFoundException
+ public ObjectInstance getObjectInstance(ObjectName name)
+ throws InstanceNotFoundException
{
if (!isRegistered(name))
throw new InstanceNotFoundException(name + " not registered.");
- return new ObjectInstance(name, registry.get(name).getResourceClassName());
+ return new ServerObjectInstance(qualifyName(name),
+ registry.get(name).getResourceClassName(), delegate.getMBeanServerId());
}
- public java.util.Set queryMBeans(ObjectName name, QueryExp query)
+ public Set queryMBeans(ObjectName name, QueryExp query)
{
- return null;
+ // Set up the query
+ Set result = new HashSet();
+ if (query != null)
+ query.setMBeanServer(this);
+
+ // Get the possible MBeans
+ List entries = registry.findEntries(name);
+ Iterator iterator = entries.iterator();
+ while (iterator.hasNext())
+ {
+ // Check each MBean against the query
+ MBeanEntry entry = (MBeanEntry) iterator.next();
+ ObjectName objectName = entry.getObjectName();
+ if (queryMBean(objectName, query) == true)
+ result.add(new ServerObjectInstance(objectName,
+ entry.getResourceClassName(), delegate.getMBeanServerId()));
+ }
+
+ return result;
}
- public java.util.Set queryNames(ObjectName name, QueryExp query)
+ public Set queryNames(ObjectName name, QueryExp query)
{
- return null;
+ // Set up the query
+ Set result = new HashSet();
+ if (query != null)
+ query.setMBeanServer(this);
+
+ // Get the possible MBeans
+ List entries = registry.findEntries(name);
+ Iterator iterator = entries.iterator();
+ while (iterator.hasNext())
+ {
+ // Check each MBean against the query
+ MBeanEntry entry = (MBeanEntry) iterator.next();
+ ObjectName objectName = entry.getObjectName();
+ if (queryMBean(objectName, query) == true)
+ result.add(objectName);
+ }
+
+ return result;
}
public boolean isRegistered(ObjectName name)
@@ -470,14 +474,18 @@
}
public Object getAttribute(ObjectName name, String attribute)
- throws MBeanException, AttributeNotFoundException, InstanceNotFoundException,
ReflectionException
+ throws MBeanException,
+ AttributeNotFoundException,
+ InstanceNotFoundException,
+ ReflectionException
{
DynamicMBean mbean = registry.get(name).getMBean();
return mbean.getAttribute(attribute);
}
public AttributeList getAttributes(ObjectName name, String[] attributes)
- throws InstanceNotFoundException, ReflectionException
+ throws InstanceNotFoundException,
+ ReflectionException
{
DynamicMBean mbean = registry.get(name).getMBean();
return mbean.getAttributes(attributes);
@@ -633,6 +641,155 @@
}
// Protected -----------------------------------------------------
+
+ /**
+ * Register an MBean<p>
+ *
+ * Pass {@link JMImplementation} in the magic token to get access to the
+ * reserved domain<p>
+ *
+ * TODO: Flesh this out
+ *
+ * @param object the mbean to register
+ * @param name the object name to register
+ * @param magicToken used to get access to the
+ * @exception InstanceAlreadyExistsException when already registered
+ * @exception MBeanRegistrationException when
+ * preRegister(MBeanServer, ObjectName) throws an exception
+ * @exception NotCompliantMBeanException when the object is not an MBean
+ * @exception RuntimeOperationException containing an
+ * IllegalArgumentException for another problem with the name
+ * or a null object
+ */
+ protected ObjectInstance registerMBean(Object object, ObjectName name,
+ String magicToken)
+ throws InstanceAlreadyExistsException,
+ MBeanRegistrationException,
+ NotCompliantMBeanException
+ {
+ boolean registrationDone = true;
+ ObjectName regName = name;
+
+ // Check the objects compliance
+ if (object == null)
+ throw new RuntimeOperationsException(
+ new IllegalArgumentException("Null object"));
+ MBeanCapability mbcap = MBeanCapability.of(object.getClass());
+
+ // Does the bean require registration processing?
+ MBeanRegistration registrationInterface = mbcap.getMBeanRegistration(object);
+
+ try
+ {
+ // Do the preRegister, pass the fully qualified name
+ if (null != registrationInterface)
+ {
+ if (regName != null)
+ regName = qualifyName(regName);
+
+ try
+ {
+ ObjectName mbean = registrationInterface.preRegister(this, regName);
+ if (regName == null)
+ regName = mbean;
+ }
+ catch (Exception e)
+ {
+ throw new MBeanRegistrationException(e, "Registration failed");
+ }
+ catch (Throwable t)
+ {
+ log.debug("Registration failed: ", t);
+ throw t;
+ }
+ }
+
+ // This is the final check of the name
+ regName = validateAndQualifyName(regName, magicToken);
+
+ try
+ {
+ // Register the mbean
+ MBeanTarget target = new MBeanTarget(mbcap.getMBean(object));
+ MBeanInvoker invoker = new MBeanInvoker(target);
+ MBeanEntry entry = new MBeanEntry(regName, invoker, object);
+ registry.add(entry);
+
+ try
+ {
+ // Add the classloader to the repository
+ if (object instanceof ClassLoader)
+ loaderRepository.addClassLoader((ClassLoader)object);
+
+ try
+ {
+ delegate.sendNotification(
+ new MBeanServerNotification(
+ MBeanServerNotification.REGISTRATION_NOTIFICATION,
+ delegate, registrationNotificationSequence++, regName));
+
+ return new ServerObjectInstance(regName,
entry.getResourceClassName(),
+ delegate.getMBeanServerId());
+ }
+ catch (Throwable t)
+ {
+ // Problem, remove a classloader from the repository
+ if (object instanceof ClassLoader)
+ loaderRepository.removeClassLoader((ClassLoader)object);
+ throw t;
+ }
+ }
+ catch (Throwable t)
+ {
+ // Problem, remove the mbean from the registry
+ registry.remove(regName);
+ throw t;
+ }
+ }
+ // Thrown by the registry
+ catch (InstanceAlreadyExistsException e)
+ {
+ throw e;
+ }
+ catch (Throwable t)
+ {
+ // Something is broken
+ log.error("Unexpected Exception:", t);
+ throw t;
+ }
+ }
+ catch (InstanceAlreadyExistsException e)
+ {
+ // It was already registered
+ registrationDone = false;
+ throw e;
+ }
+ catch (MBeanRegistrationException e)
+ {
+ // The MBean cancelled the registration
+ registrationDone = false;
+ throw e;
+ }
+ catch (RuntimeOperationsException e)
+ {
+ // There was a problem with one the arguments
+ registrationDone = false;
+ throw e;
+ }
+ catch (Throwable t)
+ {
+ // Some other error
+ registrationDone = false;
+ return null;
+ }
+ finally
+ {
+ // Tell the MBean the result of the registration
+ if (registrationInterface != null)
+ registrationInterface.postRegister(new Boolean(registrationDone));
+ }
+ }
+
protected void handleInstantiateExceptions(Throwable t, String className) throws
ReflectionException, MBeanException
{
if (t instanceof ClassNotFoundException)
@@ -688,49 +845,104 @@
}
}
- protected int getMBeanType(Object object)
- {
-
- Class clazz = object.getClass();
- int type = NOT_AN_MBEAN;
-
- while (clazz != null)
- {
- Class[] interfaces = clazz.getInterfaces();
+ // Private -------------------------------------------------------
- for (int i = 0; i < interfaces.length; ++i)
- {
- type = getMBeanInterface(clazz.getName(), interfaces[i]);
- if (type != NOT_AN_MBEAN)
- return type;
+ /**
+ * Validates and qualifies an MBean<p>
+ *
+ * Validates the name is not a pattern.<p>
+ *
+ * Adds the default domain if no domain is specified.<p>
+ *
+ * Checks the name is not in the reserved domain JMImplementation when
+ * the magicToken is not {@link JMImplementation}
+ *
+ * @param name the name to validate
+ * @param magicToken used to get access to the reserved domain
+ * @return the original name or the name prepended with the default domain
+ * if no domain is specified.
+ * @exception RuntimeOperationException containing an
+ * IllegalArgumentException for a problem with the name
+ */
+ private final ObjectName validateAndQualifyName(ObjectName name,
+ String magicToken)
+ {
+ // Check for qualification
+ ObjectName result = qualifyName(name);
- Class[] superInterfaces = interfaces[i].getInterfaces();
- for (int j = 0; j < superInterfaces.length; ++j)
- {
- type = getMBeanInterface(clazz.getName(), superInterfaces[j]);
- if (type != NOT_AN_MBEAN)
- return type;
- }
- }
- clazz = clazz.getSuperclass();
- }
+ // Make sure the name is not a pattern
+ if (result.isPattern())
+ throw new RuntimeOperationsException(
+ new IllegalArgumentException("Object name is a pattern:" + name));
+
+ // Check for reserved domain
+ if (magicToken != JMImplementation &&
+ result.getDomain().equals(JMImplementation))
+ throw new RuntimeOperationsException(new IllegalArgumentException(
+ "Domain " + JMImplementation + " is reserved"));
+
+ // Is it already registered? AB: Left to the registry to check, more atomic
+ // if (isRegistered(result))
+ // throw new InstanceAlreadyExistsException(
+ // "MBean " + result + " already registered.");
- return type;
+ // I can't think of anymore tests, we're done
+ return result;
}
- // Private -------------------------------------------------------
- private static int DYNAMIC_MBEAN = 0x321;
- private static int STANDARD_MBEAN = 0x123;
- private static int NOT_AN_MBEAN = 0xc0de;
-
- private int getMBeanInterface(String className, Class c)
- {
- if (c.getName().equals("javax.management.DynamicMBean"))
- return DYNAMIC_MBEAN;
- if (c.getName().equals(className + "MBean"))
- return STANDARD_MBEAN;
- return NOT_AN_MBEAN;
+ /**
+ * Qualify an object name with the default domain<p>
+ *
+ * Adds the default domain if no domain is specified.
+ *
+ * @param name the name to qualify
+ * @return the original name or the name prepended with the default domain
+ * if no domain is specified.
+ * @exception RuntimeOperationException containing an
+ * IllegalArgumentException when there is a problem
+ */
+ private final ObjectName qualifyName(ObjectName name)
+ {
+ if (name == null)
+ throw new RuntimeOperationsException(
+ new IllegalArgumentException("Null object name"));
+ try
+ {
+ if (name.getDomain().length() == 0)
+ return new ObjectName(defaultDomain + ":" +
+ name.getCanonicalKeyPropertyListString());
+ else
+ return name;
+ }
+ catch (MalformedObjectNameException e)
+ {
+ throw new RuntimeOperationsException(
+ new IllegalArgumentException(e.toString()));
+ }
}
+ /**
+ * Query an MBean against the query
+ *
+ * @param objectName the object name of the mbean to check
+ * @param queryExp the query expression to test
+ * @return true when the query applies to the MBean or the query is null,
+ * false otherwise.
+ */
+ private boolean queryMBean(ObjectName objectName, QueryExp queryExp)
+ {
+ if (queryExp == null)
+ return true;
+
+ try
+ {
+ return queryExp.apply(objectName);
+ }
+ catch (Exception e)
+ {
+// TODO Is this correct?
+ return false;
+ }
+ }
}
1.1 jmx/src/main/org/jboss/mx/server/ServerObjectInstance.java
Index: ServerObjectInstance.java
===================================================================
/*
* JBoss, the OpenSource J2EE webOS
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package org.jboss.mx.server;
import java.io.ObjectStreamException;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
/**
* An Object Instance that differentiates between MBeanServers.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Adrian Brock</a>.
* @version $Revision: 1.1 $
*/
public class ServerObjectInstance
extends ObjectInstance
{
// Constants ---------------------------------------------------
// Attributes --------------------------------------------------
/**
* The agent id
*/
String agentID;
// Static ------------------------------------------------------
// Constructors ------------------------------------------------
/**
* Create a new Server Object Instance
*
* @param name the object name
* @param className the class name
* @param agentID the agentID
*/
public ServerObjectInstance(ObjectName name, String className, String agentID)
{
super(name, className);
this.agentID = agentID;
}
// Public ------------------------------------------------------
/**
* Retrieve the agent id of the object instance
*
* @return the agent id
*/
String getAgentID()
{
return agentID;
}
// X implementation --------------------------------------------
// ObjectInstance overrides ------------------------------------
public boolean equals(Object object)
{
if (object instanceof ServerObjectInstance)
return (super.equals(object) == true
&& this.agentID.equals(((ServerObjectInstance)object).agentID));
else
return super.equals(object);
}
// Protected ---------------------------------------------------
// Private -----------------------------------------------------
/**
* We replace ourself with an ObjectInstance in the stream.
* This loses the agentId which isn't part of the spec.
*
* @return an ObjectInstance version of ourself
* @exception ObjectStreamException for a serialization error
*/
private Object writeReplace()
throws ObjectStreamException
{
return new ObjectInstance(getObjectName(), getClassName());
}
// Inner classes -----------------------------------------------
}
_______________________________________________
Jboss-development mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/jboss-development