alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Spring Framework example source code file (JmxUtils.java)

This example Spring Framework source code file (JmxUtils.java) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Spring Framework tags/keywords

bean, boolean, class, class, classnotfoundexception, found, hashtable, javabean, management, mbean_suffix, mbeanserver, mbeanserver, mbeanservernotfoundexception, mbeanservernotfoundexception, mxbean, reflection, string, string, util

The Spring Framework JmxUtils.java source code

/*
 * Copyright 2002-2007 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.jmx.support;

import java.beans.PropertyDescriptor;
import java.lang.management.ManagementFactory;
import java.lang.reflect.Method;
import java.util.Hashtable;
import java.util.List;

import javax.management.DynamicMBean;
import javax.management.MBeanParameterInfo;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.MXBean;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.springframework.core.JdkVersion;
import org.springframework.jmx.MBeanServerNotFoundException;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

/**
 * Collection of generic utility methods to support Spring JMX.
 * Includes a convenient method to locate an MBeanServer.
 *
 * @author Rob Harrop
 * @author Juergen Hoeller
 * @since 1.2
 * @see #locateMBeanServer
 */
public abstract class JmxUtils {

	/**
	 * The key used when extending an existing {@link ObjectName} with the
	 * identity hash code of its corresponding managed resource.
	 */
	public static final String IDENTITY_OBJECT_NAME_KEY = "identity";

	/**
	 * Suffix used to identify an MBean interface.
	 */
	private static final String MBEAN_SUFFIX = "MBean";

	/**
	 * Suffix used to identify a Java 6 MXBean interface.
	 */
	private static final String MXBEAN_SUFFIX = "MXBean";

	private static final String MXBEAN_ANNOTATION_CLASS_NAME = "javax.management.MXBean";


	private static final boolean mxBeanAnnotationAvailable =
			ClassUtils.isPresent(MXBEAN_ANNOTATION_CLASS_NAME, JmxUtils.class.getClassLoader());

	private static final Log logger = LogFactory.getLog(JmxUtils.class);


	/**
	 * Attempt to find a locally running <code>MBeanServer. Fails if no
	 * <code>MBeanServer can be found. Logs a warning if more than one
	 * <code>MBeanServer found, returning the first one from the list.
	 * @return the <code>MBeanServer if found
	 * @throws org.springframework.jmx.MBeanServerNotFoundException
	 * if no <code>MBeanServer could be found
	 * @see javax.management.MBeanServerFactory#findMBeanServer
	 */
	public static MBeanServer locateMBeanServer() throws MBeanServerNotFoundException {
		return locateMBeanServer(null);
	}

	/**
	 * Attempt to find a locally running <code>MBeanServer. Fails if no
	 * <code>MBeanServer can be found. Logs a warning if more than one
	 * <code>MBeanServer found, returning the first one from the list.
	 * @param agentId the agent identifier of the MBeanServer to retrieve.
	 * If this parameter is <code>null, all registered MBeanServers are
	 * considered.
	 * @return the <code>MBeanServer if found
	 * @throws org.springframework.jmx.MBeanServerNotFoundException
	 * if no <code>MBeanServer could be found
	 * @see javax.management.MBeanServerFactory#findMBeanServer(String)
	 */
	public static MBeanServer locateMBeanServer(String agentId) throws MBeanServerNotFoundException {
		List servers = MBeanServerFactory.findMBeanServer(agentId);

		MBeanServer server = null;
		if (servers != null && servers.size() > 0) {
			// Check to see if an MBeanServer is registered.
			if (servers.size() > 1 && logger.isWarnEnabled()) {
				logger.warn("Found more than one MBeanServer instance" +
						(agentId != null ? " with agent id [" + agentId + "]" : "") +
						". Returning first from list.");
			}
			server = (MBeanServer) servers.get(0);
		}

		if (server == null && agentId == null && JdkVersion.isAtLeastJava15()) {
			// Attempt to load the PlatformMBeanServer.
			try {
				server = ManagementFactory.getPlatformMBeanServer();
			}
			catch (SecurityException ex) {
				throw new MBeanServerNotFoundException("No specific MBeanServer found, " +
						"and not allowed to obtain the Java platform MBeanServer", ex);
			}
		}

		if (server == null) {
			throw new MBeanServerNotFoundException(
					"Unable to locate an MBeanServer instance" +
					(agentId != null ? " with agent id [" + agentId + "]" : ""));
		}

		if (logger.isDebugEnabled()) {
			logger.debug("Found MBeanServer: " + server);
		}
		return server;
	}

