
org.eclipse.jetty.jmx.ObjectMBean Maven / Gradle / Ivy
//
// ========================================================================
// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.jmx;
import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.AttributeNotFoundException;
import javax.management.DynamicMBean;
import javax.management.MBeanException;
import javax.management.MBeanInfo;
import javax.management.ObjectName;
import javax.management.ReflectionException;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
/**
* A dynamic MBean that can wrap an arbitrary Object instance.
* The attributes and operations exposed by this bean are controlled
* by the merge of annotations discovered in all superclasses and all
* superinterfaces.
* Given class {@code com.acme.Foo}, then {@code com.acme.jmx.FooMBean}
* is searched; if found, it is instantiated with the {@code com.acme.Foo}
* instance passed to the constructor.
* Class {@code com.acme.jmx.FooMBean} can then override the default
* behavior of ObjectMBean and provide a custom ObjectName, or custom
* ObjectName properties {@code name} and {@code context}, etc.
*/
public class ObjectMBean implements DynamicMBean
{
private static final Logger LOG = Log.getLogger(ObjectMBean.class);
protected final Object _managed;
private MetaData _metaData;
private MBeanContainer _mbeanContainer;
/**
* Creates a new ObjectMBean wrapping the given {@code managedObject}.
*
* @param managedObject the object to manage
*/
public ObjectMBean(Object managedObject)
{
_managed = managedObject;
}
/**
* @return the managed object
*/
public Object getManagedObject()
{
return _managed;
}
/**
* Allows to customize the ObjectName of this MBean.
*
* @return a custom ObjectName, or null to indicate to {@link MBeanContainer} to create a default ObjectName
*/
public ObjectName getObjectName()
{
return null;
}
/**
* Allows to customize the ObjectName property {@code context}.
* When {@link MBeanContainer} creates default ObjectNames, the {@code context} property
* is "inherited" recursively by MBeans that are children of this MBean; this allows to
* "group" descendant MBeans so that it is clear who is the ancestor they belong to.
* For example, if object A has a child component B which has children components C,
* then AMBean can override this method to return "alpha", and then the ObjectNames will be:
*
* - domain:type=a,context=alpha,id=0
* - domain:type=b,context=alpha,id=0
* - domain:type=c,context=alpha,id=0
* - domain:type=c,context=alpha,id=1
*
*
* @return a custom value for the property {@code context}
*/
public String getObjectContextBasis()
{
return null;
}
/**
* Allows to customize the ObjectName property {@code name}.
* Certain components have a natural name and returning it from this method
* allows it to be part of the ObjectName.
*
* @return a custom value for the property {@code name}
*/
public String getObjectNameBasis()
{
return null;
}
protected void setMBeanContainer(MBeanContainer container)
{
this._mbeanContainer = container;
}
public MBeanContainer getMBeanContainer()
{
return this._mbeanContainer;
}
/**
* @param o the object to wrap as MBean
* @return a new instance of an MBean for the object or null if the MBean cannot be created
* @deprecated Use {@link MBeanContainer#mbeanFor(Object)} instead
*/
@Deprecated
public static Object mbeanFor(Object o)
{
return MBeanContainer.mbeanFor(null, o);
}
@Override
public MBeanInfo getMBeanInfo()
{
return metaData().getMBeanInfo();
}
@Override
public Object getAttribute(String name) throws AttributeNotFoundException, ReflectionException, MBeanException
{
ClassLoader prevLoader = Thread.currentThread().getContextClassLoader();
try
{
return metaData().getAttribute(name, this);
}
finally
{
Thread.currentThread().setContextClassLoader(prevLoader);
}
}
@Override
public AttributeList getAttributes(String[] names)
{
AttributeList results = new AttributeList(names.length);
for (String name : names)
{
try
{
results.add(new Attribute(name, getAttribute(name)));
}
catch (Throwable x)
{
if (LOG.isDebugEnabled())
LOG.debug(x);
}
}
return results;
}
@Override
public void setAttribute(Attribute attribute) throws AttributeNotFoundException, ReflectionException, MBeanException
{
ClassLoader prevLoader = Thread.currentThread().getContextClassLoader();
try
{
metaData().setAttribute(attribute, this);
}
finally
{
Thread.currentThread().setContextClassLoader(prevLoader);
}
}
@Override
public AttributeList setAttributes(AttributeList attributes)
{
AttributeList results = new AttributeList(attributes.size());
for (Attribute attribute : attributes.asList())
{
try
{
setAttribute(attribute);
results.add(new Attribute(attribute.getName(), getAttribute(attribute.getName())));
}
catch (Throwable x)
{
if (LOG.isDebugEnabled())
LOG.debug(x);
}
}
return results;
}
@Override
public Object invoke(String name, Object[] params, String[] signature) throws ReflectionException, MBeanException
{
ClassLoader prevLoader = Thread.currentThread().getContextClassLoader();
try
{
return metaData().invoke(name, signature, params, this);
}
finally
{
Thread.currentThread().setContextClassLoader(prevLoader);
}
}
ObjectName findObjectName(Object bean)
{
return _mbeanContainer.findMBean(bean);
}
Object findBean(ObjectName objectName)
{
return _mbeanContainer.findBean(objectName);
}
MetaData metaData()
{
if (_metaData == null)
_metaData = MBeanContainer.findMetaData(_mbeanContainer, _managed.getClass());
return _metaData;
}
}