JMX.java 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. /* JMX.java -- Static methods pertaining to the management API.
  2. Copyright (C) 2007 Free Software Foundation, Inc.
  3. This file is part of GNU Classpath.
  4. GNU Classpath is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2, or (at your option)
  7. any later version.
  8. GNU Classpath is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GNU Classpath; see the file COPYING. If not, write to the
  14. Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  15. 02110-1301 USA.
  16. Linking this library statically or dynamically with other modules is
  17. making a combined work based on this library. Thus, the terms and
  18. conditions of the GNU General Public License cover the whole
  19. combination.
  20. As a special exception, the copyright holders of this library give you
  21. permission to link this library with independent modules to produce an
  22. executable, regardless of the license terms of these independent
  23. modules, and to copy and distribute the resulting executable under
  24. terms of your choice, provided that you also meet, for each linked
  25. independent module, the terms and conditions of the license of that
  26. module. An independent module is a module which is not derived from
  27. or based on this library. If you modify this library, you may extend
  28. this exception to your version of the library, but you are not
  29. obligated to do so. If you do not wish to do so, delete this
  30. exception statement from your version. */
  31. package javax.management;
  32. import java.lang.reflect.Proxy;
  33. /**
  34. * Common static methods pertaining to the management
  35. * API. There are no instances of this class.
  36. *
  37. * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
  38. * @since 1.6
  39. */
  40. public class JMX
  41. {
  42. /**
  43. * The name of the defaultValue field.
  44. */
  45. public static final String DEFAULT_VALUE_FIELD = "defaultValue";
  46. /**
  47. * The name of the immutableInfo field.
  48. */
  49. public static final String IMMUTABLE_INFO_FIELD = "immutableInfo";
  50. /**
  51. * The name of the interfaceClassName field.
  52. */
  53. public static final String INTERFACE_CLASS_NAME_FIELD = "interfaceClassName";
  54. /**
  55. * The name of the legalValues field.
  56. */
  57. public static final String LEGAL_VALUES_FIELD = "legalValues";
  58. /**
  59. * The name of the maxValue field.
  60. */
  61. public static final String MAX_VALUE_FIELD = "maxValue";
  62. /**
  63. * The name of the minValue field.
  64. */
  65. public static final String MIN_VALUE_FIELD = "minValue";
  66. /**
  67. * The name of the mxbean field.
  68. */
  69. public static final String MXBEAN_FIELD = "mxbean";
  70. /**
  71. * The name of the openType field.
  72. */
  73. public static final String OPEN_TYPE_FIELD = "openType";
  74. /**
  75. * The name of the originalType field.
  76. */
  77. public static final String ORIGINAL_TYPE_FIELD = "originalType";
  78. /**
  79. * Prevent instance creation.
  80. */
  81. private JMX()
  82. {
  83. }
  84. /**
  85. * <p>
  86. * Returns true if the given class represents an {@link MXBean}
  87. * interface. An interface is an {@link MXBean interface} if:
  88. * </p>
  89. * <ul>
  90. * <li>It is annotated with {@code @MXBean} or
  91. * {@code @MXBean(true)}</li>.
  92. * <li>Its name ends in {@code "MXBean"} and it does not
  93. * have an {@link MXBean} annotation.</li>
  94. * </ul>
  95. *
  96. * @param iface the interface class that is to be checked
  97. * for {@link MXBean} status.
  98. * @return true if the interface represents an {@link MXBean}.
  99. * @throws NullPointerException if {@code iface} is {@code null}.
  100. */
  101. public static boolean isMXBeanInterface(Class<?> iface)
  102. {
  103. MXBean annotation = iface.getAnnotation(MXBean.class);
  104. if (annotation != null)
  105. return annotation.value();
  106. return iface.getName().endsWith("MXBean");
  107. }
  108. /**
  109. * <p>
  110. * Returns a proxy for a standard management bean, using
  111. * the specified connection to access the named implementation.
  112. * To create a proxy for the bean, {@code SomethingMBean}, a call to
  113. * {@code JMX.newMBeanProxy(server, name, SomethingMBean.class)}
  114. * is made, where {@code server} is a local or remote management
  115. * server, and {@code name} is the registered {@link ObjectName}
  116. * of the implementation of {@code SomethingMBean} to use.
  117. * </p>
  118. * <p>
  119. * The proxy redirects calls to the methods of the interface,
  120. * {@link SomethingMBean}, to the appropriate methods of the
  121. * management server. If {@link SomethingMBean} is specified
  122. * as follows:
  123. * </p>
  124. * <pre>
  125. * public interface SomethingMBean
  126. * {
  127. * String getName();
  128. * void setName(String name);
  129. * void doStuff();
  130. * }
  131. * </pre>
  132. * <p>
  133. * The proxy created above will provide these three methods
  134. * using an instance of {@link MBeanServerInvocationHandler}.
  135. * The two methods, {@code getName} and {@code setName} define
  136. * an attribute, {@code Name}, so a call to {@code getName()}
  137. * will return the value of {@code server.getAttribute(name,
  138. * "Name")}, while {@code setName(newName)} will result in a
  139. * call to {@code server.setAttribute(name, new Attribute("Name",
  140. * newName))}. Finally, {@code doStuff()}, as an operation,
  141. * will cause the proxy to call {@link MBeanServer#invoke(ObjectName,
  142. * String, Object[], String[])} as
  143. * {@code server.invoke(name, "doStuff", null, null)}.
  144. * </p>
  145. * <p>
  146. * Calling this method is equivalent to calling
  147. * {@link #newMBeanProxy(MBeanServerConnection, ObjectName, Class,
  148. * boolean)}.
  149. * </p>
  150. *
  151. * @param conn the server connection over which to forward calls to
  152. * the bean.
  153. * @param name the registered name of the bean to use to implement
  154. * the given interface.
  155. * @param iface the interface to provide a proxy for.
  156. * @return a proxy implementing the specified interface using calls
  157. * to the methods of the bean registered with the supplied
  158. * server using the given name.
  159. * @see #newMBeanProxy(MBeanServerConnection, ObjectName, Class,
  160. * boolean)
  161. */
  162. public static <T> T newMBeanProxy(MBeanServerConnection conn,
  163. ObjectName name, Class<T> iface)
  164. {
  165. return newMBeanProxy(conn, name, iface, false);
  166. }
  167. /**
  168. * Returns a proxy for a standard management bean, using
  169. * the specified connection to access the named implementation,
  170. * as with {@link #newMBeanProxy(MBeanServerConnection, ObjectName,
  171. * Class)}. In addition, the proxy returned by this method will
  172. * also implement {@link NotificationEmitter} if {@code bcast} is
  173. * true, under the assumption that the implementation referenced by
  174. * {@code name} implements this interface. Calls to the methods of
  175. * {@link NotificationEmitter} will be forwarded to the bean
  176. * implementation via the appropriate server methods.
  177. *
  178. * @param conn the server connection over which to forward calls to
  179. * the bean.
  180. * @param name the registered name of the bean to use to implement
  181. * the given interface.
  182. * @param iface the interface to provide a proxy for.
  183. * @param bcast true if the proxy should implement
  184. * {@link NotificationEmitter}.
  185. * @return a proxy implementing the specified interface using calls
  186. * to the methods of the bean registered with the supplied
  187. * server using the given name.
  188. * @see #newMBeanProxy(MBeanServerConnection, ObjectName, Class)
  189. */
  190. public static <T> T newMBeanProxy(MBeanServerConnection conn,
  191. ObjectName name, Class<T> iface,
  192. boolean bcast)
  193. {
  194. return MBeanServerInvocationHandler.newProxyInstance(conn, name,
  195. iface, bcast);
  196. }
  197. /**
  198. * <p>
  199. * Returns a proxy for a {@link MXBean}, using the specified
  200. * connection to access the named implementation.
  201. * To create a proxy for the bean, {@code SomethingMXBean}, a call to
  202. * {@code JMX.newMXBeanProxy(server, name, SomethingMXBean.class)}
  203. * is made, where {@code server} is a local or remote management
  204. * server, and {@code name} is the registered {@link ObjectName}
  205. * of the implementation of {@code SomethingMBean} to use.
  206. * </p>
  207. * <p>
  208. * The proxy redirects calls to the methods of the interface,
  209. * {@link SomethingMXBean}, to the appropriate methods of the
  210. * management server with appropriate conversion between
  211. * Java and open types, according to the MXBean rules. If
  212. * {@link SomethingMXBean} is specified as follows:
  213. * </p>
  214. * <pre>
  215. * public interface SomethingMXBean
  216. * {
  217. * String getName();
  218. * void setName(String name);
  219. * List<Double> getStatistics();
  220. * void setStatistics(List<Double> statistics);
  221. * List<Double> getNamedStatistics(String, Map<String,Integer>);
  222. * }
  223. * </pre>
  224. * <p>
  225. * The proxy created above will provide these five methods
  226. * using an instance of {@link MBeanServerInvocationHandler}.
  227. * The two methods, {@code getName} and {@code setName} define
  228. * an attribute, {@code Name}, so a call to {@code getName()}
  229. * will return the value of {@code server.getAttribute(name,
  230. * "Name")}, while {@code setName(newName)} will result in a
  231. * call to {@code server.setAttribute(name, new Attribute("Name",
  232. * newName))}. As this uses a simple type, {@link String}, no
  233. * conversion is necessary.
  234. * </p>
  235. * <p>
  236. * The two methods, {@code getStatistics} and {@code setStatistics}
  237. * similarly define another attribute, {@code Statistics}. Calling
  238. * {@code getStatistics()} will cause a call to the server to be
  239. * made as before, {@code server.getAttribute(name, "Statistics")}.
  240. * However, the type of the return value from this call will be
  241. * an array of {@link Double} objects, as per the {@link MXBean}
  242. * rules. The proxy converts this back in to a {@link java.util.List}
  243. * of {@link Double} objects before returning it.
  244. * </p>
  245. * <p>
  246. * The same process is applied in reverse for
  247. * {@code setStatistics(newStats)}. The list is converted into
  248. * an appropriate array before the call to
  249. * {@link MBeanServerConnection#setAttribute(ObjectName, Attribute)}
  250. * is made. Finally, a call to {@code getNamedStatistics} will require
  251. * both a Java to open type conversion on the arguments, and then
  252. * an open type to Java conversion of the return value. Thus, a proxy
  253. * enables an {@link MXBean} to be used in cases where the appropriate
  254. * Java types are available and the user wishes to access the bean
  255. * using the types directly defined in its interface, just as with
  256. * standard management beans.
  257. * </p>
  258. * <p>
  259. * Calling this method is equivalent to calling
  260. * {@link #newMXBeanProxy(MBeanServerConnection, ObjectName, Class,
  261. * boolean)}.
  262. * </p>
  263. *
  264. * @param conn the server connection over which to forward calls to
  265. * the bean.
  266. * @param name the registered name of the bean to use to implement
  267. * the given interface.
  268. * @param iface the interface to provide a proxy for.
  269. * @return a proxy implementing the specified interface using calls
  270. * to the methods of the bean registered with the supplied
  271. * server using the given name.
  272. * @see #newMXBeanProxy(MBeanServerConnection, ObjectName, Class,
  273. * boolean)
  274. */
  275. public static <T> T newMXBeanProxy(MBeanServerConnection conn,
  276. ObjectName name, Class<T> iface)
  277. {
  278. return newMXBeanProxy(conn, name, iface, false);
  279. }
  280. /**
  281. * Returns a proxy for a {@link MXBean}, using
  282. * the specified connection to access the named implementation,
  283. * as with {@link #newMXBeanProxy(MBeanServerConnection, ObjectName,
  284. * Class)}. In addition, the proxy returned by this method will
  285. * also implement {@link NotificationEmitter} if {@code bcast} is
  286. * true, under the assumption that the implementation referenced by
  287. * {@code name} implements this interface. Calls to the methods of
  288. * {@link NotificationEmitter} will be forwarded to the bean
  289. * implementation via the appropriate server methods.
  290. *
  291. * @param conn the server connection over which to forward calls to
  292. * the bean.
  293. * @param name the registered name of the bean to use to implement
  294. * the given interface.
  295. * @param iface the interface to provide a proxy for.
  296. * @param bcast true if the proxy should implement
  297. * {@link NotificationEmitter}.
  298. * @return a proxy implementing the specified interface using calls
  299. * to the methods of the bean registered with the supplied
  300. * server using the given name.
  301. * @see #newMXBeanProxy(MBeanServerConnection, ObjectName, Class)
  302. */
  303. // Suppress warnings as we know an instance of T will be returned.
  304. @SuppressWarnings("unchecked")
  305. public static <T> T newMXBeanProxy(MBeanServerConnection conn,
  306. ObjectName name, Class<T> iface,
  307. boolean bcast)
  308. {
  309. if (bcast)
  310. return (T) Proxy.newProxyInstance(iface.getClassLoader(),
  311. new Class[] { iface,
  312. NotificationEmitter.class },
  313. new MBeanServerInvocationHandler(conn,name,true));
  314. else
  315. return (T) Proxy.newProxyInstance(iface.getClassLoader(),
  316. new Class[] { iface },
  317. new MBeanServerInvocationHandler(conn,name,true));
  318. }
  319. }