	/**
	 * Convert an array of <code>MBeanParameterInfo into an array of
	 * <code>Class instances corresponding to the parameters.
	 * @param paramInfo the JMX parameter info
	 * @return the parameter types as classes
	 * @throws ClassNotFoundException if a parameter type could not be resolved
	 */
	public static Class[] parameterInfoToTypes(MBeanParameterInfo[] paramInfo) throws ClassNotFoundException {
		return parameterInfoToTypes(paramInfo, ClassUtils.getDefaultClassLoader());
	}

	/**
	 * Convert an array of <code>MBeanParameterInfo into an array of
	 * <code>Class instances corresponding to the parameters.
	 * @param paramInfo the JMX parameter info
	 * @param classLoader the ClassLoader to use for loading parameter types
	 * @return the parameter types as classes
	 * @throws ClassNotFoundException if a parameter type could not be resolved
	 */
	public static Class[] parameterInfoToTypes(MBeanParameterInfo[] paramInfo, ClassLoader classLoader)
			throws ClassNotFoundException {

		Class[] types = null;
		if (paramInfo != null && paramInfo.length > 0) {
			types = new Class[paramInfo.length];
			for (int x = 0; x < paramInfo.length; x++) {
				types[x] = ClassUtils.forName(paramInfo[x].getType(), classLoader);
			}
		}
		return types;
	}

	/**
	 * Create a <code>String[] representing the argument signature of a
	 * method. Each element in the array is the fully qualified class name
	 * of the corresponding argument in the methods signature.
	 * @param method the method to build an argument signature for
	 * @return the signature as array of argument types
	 */
	public static String[] getMethodSignature(Method method) {
		Class[] types = method.getParameterTypes();
		String[] signature = new String[types.length];
		for (int x = 0; x < types.length; x++) {
			signature[x] = types[x].getName();
		}
		return signature;
	}

	/**
	 * Return the JMX attribute name to use for the given JavaBeans property.
	 * <p>When using strict casing, a JavaBean property with a getter method
	 * such as <code>getFoo() translates to an attribute called
	 * <code>Foo. With strict casing disabled, getFoo()
	 * would translate to just <code>foo.
	 * @param property the JavaBeans property descriptor
	 * @param useStrictCasing whether to use strict casing
	 * @return the JMX attribute name to use
	 */
	public static String getAttributeName(PropertyDescriptor property, boolean useStrictCasing) {
		if (useStrictCasing) {
			return StringUtils.capitalize(property.getName());
		}
		else {
			return property.getName();
		}
	}

	/**
	 * Append an additional key/value pair to an existing {@link ObjectName} with the key being
	 * the static value <code>identity and the value being the identity hash code of the
	 * managed resource being exposed on the supplied {@link ObjectName}. This can be used to
	 * provide a unique {@link ObjectName} for each distinct instance of a particular bean or
	 * class. Useful when generating {@link ObjectName ObjectNames} at runtime for a set of
	 * managed resources based on the template value supplied by a
	 * {@link org.springframework.jmx.export.naming.ObjectNamingStrategy}.
	 * @param objectName the original JMX ObjectName
	 * @param managedResource the MBean instance
	 * @return an ObjectName with the MBean identity added
	 * @throws MalformedObjectNameException in case of an invalid object name specification
	 * @see org.springframework.util.ObjectUtils#getIdentityHexString(Object)
	 */
	public static ObjectName appendIdentityToObjectName(ObjectName objectName, Object managedResource)
			throws MalformedObjectNameException {

		Hashtable keyProperties = objectName.getKeyPropertyList();
		keyProperties.put(IDENTITY_OBJECT_NAME_KEY, ObjectUtils.getIdentityHexString(managedResource));
		return ObjectNameManager.getInstance(objectName.getDomain(), keyProperties);
	}

