001 /*
002 * $Id: MBeanHelper.java,v 1.15 2014/05/18 12:25:15 oboehm Exp $
003 *
004 * Copyright (c) 2008 by Oliver Boehm
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License");
007 * you may not use this file except in compliance with the License.
008 * You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express orimplied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 *
018 * (c)reated 19.02.2009 by oliver (ob@oasd.de)
019 */
020 package patterntesting.runtime.jmx;
021
022 import java.lang.management.ManagementFactory;
023
024 import javax.management.*;
025 import javax.management.openmbean.*;
026
027 import org.apache.commons.lang.StringUtils;
028 import org.slf4j.*;
029
030 /**
031 * This class simplifies the use of JMX and MBeans a little bit.
032 *
033 * @author <a href="boehm@javatux.de">oliver</a>
034 * @since 19.02.2009
035 * @version $Revision: 1.15 $
036 */
037 public class MBeanHelper {
038
039 private static final Logger log = LoggerFactory.getLogger(MBeanHelper.class);
040 private static MBeanServer server = ManagementFactory.getPlatformMBeanServer();
041
042 static {
043 registerMBean("patterntesting.runtime:name=Info", new Info());
044 }
045
046 /** Utility class - no need to instantiate it */
047 private MBeanHelper() {}
048
049 /**
050 * Gets an MBean name for the given object.
051 *
052 * @param mbean the mbean
053 *
054 * @return the name of the MBean
055 */
056 public static String getMBeanName(final Object mbean) {
057 return getMBeanName(mbean.getClass());
058 }
059
060 /**
061 * Gets an MBean name for the given object.
062 *
063 * @param mbean the mbean
064 * @param level the level
065 * @return the name of the MBean
066 * @since 1.4.3
067 */
068 public static String getMBeanName(final Object mbean, final int level) {
069 return getMBeanName(mbean.getClass(), level);
070 }
071
072 /**
073 * Converts the class name into a MBean name. For a hierachical structure of
074 * the registered MBeans take a look at <a href=
075 * "http://www.oracle.com/technetwork/java/javase/tech/best-practices-jsp-136021.html"
076 * >Java Management Extensions (JMX) - Best Practices</a>.
077 * <p>
078 * The default level for an MBean is since 1.4.3 now set to "2" (see
079 * {@link #getMBeanName(Object, int)}. This means you will find all MBeans
080 * from PatternTesting Runtime under the node "patterntesting.runtime"
081 * if you open your JMX console (e.g. the 'jconsole' from the JDK).
082 * </p>
083 *
084 * @param cl e.g. my.good.bye.World
085 * @return a valid MBean name e.g. "my:type=good,good=bye,name=World"
086 * @see #getMBeanName(Class, int)
087 */
088 public static String getMBeanName(final Class<?> cl) {
089 return getMBeanName(cl, 2);
090 }
091
092 /**
093 * Converts the class name into a MBean name. For a hierachical structure of
094 * the registered MBeans take a look at <a href=
095 * "http://www.oracle.com/technetwork/java/javase/tech/best-practices-jsp-136021.html"
096 * >Java Management Extensions (JMX) - Best Practices</a>.
097 * <p>
098 * With the 2nd parameter (level) you can control the root element. If you
099 * set it i.e. to 2 the result in the jconsole would look like:
100 * <pre>
101 * my.good
102 * bye
103 * World
104 * </pre>
105 * if the given class is "my.good.by.World".
106 * </p>
107 *
108 * @param cl e.g. my.good.bye.World
109 * @param level the level, e.g.
110 * @return a valid MBean name e.g. "my.good:type=bye,name=World"
111 * @since 1.4.3
112 */
113 public static String getMBeanName(final Class<?> cl, final int level) {
114 assert level > 0 : "level must be 1 or greater";
115 String packageName = cl.getPackage().getName();
116 String[] names = StringUtils.split(packageName, ".");
117 int n = (level >= names.length) ? names.length - 1 : level;
118 String domain = names[0];
119 for (int i = 1; i < n; i++) {
120 domain += "." + names[i];
121 }
122 String type = names[n];
123 StringBuffer mbeanName = new StringBuffer(domain + ":type=" + type);
124 for (int i = n+1; i < names.length; i++) {
125 mbeanName.append("," + names[i-1] + "=" + names[i]);
126 }
127 return mbeanName + ",name=" + cl.getSimpleName();
128 }
129
130 /**
131 * Register the given object as MBean.
132 *
133 * @param mbean the mbean
134 *
135 * @throws JMException if registration fails
136 */
137 public static void registerMBean(final Object mbean) throws JMException {
138 String mbeanName = getMBeanName(mbean);
139 registerMBean(mbeanName, mbean);
140 }
141
142 /**
143 * Register the given object as MBean.
144 *
145 * @param mbeanName the mbean name
146 * @param mbean the mbean
147 */
148 public static synchronized void registerMBean(final String mbeanName, final Object mbean) {
149 try {
150 ObjectName name = new ObjectName(mbeanName);
151 registerMBean(name, mbean);
152 } catch (MalformedObjectNameException e) {
153 log.info("can't register <" + mbean + "> as MBean", e);
154 }
155 }
156
157 /**
158 * Register m bean.
159 *
160 * @param name the name
161 * @param mbean the mbean
162 */
163 public static synchronized void registerMBean(final ObjectName name, final Object mbean) {
164 try {
165 log.trace("registering " + name + "...");
166 server.registerMBean(mbean, name);
167 log.debug(name + " successful registered as MBean");
168 } catch (Exception e) {
169 log.info("can't register <" + mbean + "> as MBean", e);
170 }
171 }
172
173 /**
174 * Unregister m bean.
175 *
176 * @param mbeanName the mbean name
177 */
178 public static synchronized void unregisterMBean(final String mbeanName) {
179 try {
180 ObjectName name = new ObjectName(mbeanName);
181 server.unregisterMBean(name);
182 log.debug("MBean " + name + " successful unregistered");
183 } catch (Exception e) {
184 log.info("can't unregister " + mbeanName, e);
185 }
186 }
187
188 /**
189 * Checks if is registered.
190 *
191 * @param mbeanName the mbean name
192 *
193 * @return true, if is registered
194 */
195 public static boolean isRegistered(final String mbeanName) {
196 try {
197 ObjectName name = new ObjectName(mbeanName);
198 ObjectInstance mbean = server.getObjectInstance(name);
199 return (mbean != null);
200 } catch (Exception e) {
201 log.trace(mbeanName + " not found (" + e + ")");
202 return false;
203 }
204 }
205
206 /**
207 * Checks if is registered.
208 *
209 * @param obj the obj
210 *
211 * @return true, if is registered
212 */
213 public static boolean isRegistered(final Object obj) {
214 String mbeanName = getMBeanName(obj.getClass());
215 return isRegistered(mbeanName);
216 }
217
218 /**
219 * Gets the object instance.
220 *
221 * @param name the name
222 * @return the object instance
223 * @throws InstanceNotFoundException the instance not found exception
224 */
225 public static ObjectInstance getObjectInstance(final String name) throws InstanceNotFoundException {
226 try {
227 ObjectName mbeanName = new ObjectName(name);
228 return getObjectInstance(mbeanName);
229 } catch (MalformedObjectNameException e) {
230 throw new IllegalArgumentException(name, e);
231 }
232 }
233
234 /**
235 * Gets the object instance.
236 *
237 * @param mbeanName the mbean name
238 * @return the object instance
239 * @throws InstanceNotFoundException the instance not found exception
240 */
241 public static ObjectInstance getObjectInstance(final ObjectName mbeanName)
242 throws InstanceNotFoundException {
243 return server.getObjectInstance(mbeanName);
244 }
245
246 /**
247 * Gets the attribute.
248 *
249 * @param mbeanName the mbean name
250 * @param attributeName the attribute name
251 * @return the attribute
252 * @throws InstanceNotFoundException the instance not found exception
253 * @throws JMException the jM exception
254 */
255 public static Object getAttribute(final String mbeanName, final String attributeName)
256 throws InstanceNotFoundException, JMException {
257 try {
258 ObjectName mbean = new ObjectName(mbeanName);
259 return getAttribute(mbean, attributeName);
260 } catch (MalformedObjectNameException e) {
261 throw new IllegalArgumentException(mbeanName, e);
262 }
263 }
264
265 /**
266 * Gets the attribute.
267 *
268 * @param mbean the mbean
269 * @param attributeName the attribute name
270 * @return the attribute
271 * @throws InstanceNotFoundException the instance not found exception
272 * @throws JMException the jM exception
273 */
274 public static Object getAttribute(final ObjectName mbean, final String attributeName)
275 throws InstanceNotFoundException, JMException {
276 try {
277 return server.getAttribute(mbean, attributeName);
278 } catch (AttributeNotFoundException e) {
279 throw new IllegalArgumentException(attributeName, e);
280 }
281 }
282
283 /**
284 * Creates a {@link TabularDataSupport} object.
285 *
286 * @param rowType the row type
287 * @param itemNames the item names
288 * @return the tabular data support
289 * @throws OpenDataException the open data exception
290 */
291 public static TabularDataSupport createTabularDataSupport(final CompositeType rowType, final String[] itemNames)
292 throws OpenDataException {
293 TabularType tabularType = new TabularType("propertyTabularType",
294 "properties tabular", rowType, itemNames);
295 TabularDataSupport data = new TabularDataSupport(tabularType);
296 return data;
297 }
298
299 }