KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > management > JMX


1 /*
2  * @(#)JMX.java 1.12 06/04/11
3  *
4  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package javax.management;
9
10 import com.sun.jmx.mbeanserver.Introspector;
11 import java.lang.reflect.InvocationHandler JavaDoc;
12 import java.lang.reflect.Proxy JavaDoc;
13
14 /**
15  * Static methods from the JMX API. There are no instances of this class.
16  *
17  * @since 1.6
18  */

19 public class JMX {
20     /* Code within this package can prove that by providing this instance of
21      * this class.
22      */

23     static final JMX JavaDoc proof = new JMX JavaDoc();
24
25     private JMX() {}
26
27     /**
28      * The name of the <a HREF="Descriptor.html#defaultValue">{@code
29      * defaultValue}</a> field.
30      */

31     public static final String JavaDoc DEFAULT_VALUE_FIELD = "defaultValue";
32
33     /**
34      * The name of the <a HREF="Descriptor.html#immutableInfo">{@code
35      * immutableInfo}</a> field.
36      */

37     public static final String JavaDoc IMMUTABLE_INFO_FIELD = "immutableInfo";
38
39     /**
40      * The name of the <a HREF="Descriptor.html#interfaceClassName">{@code
41      * interfaceClassName}</a> field.
42      */

43     public static final String JavaDoc INTERFACE_CLASS_NAME_FIELD = "interfaceClassName";
44
45     /**
46      * The name of the <a HREF="Descriptor.html#legalValues">{@code
47      * legalValues}</a> field.
48      */

49     public static final String JavaDoc LEGAL_VALUES_FIELD = "legalValues";
50
51     /**
52      * The name of the <a HREF="Descriptor.html#maxValue">{@code
53      * maxValue}</a> field.
54      */

55     public static final String JavaDoc MAX_VALUE_FIELD = "maxValue";
56     
57     /**
58      * The name of the <a HREF="Descriptor.html#minValue">{@code
59      * minValue}</a> field.
60      */

61     public static final String JavaDoc MIN_VALUE_FIELD = "minValue";
62     
63     /**
64      * The name of the <a HREF="Descriptor.html#mxbean">{@code
65      * mxbean}</a> field.
66      */

67     public static final String JavaDoc MXBEAN_FIELD = "mxbean";
68     
69     /**
70      * The name of the <a HREF="Descriptor.html#openType">{@code
71      * openType}</a> field.
72      */

73     public static final String JavaDoc OPEN_TYPE_FIELD = "openType";
74
75     /**
76      * The name of the <a HREF="Descriptor.html#originalType">{@code
77      * originalType}</a> field.
78      */

79     public static final String JavaDoc ORIGINAL_TYPE_FIELD = "originalType";
80
81     /**
82      * <p>Make a proxy for a Standard MBean in a local or remote
83      * MBean Server.</p>
84      *
85      * <p>If you have an MBean Server {@code mbs} containing an MBean
86      * with {@link ObjectName} {@code name}, and if the MBean's
87      * management interface is described by the Java interface
88      * {@code MyMBean}, you can construct a proxy for the MBean like
89      * this:</p>
90      *
91      * <pre>
92      * MyMBean proxy = JMX.newMBeanProxy(mbs, name, MyMBean.class);
93      * </pre>
94      *
95      * <p>Suppose, for example, {@code MyMBean} looks like this:</p>
96      *
97      * <pre>
98      * public interface MyMBean {
99      * public String getSomeAttribute();
100      * public void setSomeAttribute(String value);
101      * public void someOperation(String param1, int param2);
102      * }
103      * </pre>
104      *
105      * <p>Then you can execute:</p>
106      *
107      * <ul>
108      *
109      * <li>{@code proxy.getSomeAttribute()} which will result in a
110      * call to {@code mbs.}{@link MBeanServerConnection#getAttribute
111      * getAttribute}{@code (name, "SomeAttribute")}.
112      *
113      * <li>{@code proxy.setSomeAttribute("whatever")} which will result
114      * in a call to {@code mbs.}{@link MBeanServerConnection#setAttribute
115      * setAttribute}{@code (name, new Attribute("SomeAttribute", "whatever"))}.
116      *
117      * <li>{@code proxy.someOperation("param1", 2)} which will be
118      * translated into a call to {@code mbs.}{@link
119      * MBeanServerConnection#invoke invoke}{@code (name, "someOperation", <etc>)}.
120      *
121      * </ul>
122      *
123      * <p>The object returned by this method is a
124      * {@link Proxy} whose {@code InvocationHandler} is an
125      * {@link MBeanServerInvocationHandler}.</p>
126      *
127      * <p>This method is equivalent to {@link
128      * #newMBeanProxy(MBeanServerConnection, ObjectName, Class,
129      * boolean) newMBeanProxy(connection, objectName, interfaceClass,
130      * false)}.</p>
131      *
132      * @param connection the MBean server to forward to.
133      * @param objectName the name of the MBean within
134      * {@code connection} to forward to.
135      * @param interfaceClass the management interface that the MBean
136      * exports, which will also be implemented by the returned proxy.
137      *
138      * @param <T> allows the compiler to know that if the {@code
139      * interfaceClass} parameter is {@code MyMBean.class}, for
140      * example, then the return type is {@code MyMBean}.
141      *
142      * @return the new proxy instance.
143      */

144     public static <T> T newMBeanProxy(MBeanServerConnection JavaDoc connection,
145                       ObjectName JavaDoc objectName,
146                       Class JavaDoc<T> interfaceClass) {
147     return newMBeanProxy(connection, objectName, interfaceClass, false);
148     }
149
150     /**
151      * <p>Make a proxy for a Standard MBean in a local or remote MBean
152      * Server that may also support the methods of {@link
153      * NotificationEmitter}.</p>
154      *
155      * <p>This method behaves the same as {@link
156      * #newMBeanProxy(MBeanServerConnection, ObjectName, Class)}, but
157      * additionally, if {@code notificationBroadcaster} is {@code
158      * true}, then the MBean is assumed to be a {@link
159      * NotificationBroadcaster} or {@link NotificationEmitter} and the
160      * returned proxy will implement {@link NotificationEmitter} as
161      * well as {@code interfaceClass}. A call to {@link
162      * NotificationBroadcaster#addNotificationListener} on the proxy
163      * will result in a call to {@link
164      * MBeanServerConnection#addNotificationListener(ObjectName,
165      * NotificationListener, NotificationFilter, Object)}, and
166      * likewise for the other methods of {@link
167      * NotificationBroadcaster} and {@link NotificationEmitter}.</p>
168      *
169      * @param connection the MBean server to forward to.
170      * @param objectName the name of the MBean within
171      * {@code connection} to forward to.
172      * @param interfaceClass the management interface that the MBean
173      * exports, which will also be implemented by the returned proxy.
174      * @param notificationBroadcaster make the returned proxy
175      * implement {@link NotificationEmitter} by forwarding its methods
176      * via {@code connection}.
177      *
178      * @param <T> allows the compiler to know that if the {@code
179      * interfaceClass} parameter is {@code MyMBean.class}, for
180      * example, then the return type is {@code MyMBean}.
181      *
182      * @return the new proxy instance.
183      */

184     public static <T> T newMBeanProxy(MBeanServerConnection JavaDoc connection,
185                       ObjectName JavaDoc objectName,
186                       Class JavaDoc<T> interfaceClass,
187                       boolean notificationBroadcaster) {
188     return MBeanServerInvocationHandler.newProxyInstance(
189         connection,
190         objectName,
191         interfaceClass,
192         notificationBroadcaster);
193     }
194
195     /**
196      * <p>Make a proxy for an MXBean in a local or remote
197      * MBean Server.</p>
198      *
199      * <p>If you have an MBean Server {@code mbs} containing an
200      * MXBean with {@link ObjectName} {@code name}, and if the
201      * MXBean's management interface is described by the Java
202      * interface {@code MyMXBean}, you can construct a proxy for
203      * the MXBean like this:</p>
204      *
205      * <pre>
206      * MyMXBean proxy = JMX.newMXBeanProxy(mbs, name, MyMXBean.class);
207      * </pre>
208      *
209      * <p>Suppose, for example, {@code MyMXBean} looks like this:</p>
210      *
211      * <pre>
212      * public interface MyMXBean {
213      * public String getSimpleAttribute();
214      * public void setSimpleAttribute(String value);
215      * public {@link java.lang.management.MemoryUsage} getMappedAttribute();
216      * public void setMappedAttribute(MemoryUsage memoryUsage);
217      * public MemoryUsage someOperation(String param1, MemoryUsage param2);
218      * }
219      * </pre>
220      *
221      * <p>Then:</p>
222      *
223      * <ul>
224      *
225      * <li><p>{@code proxy.getSimpleAttribute()} will result in a
226      * call to {@code mbs.}{@link MBeanServerConnection#getAttribute
227      * getAttribute}{@code (name, "SimpleAttribute")}.</p>
228      *
229      * <li><p>{@code proxy.setSimpleAttribute("whatever")} will result
230      * in a call to {@code mbs.}{@link
231      * MBeanServerConnection#setAttribute setAttribute}<code>(name,
232      * new Attribute("SimpleAttribute", "whatever"))</code>.<p>
233      *
234      * <p>Because {@code String} is a <em>simple type</em>, in the
235      * sense of {@link javax.management.openmbean.SimpleType}, it
236      * is not changed in the context of an MXBean. The MXBean
237      * proxy behaves the same as a Standard MBean proxy (see
238      * {@link #newMBeanProxy(MBeanServerConnection, ObjectName,
239      * Class) newMBeanProxy}) for the attribute {@code
240      * SimpleAttribute}.</p>
241      *
242      * <li><p>{@code proxy.getMappedAttribute()} will result in a call
243      * to {@code mbs.getAttribute("MappedAttribute")}. The MXBean
244      * mapping rules mean that the actual type of the attribute {@code
245      * MappedAttribute} will be {@link
246      * javax.management.openmbean.CompositeData CompositeData} and
247      * that is what the {@code mbs.getAttribute} call will return.
248      * The proxy will then convert the {@code CompositeData} back into
249      * the expected type {@code MemoryUsage} using the MXBean mapping
250      * rules.</p>
251      *
252      * <li><p>Similarly, {@code proxy.setMappedAttribute(memoryUsage)}
253      * will convert the {@code MemoryUsage} argument into a {@code
254      * CompositeData} before calling {@code mbs.setAttribute}.</p>
255      *
256      * <li><p>{@code proxy.someOperation("whatever", memoryUsage)}
257      * will convert the {@code MemoryUsage} argument into a {@code
258      * CompositeData} and call {@code mbs.invoke}. The value returned
259      * by {@code mbs.invoke} will be also be a {@code CompositeData},
260      * and the proxy will convert this into the expected type {@code
261      * MemoryUsage} using the MXBean mapping rules.</p>
262      *
263      * </ul>
264      *
265      * <p>The object returned by this method is a
266      * {@link Proxy} whose {@code InvocationHandler} is an
267      * {@link MBeanServerInvocationHandler}.</p>
268      *
269      * <p>This method is equivalent to {@link
270      * #newMXBeanProxy(MBeanServerConnection, ObjectName, Class,
271      * boolean) newMXBeanProxy(connection, objectName, interfaceClass,
272      * false)}.</p>
273      *
274      * @param connection the MBean server to forward to.
275      * @param objectName the name of the MBean within
276      * {@code connection} to forward to.
277      * @param interfaceClass the MXBean interface,
278      * which will also be implemented by the returned proxy.
279      *
280      * @param <T> allows the compiler to know that if the {@code
281      * interfaceClass} parameter is {@code MyMXBean.class}, for
282      * example, then the return type is {@code MyMXBean}.
283      *
284      * @return the new proxy instance.
285      */

286     public static <T> T newMXBeanProxy(MBeanServerConnection JavaDoc connection,
287                        ObjectName JavaDoc objectName,
288                        Class JavaDoc<T> interfaceClass) {
289     return newMXBeanProxy(connection, objectName, interfaceClass, false);
290     }
291
292     /**
293      * <p>Make a proxy for an MXBean in a local or remote MBean
294      * Server that may also support the methods of {@link
295      * NotificationEmitter}.</p>
296      *
297      * <p>This method behaves the same as {@link
298      * #newMXBeanProxy(MBeanServerConnection, ObjectName, Class)}, but
299      * additionally, if {@code notificationBroadcaster} is {@code
300      * true}, then the MXBean is assumed to be a {@link
301      * NotificationBroadcaster} or {@link NotificationEmitter} and the
302      * returned proxy will implement {@link NotificationEmitter} as
303      * well as {@code interfaceClass}. A call to {@link
304      * NotificationBroadcaster#addNotificationListener} on the proxy
305      * will result in a call to {@link
306      * MBeanServerConnection#addNotificationListener(ObjectName,
307      * NotificationListener, NotificationFilter, Object)}, and
308      * likewise for the other methods of {@link
309      * NotificationBroadcaster} and {@link NotificationEmitter}.</p>
310      *
311      * @param connection the MBean server to forward to.
312      * @param objectName the name of the MBean within
313      * {@code connection} to forward to.
314      * @param interfaceClass the MXBean interface,
315      * which will also be implemented by the returned proxy.
316      * @param notificationBroadcaster make the returned proxy
317      * implement {@link NotificationEmitter} by forwarding its methods
318      * via {@code connection}.
319      *
320      * @param <T> allows the compiler to know that if the {@code
321      * interfaceClass} parameter is {@code MyMXBean.class}, for
322      * example, then the return type is {@code MyMXBean}.
323      *
324      * @return the new proxy instance.
325      */

326     public static <T> T newMXBeanProxy(MBeanServerConnection JavaDoc connection,
327                        ObjectName JavaDoc objectName,
328                        Class JavaDoc<T> interfaceClass,
329                        boolean notificationBroadcaster) {
330         // Check interface for MXBean compliance
331
//
332
try {
333             Introspector.testComplianceMXBeanInterface(interfaceClass);
334         } catch (NotCompliantMBeanException JavaDoc e) {
335             throw new IllegalArgumentException JavaDoc(e);
336         }
337     InvocationHandler JavaDoc handler = new MBeanServerInvocationHandler JavaDoc(
338         connection, objectName, true);
339     final Class JavaDoc[] interfaces;
340     if (notificationBroadcaster) {
341         interfaces =
342         new Class JavaDoc<?>[] {interfaceClass, NotificationEmitter JavaDoc.class};
343     } else
344         interfaces = new Class JavaDoc[] {interfaceClass};
345     Object JavaDoc proxy = Proxy.newProxyInstance(
346         interfaceClass.getClassLoader(),
347         interfaces,
348         handler);
349     return interfaceClass.cast(proxy);
350     }
351     
352     /**
353      * <p>Test whether an interface is an MXBean interface.
354      * An interface is an MXBean interface if it is annotated
355      * {@link MXBean &#64;MXBean} or {@code @MXBean(true)}
356      * or if it does not have an {@code @MXBean} annotation
357      * and its name ends with "{@code MXBean}".</p>
358      *
359      * @param interfaceClass The candidate interface.
360      *
361      * @return true if {@code interfaceClass} is an interface and
362      * meets the conditions described.
363      *
364      * @throws NullPointerException if {@code interfaceClass} is null.
365      */

366     public static boolean isMXBeanInterface(Class JavaDoc<?> interfaceClass) {
367         if (!interfaceClass.isInterface())
368             return false;
369         MXBean JavaDoc a = interfaceClass.getAnnotation(MXBean JavaDoc.class);
370         if (a != null)
371             return a.value();
372         return interfaceClass.getName().endsWith("MXBean");
373         // We don't bother excluding the case where the name is
374
// exactly the string "MXBean" since that would mean there
375
// was no package name, which is pretty unlikely in practice.
376
}
377 }
378
Popular Tags