	/**
	 * Return the class or interface to expose for the given bean.
	 * This is the class that will be searched for attributes and operations
	 * (for example, checked for annotations).
	 * <p>This implementation returns the superclass for a CGLIB proxy and
	 * the class of the given bean else (for a JDK proxy or a plain bean class).
	 * @param managedBean the bean instance (might be an AOP proxy)
	 * @return the bean class to expose
	 * @see org.springframework.util.ClassUtils#getUserClass(Object)
	 */
	public static Class getClassToExpose(Object managedBean) {
		return ClassUtils.getUserClass(managedBean);
	}

	/**
	 * Return the class or interface to expose for the given bean class.
	 * This is the class that will be searched for attributes and operations
	 * (for example, checked for annotations).
	 * <p>This implementation returns the superclass for a CGLIB proxy and
	 * the class of the given bean else (for a JDK proxy or a plain bean class).
	 * @param beanClass the bean class (might be an AOP proxy class)
	 * @return the bean class to expose
	 * @see org.springframework.util.ClassUtils#getUserClass(Class)
	 */
	public static Class getClassToExpose(Class beanClass) {
		return ClassUtils.getUserClass(beanClass);
	}

	/**
	 * Determine whether the given bean class qualifies as an MBean as-is.
	 * <p>This implementation checks for {@link javax.management.DynamicMBean}
	 * classes as well as classes with corresponding "*MBean" interface
	 * (Standard MBeans) or corresponding "*MXBean" interface (Java 6 MXBeans).
	 * @param beanClass the bean class to analyze
	 * @return whether the class qualifies as an MBean
	 * @see org.springframework.jmx.export.MBeanExporter#isMBean(Class)
	 */
	public static boolean isMBean(Class beanClass) {
		return (beanClass != null &&
				(DynamicMBean.class.isAssignableFrom(beanClass) ||
						(getMBeanInterface(beanClass) != null || getMXBeanInterface(beanClass) != null)));
	}

	/**
	 * Return the Standard MBean interface for the given class, if any
	 * (that is, an interface whose name matches the class name of the
	 * given class but with suffix "MBean").
	 * @param clazz the class to check
	 * @return the Standard MBean interface for the given class
	 */
	public static Class getMBeanInterface(Class clazz) {
		if (clazz.getSuperclass() == null) {
			return null;
		}
		Class[] implementedInterfaces = clazz.getInterfaces();
		String mbeanInterfaceName = clazz.getName() + MBEAN_SUFFIX;
		for (int x = 0; x < implementedInterfaces.length; x++) {
			Class iface = implementedInterfaces[x];
			if (iface.getName().equals(mbeanInterfaceName)) {
				return iface;
			}
		}
		return getMBeanInterface(clazz.getSuperclass());
	}

	/**
	 * Return the Java 6 MXBean interface exists for the given class, if any
	 * (that is, an interface whose name ends with "MXBean" and/or
	 * carries an appropriate MXBean annotation).
	 * @param clazz the class to check
	 * @return whether there is an MXBean interface for the given class
	 */
	public static Class getMXBeanInterface(Class clazz) {
		if (clazz.getSuperclass() == null) {
			return null;
		}
		Class[] implementedInterfaces = clazz.getInterfaces();
		for (int x = 0; x < implementedInterfaces.length; x++) {
			Class iface = implementedInterfaces[x];
			boolean isMxBean = iface.getName().endsWith(MXBEAN_SUFFIX);
			if (mxBeanAnnotationAvailable) {
				Boolean checkResult = MXBeanChecker.hasMXBeanAnnotation(iface);
				if (checkResult != null) {
					isMxBean = checkResult.booleanValue();
				}
			}
			if (isMxBean) {
				return iface;
			}
		}
		return getMXBeanInterface(clazz.getSuperclass());
	}


	/**
	 * Inner class to avoid a Java 6 dependency.
	 */
	private static class MXBeanChecker {

		public static Boolean hasMXBeanAnnotation(Class iface) {
			MXBean mxBean = (MXBean) iface.getAnnotation(MXBean.class);
			if (mxBean != null) {
				return Boolean.valueOf(mxBean.value());
			}
			else {
				return null;
			}
		}
	}

}

Other Spring Framework examples (source code examples)

Here is a short list of links related to this Spring Framework JmxUtils.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.