Skip to content

Instantly share code, notes, and snippets.

@nickman
Created April 12, 2012 12:14
Show Gist options
  • Save nickman/2366862 to your computer and use it in GitHub Desktop.
Save nickman/2366862 to your computer and use it in GitHub Desktop.
An example of an MBeanServer interceptor
package org.helios.jmx;
import java.io.ObjectInputStream;
import java.lang.management.ManagementFactory;
import java.util.Set;
import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.AttributeNotFoundException;
import javax.management.InstanceAlreadyExistsException;
import javax.management.InstanceNotFoundException;
import javax.management.IntrospectionException;
import javax.management.InvalidAttributeValueException;
import javax.management.ListenerNotFoundException;
import javax.management.MBeanException;
import javax.management.MBeanInfo;
import javax.management.MBeanRegistrationException;
import javax.management.MBeanServer;
import javax.management.MBeanServerBuilder;
import javax.management.MBeanServerDelegate;
import javax.management.MBeanServerFactory;
import javax.management.NotCompliantMBeanException;
import javax.management.NotificationFilter;
import javax.management.NotificationListener;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
import javax.management.OperationsException;
import javax.management.QueryExp;
import javax.management.ReflectionException;
import javax.management.loading.ClassLoaderRepository;
/**
* <p>Title: HeliosMBeanServerBuilder</p>
* <p>Description: Builds a intercepting MBeanServer</p>
* <p>Company: Helios Development Group LLC</p>
* @author Whitehead (nwhitehead AT heliosdev DOT org)
* <p><code>org.helios.jmx.HeliosMBeanServerBuilder</code></p>
*/
public class HeliosMBeanServerBuilder extends MBeanServerBuilder {
/** The ObjectName filter that defines which ObjectNames are renamed */
protected final ObjectName filter;
/** The ObjectName rename strategy */
protected final IRenameStrategy renameStartegy;
/** The system property name for the boot time defined filter */
public static final String PROP_FILTER = "helios.jmx.renamer.filter";
/** The system property name for the default filter */
public static final String DEFAULT_FILTER = "*:*";
/** The system property name for the boot time defined renaming strategy */
public static final String PROP_STRATEGY = "helios.jmx.renamer.strategy";
/** The system property name for the default filter */
public static final String DEFAULT_STRATEGY = AppendSerialRenamer.class.getName();
// -Dhelios.jmx.renamer.filter=java.util.logging:*
/**
* @param args
*/
public static void main(String[] args) {
System.out.println("MBeanServer Interceptor Test");
// Iterate through all the registered platform MBeanServer object names
for(ObjectName o: ManagementFactory.getPlatformMBeanServer().queryNames(null, null)) {
System.out.println(o);
}
// Wait so we can browse the MBeans in JConsole
try { Thread.currentThread().join(); } catch (Exception e) {}
}
/**
* Creates a new HeliosMBeanServerBuilder
* @param filter The ObjectName renaming filter
* @param renameStartegy The ObjectName renaming strategy
*/
public HeliosMBeanServerBuilder(ObjectName filter, IRenameStrategy renameStartegy) {
this.filter = filter;
this.renameStartegy = renameStartegy;
}
/**
* Creates a new HeliosMBeanServerBuilder using a system property defined filter and strategy
*/
public HeliosMBeanServerBuilder() {
this(objectName(System.getProperty(PROP_FILTER, DEFAULT_FILTER)), resolveStrategy(System.getProperty(PROP_STRATEGY, DEFAULT_STRATEGY)));
}
/**
* Safe ObjectName creator
* @param name The ObjectName string
* @return an ObjectName
*/
public static ObjectName objectName(String name) {
if(name==null) throw new IllegalArgumentException("The passed name was null", new Throwable());
try {
return new ObjectName(name);
} catch (Exception e) {
throw new RuntimeException("Failed to create ObjectName from [" + name + "]", e);
}
}
/**
* Resolves the passed class name into an IRenameStrategy instance
* @param className The IRenameStrategy class name
* @return an IRenameStrategy instance
*/
public static IRenameStrategy resolveStrategy(String className) {
try {
return (IRenameStrategy)Class.forName(className).newInstance();
} catch (Exception e) {
throw new RuntimeException("Failed to create renamer instance [" + className + "]", e);
}
}
/**
* {@inheritDoc}
* @see javax.management.MBeanServerBuilder#newMBeanServer(java.lang.String, javax.management.MBeanServer, javax.management.MBeanServerDelegate)
*/
public MBeanServer newMBeanServer(String defaultDomain, MBeanServer outer, MBeanServerDelegate delegate) {
return new RenamingMBeanServer(super.newMBeanServer(defaultDomain, outer, delegate), renameStartegy, filter);
}
/**
* <p>Title: IRenameStrategy</p>
* <p>Description: Defines a class that can rename an ObjectName using a specific pattern</p>
* <p>Company: Helios Development Group LLC</p>
* @author Whitehead (nwhitehead AT heliosdev DOT org)
* <p><code>org.helios.jmx.HeliosMBeanServerBuilder.IRenameStrategy</code></p>
*/
public interface IRenameStrategy {
/**
* Modifies the passed ObjectName to a new name
* @param toBeRenamed The ObjectName to rename
* @return the renamed ObjectName
*/
public ObjectName rename(ObjectName toBeRenamed);
}
/**
* <p>Title: AppendSerialRenamer</p>
* <p>Description: An IRenameStrategy that appends the hash code of the original ObjectName sting</p>
* <p>Company: Helios Development Group LLC</p>
* @author Whitehead (nwhitehead AT heliosdev DOT org)
* <p><code>org.helios.jmx.HeliosMBeanServerBuilder.AppendSerialRenamer</code></p>
*/
public static class AppendSerialRenamer implements IRenameStrategy {
public ObjectName rename(ObjectName toBeRenamed) {
if(toBeRenamed==null) throw new IllegalArgumentException("The passed object name was null", new Throwable());
try {
int serial = toBeRenamed.toString().hashCode();
return new ObjectName(toBeRenamed.toString() + ",serial=" + serial);
} catch (Exception e) {
throw new RuntimeException("Failed to rename ObjectName [" + toBeRenamed + "]", e);
}
}
}
/**
* <p>Title: RenamingMBeanServer</p>
* <p>Description: An MBeanServer wrapper that renames matching ObjectNames of registered MBeans</p>
* <p>Company: Helios Development Group LLC</p>
* @author Whitehead (nwhitehead AT heliosdev DOT org)
* <p><code>org.helios.jmx.HeliosMBeanServerBuilder.RenamingMBeanServer</code></p>
*/
public static class RenamingMBeanServer implements MBeanServer {
/** The actual MBeanServer delegate */
protected final MBeanServer inner;
/** The ObjectName renaming strategy */
protected final IRenameStrategy renamer;
/** The filter that determines which ObjectNames should be filtered */
protected final ObjectName filter;
/**
* Creates a new RenamingMBeanServer
* @param inner
* @param renamer
* @param filter
*/
public RenamingMBeanServer(MBeanServer inner, IRenameStrategy renamer, ObjectName filter) {
this.inner = inner;
this.renamer = renamer;
this.filter = filter;
}
/**
* @param object
* @param name
* @return
* @throws InstanceAlreadyExistsException
* @throws MBeanRegistrationException
* @throws NotCompliantMBeanException
* @see javax.management.MBeanServer#registerMBean(java.lang.Object, javax.management.ObjectName)
*/
public ObjectInstance registerMBean(Object object, ObjectName name)
throws InstanceAlreadyExistsException,
MBeanRegistrationException, NotCompliantMBeanException {
if(filter.apply(name)) {
name = renamer.rename(name);
}
return inner.registerMBean(object, name);
}
// =======================================================================
/**
* @param className
* @param name
* @return
* @throws ReflectionException
* @throws InstanceAlreadyExistsException
* @throws MBeanRegistrationException
* @throws MBeanException
* @throws NotCompliantMBeanException
* @see javax.management.MBeanServer#createMBean(java.lang.String, javax.management.ObjectName)
*/
public ObjectInstance createMBean(String className, ObjectName name)
throws ReflectionException, InstanceAlreadyExistsException,
MBeanRegistrationException, MBeanException,
NotCompliantMBeanException {
return inner.createMBean(className, name);
}
/**
* @param className
* @param name
* @param loaderName
* @return
* @throws ReflectionException
* @throws InstanceAlreadyExistsException
* @throws MBeanRegistrationException
* @throws MBeanException
* @throws NotCompliantMBeanException
* @throws InstanceNotFoundException
* @see javax.management.MBeanServer#createMBean(java.lang.String, javax.management.ObjectName, javax.management.ObjectName)
*/
public ObjectInstance createMBean(String className, ObjectName name,
ObjectName loaderName) throws ReflectionException,
InstanceAlreadyExistsException, MBeanRegistrationException,
MBeanException, NotCompliantMBeanException,
InstanceNotFoundException {
return inner.createMBean(className, name, loaderName);
}
/**
* @param className
* @param name
* @param params
* @param signature
* @return
* @throws ReflectionException
* @throws InstanceAlreadyExistsException
* @throws MBeanRegistrationException
* @throws MBeanException
* @throws NotCompliantMBeanException
* @see javax.management.MBeanServer#createMBean(java.lang.String, javax.management.ObjectName, java.lang.Object[], java.lang.String[])
*/
public ObjectInstance createMBean(String className, ObjectName name,
Object[] params, String[] signature)
throws ReflectionException, InstanceAlreadyExistsException,
MBeanRegistrationException, MBeanException,
NotCompliantMBeanException {
return inner.createMBean(className, name, params, signature);
}
/**
* @param className
* @param name
* @param loaderName
* @param params
* @param signature
* @return
* @throws ReflectionException
* @throws InstanceAlreadyExistsException
* @throws MBeanRegistrationException
* @throws MBeanException
* @throws NotCompliantMBeanException
* @throws InstanceNotFoundException
* @see javax.management.MBeanServer#createMBean(java.lang.String, javax.management.ObjectName, javax.management.ObjectName, java.lang.Object[], java.lang.String[])
*/
public ObjectInstance createMBean(String className, ObjectName name,
ObjectName loaderName, Object[] params, String[] signature)
throws ReflectionException, InstanceAlreadyExistsException,
MBeanRegistrationException, MBeanException,
NotCompliantMBeanException, InstanceNotFoundException {
return inner.createMBean(className, name, loaderName, params,
signature);
}
/**
* @param name
* @throws InstanceNotFoundException
* @throws MBeanRegistrationException
* @see javax.management.MBeanServer#unregisterMBean(javax.management.ObjectName)
*/
public void unregisterMBean(ObjectName name)
throws InstanceNotFoundException, MBeanRegistrationException {
inner.unregisterMBean(name);
}
/**
* @param name
* @return
* @throws InstanceNotFoundException
* @see javax.management.MBeanServer#getObjectInstance(javax.management.ObjectName)
*/
public ObjectInstance getObjectInstance(ObjectName name)
throws InstanceNotFoundException {
return inner.getObjectInstance(name);
}
/**
* @param name
* @param query
* @return
* @see javax.management.MBeanServer#queryMBeans(javax.management.ObjectName, javax.management.QueryExp)
*/
public Set<ObjectInstance> queryMBeans(ObjectName name, QueryExp query) {
return inner.queryMBeans(name, query);
}
/**
* @param name
* @param query
* @return
* @see javax.management.MBeanServer#queryNames(javax.management.ObjectName, javax.management.QueryExp)
*/
public Set<ObjectName> queryNames(ObjectName name, QueryExp query) {
return inner.queryNames(name, query);
}
/**
* @param name
* @return
* @see javax.management.MBeanServer#isRegistered(javax.management.ObjectName)
*/
public boolean isRegistered(ObjectName name) {
return inner.isRegistered(name);
}
/**
* @return
* @see javax.management.MBeanServer#getMBeanCount()
*/
public Integer getMBeanCount() {
return inner.getMBeanCount();
}
/**
* @param name
* @param attribute
* @return
* @throws MBeanException
* @throws AttributeNotFoundException
* @throws InstanceNotFoundException
* @throws ReflectionException
* @see javax.management.MBeanServer#getAttribute(javax.management.ObjectName, java.lang.String)
*/
public Object getAttribute(ObjectName name, String attribute)
throws MBeanException, AttributeNotFoundException,
InstanceNotFoundException, ReflectionException {
return inner.getAttribute(name, attribute);
}
/**
* @param name
* @param attributes
* @return
* @throws InstanceNotFoundException
* @throws ReflectionException
* @see javax.management.MBeanServer#getAttributes(javax.management.ObjectName, java.lang.String[])
*/
public AttributeList getAttributes(ObjectName name, String[] attributes)
throws InstanceNotFoundException, ReflectionException {
return inner.getAttributes(name, attributes);
}
/**
* @param name
* @param attribute
* @throws InstanceNotFoundException
* @throws AttributeNotFoundException
* @throws InvalidAttributeValueException
* @throws MBeanException
* @throws ReflectionException
* @see javax.management.MBeanServer#setAttribute(javax.management.ObjectName, javax.management.Attribute)
*/
public void setAttribute(ObjectName name, Attribute attribute)
throws InstanceNotFoundException, AttributeNotFoundException,
InvalidAttributeValueException, MBeanException,
ReflectionException {
inner.setAttribute(name, attribute);
}
/**
* @param name
* @param attributes
* @return
* @throws InstanceNotFoundException
* @throws ReflectionException
* @see javax.management.MBeanServer#setAttributes(javax.management.ObjectName, javax.management.AttributeList)
*/
public AttributeList setAttributes(ObjectName name,
AttributeList attributes) throws InstanceNotFoundException,
ReflectionException {
return inner.setAttributes(name, attributes);
}
/**
* @param name
* @param operationName
* @param params
* @param signature
* @return
* @throws InstanceNotFoundException
* @throws MBeanException
* @throws ReflectionException
* @see javax.management.MBeanServer#invoke(javax.management.ObjectName, java.lang.String, java.lang.Object[], java.lang.String[])
*/
public Object invoke(ObjectName name, String operationName,
Object[] params, String[] signature)
throws InstanceNotFoundException, MBeanException,
ReflectionException {
return inner.invoke(name, operationName, params, signature);
}
/**
* @return
* @see javax.management.MBeanServer#getDefaultDomain()
*/
public String getDefaultDomain() {
return inner.getDefaultDomain();
}
/**
* @return
* @see javax.management.MBeanServer#getDomains()
*/
public String[] getDomains() {
return inner.getDomains();
}
/**
* @param name
* @param listener
* @param filter
* @param handback
* @throws InstanceNotFoundException
* @see javax.management.MBeanServer#addNotificationListener(javax.management.ObjectName, javax.management.NotificationListener, javax.management.NotificationFilter, java.lang.Object)
*/
public void addNotificationListener(ObjectName name,
NotificationListener listener, NotificationFilter filter,
Object handback) throws InstanceNotFoundException {
inner.addNotificationListener(name, listener, filter, handback);
}
/**
* @param name
* @param listener
* @param filter
* @param handback
* @throws InstanceNotFoundException
* @see javax.management.MBeanServer#addNotificationListener(javax.management.ObjectName, javax.management.ObjectName, javax.management.NotificationFilter, java.lang.Object)
*/
public void addNotificationListener(ObjectName name,
ObjectName listener, NotificationFilter filter, Object handback)
throws InstanceNotFoundException {
inner.addNotificationListener(name, listener, filter, handback);
}
/**
* @param name
* @param listener
* @throws InstanceNotFoundException
* @throws ListenerNotFoundException
* @see javax.management.MBeanServer#removeNotificationListener(javax.management.ObjectName, javax.management.ObjectName)
*/
public void removeNotificationListener(ObjectName name,
ObjectName listener) throws InstanceNotFoundException,
ListenerNotFoundException {
inner.removeNotificationListener(name, listener);
}
/**
* @param name
* @param listener
* @param filter
* @param handback
* @throws InstanceNotFoundException
* @throws ListenerNotFoundException
* @see javax.management.MBeanServer#removeNotificationListener(javax.management.ObjectName, javax.management.ObjectName, javax.management.NotificationFilter, java.lang.Object)
*/
public void removeNotificationListener(ObjectName name,
ObjectName listener, NotificationFilter filter, Object handback)
throws InstanceNotFoundException, ListenerNotFoundException {
inner.removeNotificationListener(name, listener, filter, handback);
}
/**
* @param name
* @param listener
* @throws InstanceNotFoundException
* @throws ListenerNotFoundException
* @see javax.management.MBeanServer#removeNotificationListener(javax.management.ObjectName, javax.management.NotificationListener)
*/
public void removeNotificationListener(ObjectName name,
NotificationListener listener)
throws InstanceNotFoundException, ListenerNotFoundException {
inner.removeNotificationListener(name, listener);
}
/**
* @param name
* @param listener
* @param filter
* @param handback
* @throws InstanceNotFoundException
* @throws ListenerNotFoundException
* @see javax.management.MBeanServer#removeNotificationListener(javax.management.ObjectName, javax.management.NotificationListener, javax.management.NotificationFilter, java.lang.Object)
*/
public void removeNotificationListener(ObjectName name,
NotificationListener listener, NotificationFilter filter,
Object handback) throws InstanceNotFoundException,
ListenerNotFoundException {
inner.removeNotificationListener(name, listener, filter, handback);
}
/**
* @param name
* @return
* @throws InstanceNotFoundException
* @throws IntrospectionException
* @throws ReflectionException
* @see javax.management.MBeanServer#getMBeanInfo(javax.management.ObjectName)
*/
public MBeanInfo getMBeanInfo(ObjectName name)
throws InstanceNotFoundException, IntrospectionException,
ReflectionException {
return inner.getMBeanInfo(name);
}
/**
* @param name
* @param className
* @return
* @throws InstanceNotFoundException
* @see javax.management.MBeanServer#isInstanceOf(javax.management.ObjectName, java.lang.String)
*/
public boolean isInstanceOf(ObjectName name, String className)
throws InstanceNotFoundException {
return inner.isInstanceOf(name, className);
}
/**
* @param className
* @return
* @throws ReflectionException
* @throws MBeanException
* @see javax.management.MBeanServer#instantiate(java.lang.String)
*/
public Object instantiate(String className) throws ReflectionException,
MBeanException {
return inner.instantiate(className);
}
/**
* @param className
* @param loaderName
* @return
* @throws ReflectionException
* @throws MBeanException
* @throws InstanceNotFoundException
* @see javax.management.MBeanServer#instantiate(java.lang.String, javax.management.ObjectName)
*/
public Object instantiate(String className, ObjectName loaderName)
throws ReflectionException, MBeanException,
InstanceNotFoundException {
return inner.instantiate(className, loaderName);
}
/**
* @param className
* @param params
* @param signature
* @return
* @throws ReflectionException
* @throws MBeanException
* @see javax.management.MBeanServer#instantiate(java.lang.String, java.lang.Object[], java.lang.String[])
*/
public Object instantiate(String className, Object[] params,
String[] signature) throws ReflectionException, MBeanException {
return inner.instantiate(className, params, signature);
}
/**
* @param className
* @param loaderName
* @param params
* @param signature
* @return
* @throws ReflectionException
* @throws MBeanException
* @throws InstanceNotFoundException
* @see javax.management.MBeanServer#instantiate(java.lang.String, javax.management.ObjectName, java.lang.Object[], java.lang.String[])
*/
public Object instantiate(String className, ObjectName loaderName,
Object[] params, String[] signature)
throws ReflectionException, MBeanException,
InstanceNotFoundException {
return inner.instantiate(className, loaderName, params, signature);
}
/**
* @param name
* @param data
* @return
* @throws InstanceNotFoundException
* @throws OperationsException
* @deprecated
* @see javax.management.MBeanServer#deserialize(javax.management.ObjectName, byte[])
*/
public ObjectInputStream deserialize(ObjectName name, byte[] data)
throws InstanceNotFoundException, OperationsException {
return inner.deserialize(name, data);
}
/**
* @param className
* @param data
* @return
* @throws OperationsException
* @throws ReflectionException
* @deprecated
* @see javax.management.MBeanServer#deserialize(java.lang.String, byte[])
*/
public ObjectInputStream deserialize(String className, byte[] data)
throws OperationsException, ReflectionException {
return inner.deserialize(className, data);
}
/**
* @param className
* @param loaderName
* @param data
* @return
* @throws InstanceNotFoundException
* @throws OperationsException
* @throws ReflectionException
* @deprecated
* @see javax.management.MBeanServer#deserialize(java.lang.String, javax.management.ObjectName, byte[])
*/
public ObjectInputStream deserialize(String className,
ObjectName loaderName, byte[] data)
throws InstanceNotFoundException, OperationsException,
ReflectionException {
return inner.deserialize(className, loaderName, data);
}
/**
* @param mbeanName
* @return
* @throws InstanceNotFoundException
* @see javax.management.MBeanServer#getClassLoaderFor(javax.management.ObjectName)
*/
public ClassLoader getClassLoaderFor(ObjectName mbeanName)
throws InstanceNotFoundException {
return inner.getClassLoaderFor(mbeanName);
}
/**
* @param loaderName
* @return
* @throws InstanceNotFoundException
* @see javax.management.MBeanServer#getClassLoader(javax.management.ObjectName)
*/
public ClassLoader getClassLoader(ObjectName loaderName)
throws InstanceNotFoundException {
return inner.getClassLoader(loaderName);
}
/**
* @return
* @see javax.management.MBeanServer#getClassLoaderRepository()
*/
public ClassLoaderRepository getClassLoaderRepository() {
return inner.getClassLoaderRepository();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment