diff --git a/.hgtags-top-repo b/.hgtags-top-repo index cec8ccbe986..ce58a609d1b 100644 --- a/.hgtags-top-repo +++ b/.hgtags-top-repo @@ -5,3 +5,4 @@ cbc8ad9dd0e085a607427ea35411990982f19a36 jdk7-b25 56652b46f328937f6b9b5130f1e4cd80f48868ef jdk7-b28 31e08f70e88d77c2053f91c21b49a04296bdc59a jdk7-b29 2dab2f712e1832c92acfa63ec0337048b9422c20 jdk7-b30 +3300a35a0bd56d695b92fe0b34f03ebbfc939064 jdk7-b31 diff --git a/README-builds.html b/README-builds.html index a2cf768e122..37998f9c1f6 100644 --- a/README-builds.html +++ b/README-builds.html @@ -5,15 +5,12 @@
-- - - + | ||||||||
make.exe | Devel | -make: The GNU version of the 'make' utility | +make: The GNU version of the 'make' utility + NOTE: See the GNU make section |
|||||
m4.exe | @@ -1050,7 +1108,7 @@cpio: A program to manage archives of files | |||||||
awk.exe | +gawk.exe | Utils | awk: Pattern-directed scanning and processing language | |||||
zip.exe | -Utils | +Archive | zip: Package and compress (archive) files | |||||
unzip.exe | -Utils | +Archive | unzip: Extract compressed files in a ZIP archive | |||||
free.exe | -Utils | +Procps | free: Display amount of free and used memory in the system | |||||
descriptionResource BundleBaseName | String | Any | + *||||||
descriptionResource BundleBaseName | String | Any | * *The base name for the {@link ResourceBundle} in which the key given in * the {@code descriptionResourceKey} field can be found, for example - * {@code "com.example.myapp.MBeanResources"}. The meaning of this - * field is defined by this specification but the field is not set or - * used by the JMX API itself. | + * {@code "com.example.myapp.MBeanResources"}. * - *|||||
descriptionResourceKey | String | Any | + *||||||
descriptionResourceKey | String | Any | * *A resource key for the description of this element. In * conjunction with the {@code descriptionResourceBundleBaseName}, - * this can be used to find a localized version of the description. - * The meaning of this field is defined by this specification but the - * field is not set or used by the JMX API itself. | + * this can be used to find a localized version of the description. * *|||||
enabled | String | *MBeanAttributeInfo MBeanNotificationInfo MBeanOperationInfo |
@@ -216,6 +215,14 @@ import javax.management.openmbean.OpenType;
* StandardMBean} class will have this field in its MBeanInfo
* Descriptor.
*
+ * ||||||
mxbeanMappingFactoryClass + * | String | + *MBeanInfo | + * + *The name of the {@link MXBeanMappingFactory} class that was used for this + * MXBean, if it was not the {@linkplain MXBeanMappingFactory#DEFAULT default} + * one. | + * *|||||
openType | {@link OpenType} | *MBeanAttributeInfo MBeanOperationInfo MBeanParameterInfo |
*
diff --git a/jdk/src/share/classes/javax/management/DescriptorFields.java b/jdk/src/share/classes/javax/management/DescriptorFields.java
new file mode 100644
index 00000000000..95a4b3a6df1
--- /dev/null
+++ b/jdk/src/share/classes/javax/management/DescriptorFields.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package javax.management;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ *
Name | Value |
---|---|
units | "bytes" |
since | "1.5" |
The {@code @DescriptorFields} annotation can be applied to:
+ * + *Other uses of the annotation will either fail to compile or be + * ignored.
+ * + *Interface annotations are checked only on the exact interface + * that defines the management interface of a Standard MBean or an + * MXBean, not on its parent interfaces. Method annotations are + * checked only in the most specific interface in which the method + * appears; in other words, if a child interface overrides a method + * from a parent interface, only {@code @DescriptorFields} annotations in + * the method in the child interface are considered. + * + *
The Descriptor fields contributed in this way must be consistent + * with each other and with any fields contributed by {@link + * DescriptorKey @DescriptorKey} annotations. That is, two + * different annotations, or two members of the same annotation, must + * not define a different value for the same Descriptor field. Fields + * from annotations on a getter method must also be consistent with + * fields from annotations on the corresponding setter method.
+ * + *The Descriptor resulting from these annotations will be merged + * with any Descriptor fields provided by the implementation, such as + * the {@code + * immutableInfo} field for an MBean. The fields from the annotations + * must be consistent with these fields provided by the implementation.
+ * + *The {@link DescriptorKey @DescriptorKey} annotation provides
+ * another way to use annotations to define Descriptor fields.
+ * @DescriptorKey
requires more work but is also more
+ * robust, because there is less risk of mistakes such as misspelling
+ * the name of the field or giving an invalid value.
+ * @DescriptorFields
is more convenient but includes
+ * those risks. @DescriptorFields
is more
+ * appropriate for occasional use, but for a Descriptor field that you
+ * add in many places, you should consider a purpose-built annotation
+ * using @DescriptorKey
.
+ *
+ * @since 1.7
+ */
+@Documented
+@Inherited // for @MBean and @MXBean classes
+@Target({ElementType.CONSTRUCTOR, ElementType.METHOD,
+ ElementType.PARAMETER, ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface DescriptorFields {
+ /**
+ *
The descriptor fields. Each element of the string looks like + * {@code "name=value"}.
+ */ + public String[] value(); +} diff --git a/jdk/src/share/classes/javax/management/DescriptorKey.java b/jdk/src/share/classes/javax/management/DescriptorKey.java index ad12612db18..9f919490512 100644 --- a/jdk/src/share/classes/javax/management/DescriptorKey.java +++ b/jdk/src/share/classes/javax/management/DescriptorKey.java @@ -33,6 +33,11 @@ import java.lang.annotation.*; * an MBean, or for an attribute, operation, or constructor in an * MBean, or for a parameter of an operation or constructor. * + *(The {@link DescriptorFields @DescriptorFields} annotation + * provides another way to add fields to a {@code Descriptor}. See + * the documentation for that annotation for a comparison of the + * two possibilities.)
+ * *Consider this annotation for example:
* *@@ -57,7 +62,7 @@ import java.lang.annotation.*; ** * @see javax.management.JMX.ProxyOptions + * @see javax.management.StandardMBean.Options */ public static class MBeanOptions implements Serializable, Cloneable { private static final long serialVersionUID = -6380842449318177843L; @@ -739,4 +741,28 @@ public class JMX { // exactly the string "MXBean" since that would mean there // was no package name, which is pretty unlikely in practice. } + + /** + *When a Standard MBean is made from the {@code CacheControlMBean}, * the usual rules mean that it will have an attribute called * {@code CacheSize} of type {@code long}. The {@code @Units} - * attribute, given the above definition, will ensure that the + * annotation, given the above definition, will ensure that the * {@link MBeanAttributeInfo} for this attribute will have a * {@code Descriptor} that has a field called {@code units} with * corresponding value {@code bytes}.
@@ -125,12 +130,13 @@ import java.lang.annotation.*; * the method in the child interface are considered. * *The Descriptor fields contributed in this way by different - * annotations on the same program element must be consistent. That - * is, two different annotations, or two members of the same - * annotation, must not define a different value for the same - * Descriptor field. Fields from annotations on a getter method must - * also be consistent with fields from annotations on the - * corresponding setter method.
+ * annotations on the same program element must be consistent with + * each other and with any fields contributed by a {@link + * DescriptorFields @DescriptorFields} annotation. That is, two + * different annotations, or two members of the same annotation, must + * not define a different value for the same Descriptor field. Fields + * from annotations on a getter method must also be consistent with + * fields from annotations on the corresponding setter method. * *The Descriptor resulting from these annotations will be merged * with any Descriptor fields provided by the implementation, such as @@ -169,4 +175,36 @@ import java.lang.annotation.*; @Target(ElementType.METHOD) public @interface DescriptorKey { String value(); + + /** + *
Do not include this field in the Descriptor if the annotation + * element has its default value. For example, suppose {@code @Units} is + * defined like this:
+ * + *+ * @Documented + * @Target(ElementType.METHOD) + * @Retention(RetentionPolicy.RUNTIME) + * public @interface Units { + * @DescriptorKey("units") + * String value(); + * + * @DescriptorKey(value = "descriptionResourceKey", + * omitIfDefault = true) + * String resourceKey() default ""; + * + * @DescriptorKey(value = "descriptionResourceBundleBaseName", + * omitIfDefault = true) + * String resourceBundleBaseName() default ""; + * } + *+ * + *Then consider a usage such as {@code @Units("bytes")} or + * {@code @Units(value = "bytes", resourceKey = "")}, where the + * {@code resourceKey} and {@code resourceBundleBaseNames} elements + * have their default values. In this case the Descriptor resulting + * from these annotations will not include a {@code descriptionResourceKey} + * or {@code descriptionResourceBundleBaseName} field.
+ */ + boolean omitIfDefault() default false; } diff --git a/jdk/src/share/classes/javax/management/DynamicWrapperMBean.java b/jdk/src/share/classes/javax/management/DynamicWrapperMBean.java new file mode 100644 index 00000000000..4a67a96795a --- /dev/null +++ b/jdk/src/share/classes/javax/management/DynamicWrapperMBean.java @@ -0,0 +1,62 @@ +/* + * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package javax.management; + +/** + *An MBean can implement this interface to affect how the MBeanServer's + * {@link MBeanServer#getClassLoaderFor getClassLoaderFor} and + * {@link MBeanServer#isInstanceOf isInstanceOf} methods behave. + * If these methods should refer to a wrapped object rather than the + * MBean object itself, then the {@link #getWrappedObject} method should + * return that wrapped object.
+ * + * @see MBeanServer#getClassLoaderFor + * @see MBeanServer#isInstanceOf + */ +public interface DynamicWrapperMBean extends DynamicMBean { + /** + *The resource corresponding to this MBean. This is the object whose + * class name should be reflected by the MBean's + * {@link MBeanServer#getMBeanInfo getMBeanInfo()}.{@link MBeanInfo#getClassName getClassName()} for example. For a "plain" + * DynamicMBean it will be "this". For an MBean that wraps another + * object, in the manner of {@link javax.management.StandardMBean}, it will be the + * wrapped object.
+ * + * @return The resource corresponding to this MBean. + */ + public Object getWrappedObject(); + + /** + *The {@code ClassLoader} for this MBean, which can be used to + * retrieve resources associated with the MBean for example. Usually, + * it will be + * {@link #getWrappedObject()}.{@code getClass().getClassLoader()}. + * + * @return The {@code ClassLoader} for this MBean. + */ + public ClassLoader getWrappedClassLoader(); +} diff --git a/jdk/src/share/classes/javax/management/Impact.java b/jdk/src/share/classes/javax/management/Impact.java new file mode 100644 index 00000000000..9416df6fac8 --- /dev/null +++ b/jdk/src/share/classes/javax/management/Impact.java @@ -0,0 +1,105 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package javax.management; + +/** + *
Defines the impact of an MBean operation, in particular whether it + * has an effect on the MBean or simply returns information. This enum + * is used in the {@link ManagedOperation @ManagedOperation} annotation. + * Its {@link #getCode()} method can be used to get an {@code int} suitable + * for use as the {@code impact} parameter in an {@link MBeanOperationInfo} + * constructor.
+ */ +public enum Impact { + /** + * The operation is read-like: it returns information but does not change + * any state. + * @see MBeanOperationInfo#INFO + */ + INFO(MBeanOperationInfo.INFO), + + /** + * The operation is write-like: it has an effect but does not return + * any information from the MBean. + * @see MBeanOperationInfo#ACTION + */ + ACTION(MBeanOperationInfo.ACTION), + + /** + * The operation is both read-like and write-like: it has an effect, + * and it also returns information from the MBean. + * @see MBeanOperationInfo#ACTION_INFO + */ + ACTION_INFO(MBeanOperationInfo.ACTION_INFO), + + /** + * The impact of the operation is unknown or cannot be expressed + * using one of the other values. + * @see MBeanOperationInfo#UNKNOWN + */ + UNKNOWN(MBeanOperationInfo.UNKNOWN); + + private final int code; + + /** + * An instance of this enumeration, with the corresponding {@code int} + * code used by the {@link MBeanOperationInfo} constructors. + * + * @param code the code used by the {@code MBeanOperationInfo} constructors. + */ + Impact(int code) { + this.code = code; + } + + /** + * The equivalent {@code int} code used by the {@link MBeanOperationInfo} + * constructors. + * @return the {@code int} code. + */ + public int getCode() { + return code; + } + + /** + * Return the {@code Impact} value corresponding to the given {@code int} + * code. The {@code code} is the value that would be used in an + * {@code MBeanOperationInfo} constructor. + * + * @param code the {@code int} code. + * + * @return an {@code Impact} value {@code x} such that + * {@code code == x.}{@link #getCode()}, or {@code Impact.UNKNOWN} + * if there is no such value. + */ + public static Impact forCode(int code) { + switch (code) { + case MBeanOperationInfo.ACTION: return ACTION; + case MBeanOperationInfo.INFO: return INFO; + case MBeanOperationInfo.ACTION_INFO: return ACTION_INFO; + default: return UNKNOWN; + } + } +} diff --git a/jdk/src/share/classes/javax/management/JMX.java b/jdk/src/share/classes/javax/management/JMX.java index 95608230c7e..87c7dd227ce 100644 --- a/jdk/src/share/classes/javax/management/JMX.java +++ b/jdk/src/share/classes/javax/management/JMX.java @@ -26,6 +26,7 @@ package javax.management; import com.sun.jmx.mbeanserver.Introspector; +import com.sun.jmx.mbeanserver.MBeanInjector; import com.sun.jmx.remote.util.ClassLogger; import java.beans.BeanInfo; import java.beans.PropertyDescriptor; @@ -130,6 +131,7 @@ public class JMX { *
Test if an MBean can emit notifications. An MBean can emit + * notifications if either it implements {@link NotificationBroadcaster} + * (perhaps through its child interface {@link NotificationEmitter}), or + * it uses resource + * injection to obtain an instance of {@link SendNotification} + * through which it can send notifications.
+ * + * @param mbean an MBean object. + * @return true if the given object is a valid MBean that can emit + * notifications; false if the object is a valid MBean but that + * cannot emit notifications. + * @throws NotCompliantMBeanException if the given object is not + * a valid MBean. + */ + public static boolean isNotificationSource(Object mbean) + throws NotCompliantMBeanException { + if (mbean instanceof NotificationBroadcaster) + return true; + Object resource = (mbean instanceof DynamicWrapperMBean) ? + ((DynamicWrapperMBean) mbean).getWrappedObject() : mbean; + return (MBeanInjector.injectsSendNotification(resource)); + } } diff --git a/jdk/src/share/classes/javax/management/MBean.java b/jdk/src/share/classes/javax/management/MBean.java new file mode 100644 index 00000000000..6837740334c --- /dev/null +++ b/jdk/src/share/classes/javax/management/MBean.java @@ -0,0 +1,68 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package javax.management; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + *Indicates that the annotated class is a Standard MBean. A Standard + * MBean class can be defined as in this example:
+ * + *+ * {@code @MBean} + * public class Configuration { + * {@link ManagedAttribute @ManagedAttribute} + * public int getCacheSize() {...} + * {@code @ManagedAttribute} + * public void setCacheSize(int size); + * + * {@code @ManagedAttribute} + * public long getLastChangedTime(); + * + * {@link ManagedOperation @ManagedOperation} + * public void save(); + * } + *+ * + *
The class must be public. Public methods within the class can be + * annotated with {@code @ManagedOperation} to indicate that they are + * MBean operations. Public getter and setter methods within the class + * can be annotated with {@code @ManagedAttribute} to indicate that they define + * MBean attributes.
+ * + *If the MBean is to be an MXBean rather than a Standard MBean, then + * the {@link MXBean @MXBean} annotation must be used instead of + * {@code @MBean}.
+ */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +@Inherited +public @interface MBean { +} diff --git a/jdk/src/share/classes/javax/management/MBeanOperationInfo.java b/jdk/src/share/classes/javax/management/MBeanOperationInfo.java index 9bda3ed5319..5863e96ef39 100644 --- a/jdk/src/share/classes/javax/management/MBeanOperationInfo.java +++ b/jdk/src/share/classes/javax/management/MBeanOperationInfo.java @@ -46,25 +46,30 @@ public class MBeanOperationInfo extends MBeanFeatureInfo implements Cloneable { new MBeanOperationInfo[0]; /** - * Indicates that the operation is read-like, - * it basically returns information. + * Indicates that the operation is read-like: + * it returns information but does not change any state. + * @see Impact#INFO */ public static final int INFO = 0; /** - * Indicates that the operation is a write-like, - * and would modify the MBean in some way, typically by writing some value - * or changing a configuration. + * Indicates that the operation is write-like: it has an effect but does + * not return any information from the MBean. + * @see Impact#ACTION */ public static final int ACTION = 1; /** - * Indicates that the operation is both read-like and write-like. + * Indicates that the operation is both read-like and write-like: + * it has an effect, and it also returns information from the MBean. + * @see Impact#ACTION_INFO */ public static final int ACTION_INFO = 2; /** - * Indicates that the operation has an "unknown" nature. + * Indicates that the impact of the operation is unknown or cannot be + * expressed using one of the other values. + * @see Impact#UNKNOWN */ public static final int UNKNOWN = 3; @@ -120,8 +125,9 @@ public class MBeanOperationInfo extends MBeanFeatureInfo implements Cloneable { * describing the parameters(arguments) of the method. This may be * null with the same effect as a zero-length array. * @param type The type of the method's return value. - * @param impact The impact of the method, one ofINFO,
- * ACTION, ACTION_INFO, UNKNOWN
.
+ * @param impact The impact of the method, one of
+ * {@link #INFO}, {@link #ACTION}, {@link #ACTION_INFO},
+ * {@link #UNKNOWN}.
*/
public MBeanOperationInfo(String name,
String description,
@@ -140,8 +146,9 @@ public class MBeanOperationInfo extends MBeanFeatureInfo implements Cloneable {
* describing the parameters(arguments) of the method. This may be
* null with the same effect as a zero-length array.
* @param type The type of the method's return value.
- * @param impact The impact of the method, one of INFO,
- * ACTION, ACTION_INFO, UNKNOWN
.
+ * @param impact The impact of the method, one of
+ * {@link #INFO}, {@link #ACTION}, {@link #ACTION_INFO},
+ * {@link #UNKNOWN}.
* @param descriptor The descriptor for the operation. This may be null
* which is equivalent to an empty descriptor.
*
@@ -319,9 +326,14 @@ public class MBeanOperationInfo extends MBeanFeatureInfo implements Cloneable {
for (int i = 0; i < classes.length; i++) {
Descriptor d = Introspector.descriptorForAnnotations(annots[i]);
- final String pn = "p" + (i + 1);
- params[i] =
- new MBeanParameterInfo(pn, classes[i].getName(), "", d);
+ String description = Introspector.descriptionForParameter(annots[i]);
+ if (description == null)
+ description = "";
+ String name = Introspector.nameForParameter(annots[i]);
+ if (name == null)
+ name = "p" + (i + 1);
+ params[i] = new MBeanParameterInfo(
+ name, classes[i].getName(), description, d);
}
return params;
diff --git a/jdk/src/share/classes/javax/management/MBeanRegistration.java b/jdk/src/share/classes/javax/management/MBeanRegistration.java
index fbdedc183b7..1ba1c0d827f 100644
--- a/jdk/src/share/classes/javax/management/MBeanRegistration.java
+++ b/jdk/src/share/classes/javax/management/MBeanRegistration.java
@@ -27,9 +27,101 @@ package javax.management;
/**
- * Can be implemented by an MBean in order to
+ * Can be implemented by an MBean in order to * carry out operations before and after being registered or unregistered from - * the MBean server. + * the MBean Server. An MBean can also implement this interface in order + * to get a reference to the MBean Server and/or its name within that + * MBean Server.
+ * + *As an alternative to implementing {@code MBeanRegistration}, if all that + * is needed is the MBean Server or ObjectName then an MBean can use + * resource injection.
+ * + *If a field in the MBean object has type {@link ObjectName} and has
+ * the {@link javax.annotation.Resource @Resource} annotation,
+ * then the {@code ObjectName} under which the MBean is registered is
+ * assigned to that field during registration. Likewise, if a field has type
+ * {@link MBeanServer} and the @Resource
annotation, then it will
+ * be set to the {@code MBeanServer} in which the MBean is registered.
For example:
+ * + *+ * public Configuration implements ConfigurationMBean { + * @Resource + * private volatile MBeanServer mbeanServer; + * @Resource + * private volatile ObjectName objectName; + * ... + * void unregisterSelf() throws Exception { + * mbeanServer.unregisterMBean(objectName); + * } + * } + *+ * + *
Resource injection can also be used on fields of type + * {@link SendNotification} to simplify notification sending. Such a field + * will get a reference to an object of type {@code SendNotification} when + * the MBean is registered, and it can use this reference to send notifications. + * For example:
+ * + *+ * public Configuration implements ConfigurationMBean { + * @Resource + * private volatile SendNotification sender; + * ... + * private void updated() { + * Notification n = new Notification(...); + * sender.sendNotification(n); + * } + * } + *+ * + *
A field to be injected must not be static. It is recommended that + * such fields be declared {@code volatile}.
+ * + *It is also possible to use the @Resource
annotation on
+ * methods. Such a method must have a {@code void} return type and a single
+ * argument of the appropriate type, for example {@code ObjectName}.
Any number of fields and methods may have the @Resource
+ * annotation. All fields and methods with type {@code ObjectName}
+ * (for example) will receive the same {@code ObjectName} value.
Resource injection is available for all types of MBeans, not just + * Standard MBeans.
+ * + *If an MBean implements the {@link DynamicWrapperMBean} interface then + * resource injection happens on the object returned by that interface's + * {@link DynamicWrapperMBean#getWrappedObject() getWrappedObject()} method + * rather than on the MBean object itself. + * + *
Resource injection happens after the {@link #preRegister preRegister}
+ * method is called (if any), and before the MBean is actually registered
+ * in the MBean Server. If a @Resource
method throws
+ * an exception, the effect is the same as if {@code preRegister} had
+ * thrown the exception. In particular it will prevent the MBean from being
+ * registered.
Resource injection can be used on a field or method where the type
+ * is a parent of the injected type, if the injected type is explicitly
+ * specified in the @Resource
annotation. For example:
+ * @Resource(type = MBeanServer.class) + * private volatile MBeanServerConnection mbsc; + *+ * + *
Formally, suppose R is the type in the @Resource
+ * annotation and T is the type of the method parameter or field.
+ * Then one of R and T must be a subtype of the other
+ * (or they must be the same type). Injection happens if this subtype
+ * is {@code MBeanServer}, {@code ObjectName}, or {@code SendNotification}.
+ * Otherwise the @Resource
annotation is ignored.
Resource injection in MBeans is new in version 2.0 of the JMX API.
* * @since 1.5 */ @@ -38,12 +130,12 @@ public interface MBeanRegistration { /** * Allows the MBean to perform any operations it needs before - * being registered in the MBean server. If the name of the MBean + * being registered in the MBean Server. If the name of the MBean * is not specified, the MBean can provide a name for its * registration. If any exception is raised, the MBean will not be - * registered in the MBean server. + * registered in the MBean Server. * - * @param server The MBean server in which the MBean will be registered. + * @param server The MBean Server in which the MBean will be registered. * * @param name The object name of the MBean. This name is null if * the name parameter to one of thecreateMBean
or
@@ -57,7 +149,7 @@ public interface MBeanRegistration {
* the returned value.
*
* @exception java.lang.Exception This exception will be caught by
- * the MBean server and re-thrown as an {@link
+ * the MBean Server and re-thrown as an {@link
* MBeanRegistrationException}.
*/
public ObjectName preRegister(MBeanServer server,
diff --git a/jdk/src/share/classes/javax/management/MBeanServer.java b/jdk/src/share/classes/javax/management/MBeanServer.java
index 34392aa5b0b..f0d4d16c46f 100644
--- a/jdk/src/share/classes/javax/management/MBeanServer.java
+++ b/jdk/src/share/classes/javax/management/MBeanServer.java
@@ -61,7 +61,7 @@ import javax.management.loading.ClassLoaderRepository;
* ObjectName
is: JMImplementation:type=MBeanServerDelegate
.
*
- * An object obtained from the {@link + *
An object obtained from the {@link * MBeanServerFactory#createMBeanServer(String) createMBeanServer} or * {@link MBeanServerFactory#newMBeanServer(String) newMBeanServer} * methods of the {@link MBeanServerFactory} class applies security @@ -661,13 +661,16 @@ public interface MBeanServer extends MBeanServerConnection { ReflectionException; /** - *
Return the {@link java.lang.ClassLoader} that was used for - * loading the class of the named MBean.
+ *Return the {@link java.lang.ClassLoader} that was used for loading + * the class of the named MBean. If the MBean implements the {@link + * DynamicWrapperMBean} interface, then the returned value is the + * result of the {@link DynamicWrapperMBean#getWrappedClassLoader()} + * method.
* * @param mbeanName The ObjectName of the MBean. * * @return The ClassLoader used for that MBean. If l - * is the MBean's actual ClassLoader, and r is the + * is the value specified by the rules above, and r is the * returned value, then either: * *Otherwise, the result is false.
* + *If the MBean implements the {@link DynamicWrapperMBean}
+ * interface, then in the above rules X is the result of the MBean's {@link
+ * DynamicWrapperMBean#getWrappedObject() getWrappedObject()} method and L
+ * is the result of its {@link DynamicWrapperMBean#getWrappedClassLoader()
+ * getWrappedClassLoader()} method.
+ *
* @param name The ObjectName
of the MBean.
* @param className The name of the class.
*
diff --git a/jdk/src/share/classes/javax/management/MXBean.java b/jdk/src/share/classes/javax/management/MXBean.java
index 191a76982b1..a577fd94ff5 100644
--- a/jdk/src/share/classes/javax/management/MXBean.java
+++ b/jdk/src/share/classes/javax/management/MXBean.java
@@ -27,6 +27,7 @@ package javax.management;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@@ -57,11 +58,13 @@ import javax.management.openmbean.TabularDataSupport;
import javax.management.openmbean.TabularType;
/**
-
Annotation to mark an interface explicitly as being an MXBean - interface, or as not being an MXBean interface. By default, an +
Annotation to mark a class or interface explicitly as being an MXBean, + or as not being an MXBean. By default, an interface is an MXBean interface if its name ends with {@code - MXBean}, as in {@code SomethingMXBean}. The following interfaces - are MXBean interfaces:
+ MXBean}, as in {@code SomethingMXBean}. A class is never an MXBean by + default. + +The following interfaces are MXBean interfaces:
public interface WhatsitMXBean {} @@ -82,6 +85,11 @@ import javax.management.openmbean.TabularType; public interface MisleadingMXBean {}+
A class can be annotated with {@code @MXBean} to indicate that it
+ is an MXBean. In this case, its methods should have @{@link
+ ManagedAttribute}
or @{@link ManagedOperation}
+ annotations, as described for @{@link MBean}
.
The MXBean concept provides a simple way to code an MBean @@ -1246,9 +1254,24 @@ public interface Node { @since 1.6 */ +/* + * This annotation is @Inherited because if an MXBean is defined as a + * class using annotations, then its subclasses are also MXBeans. + * For example: + * @MXBean + * public class Super { + * @ManagedAttribute + * public String getName() {...} + * } + * public class Sub extends Super {} + * Here Sub is an MXBean. + * + * The @Inherited annotation has no effect when applied to an interface. + */ @Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) +@Inherited public @interface MXBean { /** True if the annotated interface is an MXBean interface. diff --git a/jdk/src/share/classes/javax/management/ManagedAttribute.java b/jdk/src/share/classes/javax/management/ManagedAttribute.java new file mode 100644 index 00000000000..a8a7299d6f9 --- /dev/null +++ b/jdk/src/share/classes/javax/management/ManagedAttribute.java @@ -0,0 +1,64 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package javax.management; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + *
Indicates that a method in an MBean class defines an MBean attribute. + * This annotation must be applied to a public method of a public class + * that is itself annotated with an {@link MBean @MBean} or + * {@link MXBean @MXBean} annotation, or inherits such an annotation from + * a superclass.
+ * + *The annotated method must be a getter or setter. In other words, + * it must look like one of the following...
+ * + *+ * T getFoo() + * void setFoo(T param) + *+ * + *
...where {@code T} is any type and {@code Foo} is the + * name of the attribute. For any attribute {@code Foo}, if only + * a {@code get}{@code Foo} method has a {@code ManagedAttribute} + * annotation, then {@code Foo} is a read-only attribute. If only + * a {@code set}{@code Foo} method has a {@code ManagedAttribute} + * annotation, then {@code Foo} is a write-only attribute. If + * both {@code get}{@code Foo} and {@code set}{@code Foo} + * methods have the annotation, then {@code Foo} is a read-write + * attribute. In this last case, the type {@code T} must be the + * same in both methods.
+ */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +@Documented +public @interface ManagedAttribute { +} diff --git a/jdk/src/share/classes/javax/management/ManagedOperation.java b/jdk/src/share/classes/javax/management/ManagedOperation.java new file mode 100644 index 00000000000..fa01ac2bff6 --- /dev/null +++ b/jdk/src/share/classes/javax/management/ManagedOperation.java @@ -0,0 +1,67 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package javax.management; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + *Indicates that a method in an MBean class defines an MBean operation. + * This annotation can be applied to:
+ * + *Every method in an MBean or MXBean interface defines an MBean + * operation even without this annotation, but the annotation allows + * you to specify the impact of the operation:
+ * + *+ * public interface ConfigurationMBean { + * {@code @ManagedOperation}(impact = {@link Impact#ACTION Impact.ACTION}) + * public void save(); + * ... + * } + *+ */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +@Documented +public @interface ManagedOperation { + /** + *
The impact of this operation, as shown by + * {@link MBeanOperationInfo#getImpact()}. + */ + Impact impact() default Impact.UNKNOWN; +} diff --git a/jdk/src/share/classes/javax/management/NotQueryExp.java b/jdk/src/share/classes/javax/management/NotQueryExp.java index 51db3eb821a..bb39fbc95f7 100644 --- a/jdk/src/share/classes/javax/management/NotQueryExp.java +++ b/jdk/src/share/classes/javax/management/NotQueryExp.java @@ -91,6 +91,7 @@ class NotQueryExp extends QueryEval implements QueryExp { return "not (" + exp + ")"; } + @Override String toQueryString() { return "not (" + Query.toString(exp) + ")"; } diff --git a/jdk/src/share/classes/javax/management/NotificationBroadcasterSupport.java b/jdk/src/share/classes/javax/management/NotificationBroadcasterSupport.java index 65064ab900e..a358a7012a2 100644 --- a/jdk/src/share/classes/javax/management/NotificationBroadcasterSupport.java +++ b/jdk/src/share/classes/javax/management/NotificationBroadcasterSupport.java @@ -58,7 +58,8 @@ import com.sun.jmx.remote.util.ClassLogger; * * @since 1.5 */ -public class NotificationBroadcasterSupport implements NotificationEmitter { +public class NotificationBroadcasterSupport + implements NotificationEmitter, SendNotification { /** * Constructs a NotificationBroadcasterSupport where each listener is invoked by the * thread sending the notification. This constructor is equivalent to diff --git a/jdk/src/share/classes/javax/management/NotificationInfo.java b/jdk/src/share/classes/javax/management/NotificationInfo.java new file mode 100644 index 00000000000..a899346c06b --- /dev/null +++ b/jdk/src/share/classes/javax/management/NotificationInfo.java @@ -0,0 +1,117 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package javax.management; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + *
Specifies the kinds of notification an MBean can emit. In both the + * following examples, the MBean emits notifications of type + * {@code "com.example.notifs.create"} and of type + * {@code "com.example.notifs.destroy"}:
+ * + *+ * // Example one: a Standard MBean + * {@code @NotificationInfo}(types={"com.example.notifs.create", + * "com.example.notifs.destroy"}) + * public interface CacheMBean {...} + * + * public class Cache implements CacheMBean {...} + *+ * + *
+ * // Example two: an annotated MBean + * {@link MBean @MBean} + * {@code @NotificationInfo}(types={"com.example.notifs.create", + * "com.example.notifs.destroy"}) + * public class Cache {...} + *+ * + *
Each {@code @NotificationInfo} produces an {@link + * MBeanNotificationInfo} inside the {@link MBeanInfo} of each MBean + * to which the annotation applies.
+ * + *If you need to specify different notification classes, or different + * descriptions for different notification types, then you can group + * several {@code @NotificationInfo} annotations into a containing + * {@link NotificationInfos @NotificationInfos} annotation. + * + *
The {@code NotificationInfo} and {@code NotificationInfos} + * annotations can be applied to the MBean implementation class, or to + * any parent class or interface. These annotations on a class take + * precedence over annotations on any superclass or superinterface. + * If an MBean does not have these annotations on its class or any + * superclass, then superinterfaces are examined. It is an error for + * more than one superinterface to have these annotations, unless one + * of them is a child of all the others.
+ */ +@Documented +@Inherited +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface NotificationInfo { + /** + *The {@linkplain Notification#getType() notification types} + * that this MBean can emit.
+ */ + String[] types(); + + /** + *The class that emitted notifications will have. It is recommended + * that this be {@link Notification}, or one of its standard subclasses + * in the JMX API.
+ */ + Class extends Notification> notificationClass() default Notification.class; + + /** + *The description of this notification. For example: + * + *
+ * {@code @NotificationInfo}( + * types={"com.example.notifs.create"}, + * description={@code @Description}("object created")) + *+ */ + Description description() default @Description(""); + + /** + *
Additional descriptor fields for the derived {@code + * MBeanNotificationInfo}. They are specified in the same way as + * for the {@link DescriptorFields @DescriptorFields} annotation, + * for example:
+ *+ * {@code @NotificationInfo}( + * types={"com.example.notifs.create"}, + * descriptorFields={"severity=6"}) + *+ */ + String[] descriptorFields() default {}; +} diff --git a/jdk/src/share/classes/javax/management/NotificationInfos.java b/jdk/src/share/classes/javax/management/NotificationInfos.java new file mode 100644 index 00000000000..9d7c497a78d --- /dev/null +++ b/jdk/src/share/classes/javax/management/NotificationInfos.java @@ -0,0 +1,72 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package javax.management; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import javax.management.remote.JMXConnectionNotification; + +/** + *
Specifies the kinds of notification an MBean can emit, when this + * cannot be represented by a single {@link NotificationInfo + * @NotificationInfo} annotation.
+ * + *For example, this annotation specifies that an MBean can emit + * {@link AttributeChangeNotification} and {@link + * JMXConnectionNotification}:
+ * + *+ * {@code @NotificationInfos}( + * {@code @NotificationInfo}( + * types = {{@link AttributeChangeNotification#ATTRIBUTE_CHANGE}}, + * notificationClass = AttributeChangeNotification.class), + * {@code @NotificationInfo}( + * types = {{@link JMXConnectionNotification#OPENED}, + * {@link JMXConnectionNotification#CLOSED}}, + * notificationClass = JMXConnectionNotification.class) + * ) + *+ * + *
If an MBean has both {@code NotificationInfo} and {@code + * NotificationInfos} on the same class or interface, the effect is + * the same as if the {@code NotificationInfo} were moved inside the + * {@code NotificationInfos}.
+ */ +@Documented +@Inherited +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface NotificationInfos { + /** + *The {@link NotificationInfo} annotations.
+ */ + NotificationInfo[] value(); +} diff --git a/jdk/src/share/classes/javax/management/SendNotification.java b/jdk/src/share/classes/javax/management/SendNotification.java new file mode 100644 index 00000000000..e2875d4f121 --- /dev/null +++ b/jdk/src/share/classes/javax/management/SendNotification.java @@ -0,0 +1,38 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package javax.management; + +/** + * Interface implemented by objects that can be asked to send a notification. + */ +public interface SendNotification { + /** + * Sends a notification. + * + * @param notification The notification to send. + */ + public void sendNotification(Notification notification); +} diff --git a/jdk/src/share/classes/javax/management/StandardEmitterMBean.java b/jdk/src/share/classes/javax/management/StandardEmitterMBean.java index 6f2a9b57f82..c3faec374eb 100644 --- a/jdk/src/share/classes/javax/management/StandardEmitterMBean.java +++ b/jdk/src/share/classes/javax/management/StandardEmitterMBean.java @@ -25,6 +25,9 @@ package javax.management; +import com.sun.jmx.mbeanserver.MBeanInjector; +import static javax.management.JMX.MBeanOptions; + /** *An MBean whose management interface is determined by reflection * on a Java interface, and that emits notifications.
@@ -62,7 +65,7 @@ package javax.management; * @since 1.6 */ public class StandardEmitterMBean extends StandardMBean - implements NotificationEmitter { + implements NotificationEmitter, SendNotification { private final NotificationEmitter emitter; private final MBeanNotificationInfo[] notificationInfo; @@ -76,9 +79,10 @@ public class StandardEmitterMBean extends StandardMBean * for {@code implementation} and {@code emitter} to be the same object. * *If {@code emitter} is an instance of {@code - * NotificationBroadcasterSupport} then the MBean's {@link #sendNotification + * SendNotification} (for example, a {@link NotificationBroadcasterSupport}), + * then the MBean's {@link #sendNotification * sendNotification} method will call {@code emitter.}{@link - * NotificationBroadcasterSupport#sendNotification sendNotification}.
+ * SendNotification#sendNotification sendNotification}. * *The array returned by {@link #getNotificationInfo()} on the
* new MBean is a copy of the array returned by
@@ -90,20 +94,18 @@ public class StandardEmitterMBean extends StandardMBean
*
* @param implementation the implementation of the MBean interface.
* @param mbeanInterface a Standard MBean interface.
- * @param emitter the object that will handle notifications.
+ * @param emitter the object that will handle notifications. If null,
+ * a new {@code NotificationEmitter} will be constructed that also
+ * implements {@link SendNotification}.
*
* @throws IllegalArgumentException if the {@code mbeanInterface}
* does not follow JMX design patterns for Management Interfaces, or
* if the given {@code implementation} does not implement the
- * specified interface, or if {@code emitter} is null.
+ * specified interface.
*/
public
If {@code emitter} is an instance of {@code - * NotificationBroadcasterSupport} then the MBean's {@link #sendNotification + * SendNotification} (for example, a {@link NotificationBroadcasterSupport}), + * then the MBean's {@link #sendNotification * sendNotification} method will call {@code emitter.}{@link - * NotificationBroadcasterSupport#sendNotification sendNotification}.
+ * SendNotification#sendNotification sendNotification}. * *The array returned by {@link #getNotificationInfo()} on the
* new MBean is a copy of the array returned by
@@ -134,21 +137,69 @@ public class StandardEmitterMBean extends StandardMBean
* @param mbeanInterface a Standard MBean interface.
* @param isMXBean If true, the {@code mbeanInterface} parameter
* names an MXBean interface and the resultant MBean is an MXBean.
- * @param emitter the object that will handle notifications.
+ * @param emitter the object that will handle notifications. If null,
+ * a new {@code NotificationEmitter} will be constructed that also
+ * implements {@link SendNotification}.
*
* @throws IllegalArgumentException if the {@code mbeanInterface}
* does not follow JMX design patterns for Management Interfaces, or
* if the given {@code implementation} does not implement the
- * specified interface, or if {@code emitter} is null.
+ * specified interface.
*/
public Make an MBean whose management interface is specified by {@code
+ * mbeanInterface}, with the given implementation and options, and where
+ * notifications are handled by the given {@code NotificationEmitter}.
+ * Options select whether to make a Standard MBean or an MXBean, and
+ * whether the result of {@link #getWrappedObject()} is the {@code
+ * StandardEmitterMBean} object or the given implementation. The resultant
+ * MBean implements the {@code NotificationEmitter} interface by forwarding
+ * its methods to {@code emitter}. It is legal and useful for {@code
+ * implementation} and {@code emitter} to be the same object. If {@code emitter} is an instance of {@code
+ * SendNotification} (for example, a {@link NotificationBroadcasterSupport}),
+ * then the MBean's {@link #sendNotification
+ * sendNotification} method will call {@code emitter.}{@link
+ * SendNotification#sendNotification sendNotification}. The array returned by {@link #getNotificationInfo()} on the
+ * new MBean is a copy of the array returned by
+ * {@code emitter.}{@link NotificationBroadcaster#getNotificationInfo
+ * getNotificationInfo()} at the time of construction. If the array
+ * returned by {@code emitter.getNotificationInfo()} later changes,
+ * that will have no effect on this object's
+ * {@code getNotificationInfo()}.
If {@code emitter} is an instance of {@code - * NotificationBroadcasterSupport} then the MBean's {@link #sendNotification + * SendNotification} (for example, a {@link NotificationBroadcasterSupport}), + * then the MBean's {@link #sendNotification * sendNotification} method will call {@code emitter.}{@link - * NotificationBroadcasterSupport#sendNotification sendNotification}.
+ * SendNotification#sendNotification sendNotification}. * *The array returned by {@link #getNotificationInfo()} on the * new MBean is a copy of the array returned by @@ -175,20 +227,17 @@ public class StandardEmitterMBean extends StandardMBean * the given {@code mbeanInterface}.
* * @param mbeanInterface a StandardMBean interface. - * @param emitter the object that will handle notifications. + * @param emitter the object that will handle notifications. If null, + * a new {@code NotificationEmitter} will be constructed that also + * implements {@link SendNotification}. * * @throws IllegalArgumentException if the {@code mbeanInterface} * does not follow JMX design patterns for Management Interfaces, or - * if {@code this} does not implement the specified interface, or - * if {@code emitter} is null. + * if {@code this} does not implement the specified interface. */ protected StandardEmitterMBean(Class> mbeanInterface, NotificationEmitter emitter) { - super(mbeanInterface, false); - if (emitter == null) - throw new IllegalArgumentException("Null emitter"); - this.emitter = emitter; - this.notificationInfo = emitter.getNotificationInfo(); + this(mbeanInterface, false, emitter); } /** @@ -200,9 +249,10 @@ public class StandardEmitterMBean extends StandardMBean * forwarding its methods to {@code emitter}. * *If {@code emitter} is an instance of {@code - * NotificationBroadcasterSupport} then the MBean's {@link #sendNotification + * SendNotification} (for example, a {@link NotificationBroadcasterSupport}), + * then the MBean's {@link #sendNotification * sendNotification} method will call {@code emitter.}{@link - * NotificationBroadcasterSupport#sendNotification sendNotification}.
+ * SendNotification#sendNotification sendNotification}. * *The array returned by {@link #getNotificationInfo()} on the * new MBean is a copy of the array returned by @@ -218,20 +268,86 @@ public class StandardEmitterMBean extends StandardMBean * @param mbeanInterface a StandardMBean interface. * @param isMXBean If true, the {@code mbeanInterface} parameter * names an MXBean interface and the resultant MBean is an MXBean. - * @param emitter the object that will handle notifications. + * @param emitter the object that will handle notifications. If null, + * a new {@code NotificationEmitter} will be constructed that also + * implements {@link SendNotification}. * * @throws IllegalArgumentException if the {@code mbeanInterface} * does not follow JMX design patterns for Management Interfaces, or - * if {@code this} does not implement the specified interface, or - * if {@code emitter} is null. + * if {@code this} does not implement the specified interface. */ protected StandardEmitterMBean(Class> mbeanInterface, boolean isMXBean, NotificationEmitter emitter) { - super(mbeanInterface, isMXBean); + this(mbeanInterface, isMXBean ? MBeanOptions.MXBEAN : null, emitter); + } + + /** + *
Make an MBean whose management interface is specified by {@code + * mbeanInterface}, with the given options, and where notifications are + * handled by the given {@code NotificationEmitter}. This constructor can + * be used to make either Standard MBeans or MXBeans. The resultant MBean + * implements the {@code NotificationEmitter} interface by forwarding its + * methods to {@code emitter}.
+ * + *If {@code emitter} is an instance of {@code + * SendNotification} (for example, a {@link NotificationBroadcasterSupport}), + * then the MBean's {@link #sendNotification + * sendNotification} method will call {@code emitter.}{@link + * SendNotification#sendNotification sendNotification}.
+ * + *The array returned by {@link #getNotificationInfo()} on the + * new MBean is a copy of the array returned by + * {@code emitter.}{@link NotificationBroadcaster#getNotificationInfo + * getNotificationInfo()} at the time of construction. If the array + * returned by {@code emitter.getNotificationInfo()} later changes, + * that will have no effect on this object's + * {@code getNotificationInfo()}.
+ * + *This constructor must be called from a subclass that implements + * the given {@code mbeanInterface}.
+ * + * @param mbeanInterface a StandardMBean interface. + * @param options MBeanOptions that control the operation of the resulting + * MBean. + * @param emitter the object that will handle notifications. If null, + * a new {@code NotificationEmitter} will be constructed that also + * implements {@link SendNotification}. + * + * @throws IllegalArgumentException if the {@code mbeanInterface} + * does not follow JMX design patterns for Management Interfaces, or + * if {@code this} does not implement the specified interface. + */ + protected StandardEmitterMBean(Class> mbeanInterface, MBeanOptions options, + NotificationEmitter emitter) { + super(mbeanInterface, options); if (emitter == null) - throw new IllegalArgumentException("Null emitter"); + emitter = defaultEmitter(); this.emitter = emitter; this.notificationInfo = emitter.getNotificationInfo(); + injectEmitter(); + } + + private NotificationEmitter defaultEmitter() { + MBeanNotificationInfo[] mbnis = getNotificationInfo(); + // Will be null unless getNotificationInfo() is overridden, + // since the notificationInfo field has not been set at this point. + if (mbnis == null) + mbnis = getMBeanInfo().getNotifications(); + return new NotificationBroadcasterSupport(mbnis); + } + + private void injectEmitter() { + if (emitter instanceof SendNotification) { + try { + Object resource = getImplementation(); + SendNotification send = (SendNotification) emitter; + MBeanInjector.injectSendNotification(resource, send); + } catch (RuntimeException e) { + throw e; + } catch (Exception e) { + throw new IllegalArgumentException(e); + } + } } public void removeNotificationListener(NotificationListener listener) @@ -259,10 +375,10 @@ public class StandardEmitterMBean extends StandardMBean /** *Sends a notification.
* - *If the {@code emitter} parameter to the constructor was an - * instance of {@code NotificationBroadcasterSupport} then this - * method will call {@code emitter.}{@link - * NotificationBroadcasterSupport#sendNotification + *
If the {@code emitter} parameter to the constructor was + * an instance of {@link SendNotification}, such as {@link + * NotificationBroadcasterSupport}, then this method will call {@code + * emitter.}{@link SendNotification#sendNotification * sendNotification}.
* * @param n the notification to send. @@ -271,13 +387,12 @@ public class StandardEmitterMBean extends StandardMBean * constructor was not a {@code NotificationBroadcasterSupport}. */ public void sendNotification(Notification n) { - if (emitter instanceof NotificationBroadcasterSupport) - ((NotificationBroadcasterSupport) emitter).sendNotification(n); + if (emitter instanceof SendNotification) + ((SendNotification) emitter).sendNotification(n); else { final String msg = "Cannot sendNotification when emitter is not an " + - "instance of NotificationBroadcasterSupport: " + - emitter.getClass().getName(); + "instance of SendNotification: " + emitter.getClass().getName(); throw new ClassCastException(msg); } } @@ -292,6 +407,7 @@ public class StandardEmitterMBean extends StandardMBean * @param info The default MBeanInfo derived by reflection. * @return the MBeanNotificationInfo[] for the new MBeanInfo. */ + @Override MBeanNotificationInfo[] getNotifications(MBeanInfo info) { return getNotificationInfo(); } diff --git a/jdk/src/share/classes/javax/management/StandardMBean.java b/jdk/src/share/classes/javax/management/StandardMBean.java index f96ab7cf5e1..a779e8282bb 100644 --- a/jdk/src/share/classes/javax/management/StandardMBean.java +++ b/jdk/src/share/classes/javax/management/StandardMBean.java @@ -27,6 +27,7 @@ package javax.management; import com.sun.jmx.mbeanserver.DescriptorCache; import com.sun.jmx.mbeanserver.Introspector; +import com.sun.jmx.mbeanserver.MBeanInjector; import com.sun.jmx.mbeanserver.MBeanSupport; import com.sun.jmx.mbeanserver.MXBeanSupport; import com.sun.jmx.mbeanserver.StandardMBeanSupport; @@ -125,7 +126,78 @@ import static javax.management.JMX.MBeanOptions; * * @since 1.5 */ -public class StandardMBean implements DynamicMBean, MBeanRegistration { +public class StandardMBean implements DynamicWrapperMBean, MBeanRegistration { + + /** + *Options controlling the behavior of {@code StandardMBean} instances.
+ */ + public static class Options extends JMX.MBeanOptions { + private static final long serialVersionUID = 5107355471177517164L; + + private boolean wrappedVisible; + + /** + *Construct an {@code Options} object where all options have + * their default values.
+ */ + public Options() {} + + @Override + public Options clone() { + return (Options) super.clone(); + } + + /** + *Defines whether the {@link StandardMBean#getWrappedObject() + * getWrappedObject} method returns the wrapped object.
+ * + *If this option is true, then {@code getWrappedObject()} will return + * the same object as {@link StandardMBean#getImplementation() + * getImplementation}. Otherwise, it will return the + * StandardMBean instance itself. The setting of this option + * affects the behavior of {@link MBeanServer#getClassLoaderFor + * MBeanServer.getClassLoaderFor} and {@link MBeanServer#isInstanceOf + * MBeanServer.isInstanceOf}. The default value is false for + * compatibility reasons, but true is a better value for most new code.
+ * + * @return true if this StandardMBean's {@link + * StandardMBean#getWrappedObject getWrappedObject} returns the wrapped + * object. + */ + public boolean isWrappedObjectVisible() { + return this.wrappedVisible; + } + + /** + *Set the {@link #isWrappedObjectVisible WrappedObjectVisible} option + * to the given value.
+ * @param visible the new value. + */ + public void setWrappedObjectVisible(boolean visible) { + this.wrappedVisible = visible; + } + + // Canonical objects for each of (MXBean,!MXBean) x (WVisible,!WVisible) + private static final Options[] CANONICALS = { + new Options(), new Options(), new Options(), new Options(), + }; + static { + CANONICALS[1].setMXBeanMappingFactory(MXBeanMappingFactory.DEFAULT); + CANONICALS[2].setWrappedObjectVisible(true); + CANONICALS[3].setMXBeanMappingFactory(MXBeanMappingFactory.DEFAULT); + CANONICALS[3].setWrappedObjectVisible(true); + } + @Override + MBeanOptions[] canonicals() { + return CANONICALS; + } + + @Override + boolean same(MBeanOptions opts) { + return (super.same(opts) && opts instanceof Options && + ((Options) opts).wrappedVisible == wrappedVisible); + } + } private final static DescriptorCache descriptors = DescriptorCache.getInstance(JMX.proof); @@ -347,7 +419,7 @@ public class StandardMBean implements DynamicMBean, MBeanRegistration { * the management interface associated with the given * implementation. * @param options MBeanOptions that control the operation of the resulting - * MBean, as documented in the {@link MBeanOptions} class. + * MBean. * @paramGet the wrapped implementation object or return this object.
+ * + *For compatibility reasons, this method only returns the wrapped + * implementation object if the {@link Options#isWrappedObjectVisible + * WrappedObjectVisible} option was specified when this StandardMBean + * was created. Otherwise it returns {@code this}.
+ * + *If you want the MBeanServer's {@link MBeanServer#getClassLoaderFor + * getClassLoaderFor} and {@link MBeanServer#isInstanceOf + * isInstanceOf} methods to refer to the wrapped implementation and + * not this StandardMBean object, then you must set the + * {@code WrappedObjectVisible} option, for example using:
+ * + *+ * StandardMBean.Options opts = new StandardMBean.Options(); + * opts.setWrappedObjectVisible(true); + * StandardMBean mbean = new StandardMBean(impl, MyMBean.class, opts); + *+ * + * @return The wrapped implementation object, or this StandardMBean + * instance. + */ + public Object getWrappedObject() { + if (options instanceof Options && + ((Options) options).isWrappedObjectVisible()) + return getImplementation(); + else + return this; + } + + /** + *
Get the ClassLoader of the wrapped implementation object or of this + * object.
+ * + *For compatibility reasons, this method only returns the ClassLoader + * of the wrapped implementation object if the {@link + * Options#isWrappedObjectVisible WrappedObjectVisible} option was + * specified when this StandardMBean was created. Otherwise it returns + * {@code this.getClass().getClassLoader()}.
+ * + *If you want the MBeanServer's {@link MBeanServer#getClassLoaderFor + * getClassLoaderFor} and {@link MBeanServer#isInstanceOf + * isInstanceOf} methods to refer to the wrapped implementation and + * not this StandardMBean object, then you must set the + * {@code WrappedObjectVisible} option, for example using:
+ * + *+ * StandardMBean.Options opts = new StandardMBean.Options(); + * opts.setWrappedObjectVisible(true); + * StandardMBean mbean = new StandardMBean(impl, MyMBean.class, opts); + *+ * + * @return The ClassLoader of the wrapped Cimplementation object, or of + * this StandardMBean instance. + */ + public ClassLoader getWrappedClassLoader() { + return getWrappedObject().getClass().getClassLoader(); } /** @@ -457,7 +589,7 @@ public class StandardMBean implements DynamicMBean, MBeanRegistration { * @return The class of the implementation of this Standard MBean (or MXBean). **/ public Class> getImplementationClass() { - return mbean.getResource().getClass(); + return mbean.getWrappedObject().getClass(); } /** @@ -559,7 +691,7 @@ public class StandardMBean implements DynamicMBean, MBeanRegistration { MBeanSupport msupport = mbean; final MBeanInfo bi = msupport.getMBeanInfo(); - final Object impl = msupport.getResource(); + final Object impl = msupport.getWrappedObject(); final boolean immutableInfo = immutableInfo(this.getClass()); @@ -1184,6 +1316,7 @@ public class StandardMBean implements DynamicMBean, MBeanRegistration { public ObjectName preRegister(MBeanServer server, ObjectName name) throws Exception { mbean.register(server, name); + MBeanInjector.inject(mbean.getWrappedObject(), server, name); return name; } diff --git a/jdk/src/share/classes/javax/management/modelmbean/RequiredModelMBean.java b/jdk/src/share/classes/javax/management/modelmbean/RequiredModelMBean.java index bb5ad101f01..3c09c3ff2cc 100644 --- a/jdk/src/share/classes/javax/management/modelmbean/RequiredModelMBean.java +++ b/jdk/src/share/classes/javax/management/modelmbean/RequiredModelMBean.java @@ -23,7 +23,7 @@ * have any questions. */ /* - * @author IBM Corp. + * @(#)author IBM Corp. * * Copyright IBM Corp. 1999-2000. All rights reserved. */ @@ -55,6 +55,7 @@ import javax.management.AttributeChangeNotificationFilter; import javax.management.AttributeList; import javax.management.AttributeNotFoundException; import javax.management.Descriptor; +import javax.management.DynamicWrapperMBean; import javax.management.InstanceNotFoundException; import javax.management.InvalidAttributeValueException; import javax.management.ListenerNotFoundException; @@ -115,7 +116,7 @@ import sun.reflect.misc.ReflectUtil; */ public class RequiredModelMBean - implements ModelMBean, MBeanRegistration, NotificationEmitter { + implements ModelMBean, MBeanRegistration, NotificationEmitter, DynamicWrapperMBean { /*************************************/ /* attributes */ @@ -133,6 +134,9 @@ public class RequiredModelMBean * and operations will be executed */ private Object managedResource = null; + /* true if getWrappedObject returns the wrapped resource */ + private boolean visible; + /* records the registering in MBeanServer */ private boolean registered = false; private transient MBeanServer server = null; @@ -318,9 +322,13 @@ public class RequiredModelMBean * * @param mr Object that is the managed resource * @param mr_type The type of reference for the managed resource. - *
Get the managed resource for this Model MBean. For compatibility + * reasons, the managed resource is only returned if the resource type + * specified to {@link #setManagedResource setManagedResource} was {@code + * "visibleObjectReference"}. Otherwise, {@code this} is returned.
+ * + * @return The value that was specified to {@link #setManagedResource + * setManagedResource}, if the resource type is {@code + * "visibleObjectReference"}. Otherwise, {@code this}. + */ + public Object getWrappedObject() { + if (visible) + return managedResource; + else + return this; + } + + /** + *Get the ClassLoader of the managed resource for this Model MBean. For + * compatibility reasons, the ClassLoader of the managed resource is only + * returned if the resource type specified to {@link #setManagedResource + * setManagedResource} was {@code "visibleObjectReference"}. Otherwise, + * {@code this.getClass().getClassLoader()} is returned.
+ * + * @return The ClassLoader of the value that was specified to + * {@link #setManagedResource setManagedResource}, if the resource + * type is {@code "visibleObjectReference"}. Otherwise, {@code + * this.getClass().getClassLoader()}. + */ + public ClassLoader getWrappedClassLoader() { + return getWrappedObject().getClass().getClassLoader(); + } + + private static boolean isTrue(Descriptor d, String field) { + if (d == null) + return false; + Object x = d.getFieldValue(field); + if (x instanceof Boolean) + return (Boolean) x; + if (!(x instanceof String)) + return false; + String s = (String) x; + return ("true".equalsIgnoreCase(s) || "T".equalsIgnoreCase(s)); + } + /** *Instantiates this MBean instance with the data found for * the MBean in the persistent store. The data loaded could include diff --git a/jdk/src/share/classes/javax/management/monitor/package.html b/jdk/src/share/classes/javax/management/monitor/package.html index 5ccb72c9660..2e04b2422fc 100644 --- a/jdk/src/share/classes/javax/management/monitor/package.html +++ b/jdk/src/share/classes/javax/management/monitor/package.html @@ -38,14 +38,17 @@ have any questions. so within the access control context of the {@link javax.management.monitor.Monitor#start} caller.
-The value being monitored can be a simple value contained within a - complex type. For example, the {@link java.lang.management.MemoryMXBean - MemoryMXBean} defined in java.lang.management has an attribute - HeapMemoryUsage of type {@link java.lang.management.MemoryUsage - MemoryUsage}. To monitor the amount of used memory, described by - the used property of MemoryUsage, you could monitor - "HeapMemoryUsage.used". That string would be the argument to - {@link javax.management.monitor.MonitorMBean#setObservedAttribute(String) +
The value being monitored can be a simple value + contained within a complex type. For example, the {@link + java.lang.management.MemoryMXBean MemoryMXBean} defined in + java.lang.management has an attribute + HeapMemoryUsage of type {@link + java.lang.management.MemoryUsage MemoryUsage}. To monitor the + amount of used memory, described by the used + property of MemoryUsage, you could monitor + "HeapMemoryUsage.used". That string would be the + argument to {@link + javax.management.monitor.MonitorMBean#setObservedAttribute(String) setObservedAttribute}.
The rules used to interpret an ObservedAttribute like diff --git a/jdk/src/share/classes/javax/management/package.html b/jdk/src/share/classes/javax/management/package.html index 8d6205c2411..14027d648ea 100644 --- a/jdk/src/share/classes/javax/management/package.html +++ b/jdk/src/share/classes/javax/management/package.html @@ -56,41 +56,41 @@ have any questions. resource. It has a management interface consisting of:
-For example, an MBean representing an application's
- configuration could have attributes representing the different
- configuration items. Reading the CacheSize
- attribute would return the current value of that item.
- Writing it would update the item, potentially changing the
- behavior of the running application. An operation such as
- save
could store the current configuration
- persistently. A notification such as
- ConfigurationChangedNotification
could be sent
- every time the configuration is changed.
In the standard usage of the JMX API, MBeans are implemented - as Java objects. However, as explained below, these objects are - not usually referenced directly.
+For example, an MBean representing an application's
+ configuration could have attributes representing the different
+ configuration items. Reading the CacheSize
+ attribute would return the current value of that item.
+ Writing it would update the item, potentially changing the
+ behavior of the running application. An operation such as
+ save
could store the current configuration
+ persistently. A notification such as
+ ConfigurationChangedNotification
could be sent
+ every time the configuration is changed.
In the standard usage of the JMX API, MBeans are implemented + as Java objects. However, as explained below, these objects are + not usually referenced directly.
-To make MBean implementation simple, the JMX API includes the - notion of Standard MBeans. A Standard MBean is one - whose attributes and operations are deduced from a Java - interface using certain naming patterns, similar to those used - by JavaBeansTM. For - example, consider an interface like this:
+To make MBean implementation simple, the JMX API includes the + notion of Standard MBeans. A Standard MBean is one + whose attributes and operations are deduced from a Java + interface using certain naming patterns, similar to those used + by JavaBeansTM. For + example, consider an interface like this:
-+public interface ConfigurationMBean { public int getCacheSize(); public void setCacheSize(int size); @@ -128,107 +128,148 @@ have any questions. class. -MXBeans
- -An MXBean is a variant of Standard MBean where complex - types are mapped to a standard set of types defined in the - {@link javax.management.openmbean} package. MXBeans are appropriate - if you would otherwise need to reference application-specific - classes in your MBean interface. They are described in detail - in the specification for {@link javax.management.MXBean MXBean}. +
Defining Standard MBeans with annotations
+ +As an alternative to creating an interface such as +
+ +ConfigurationMBean
and a class that implements it, + you can write just the class, and use annotations to pick out the + public methods that will make up the management interface. For + example, the following class has the same management interface + as aConfiguration
class that implements the +ConfigurationMBean
interface above.+ {@link javax.management.MBean @MBean} + public class Configuration { + {@link javax.management.ManagedAttribute @ManagedAttribute} + public int getCacheSize() {...} + @ManagedAttribute + public void setCacheSize(int size) {...} + + @ManagedAttribute + public long getLastChangedTime() {...} + + {@link javax.management.ManagedOperation @ManagedOperation} + public void save() {...} + ... + } ++ +This approach simplifies development, but it does have two + potential drawbacks. First, if you run the Javadoc tool on + this class, the documentation of the management interface may + be mixed in with the documentation of non-management methods + in the class. Second, you cannot make a proxy + as described below if you do not have an + interface like
-ConfigurationMBean
.Dynamic MBeans
+MXBeans
-A Dynamic MBean is an MBean that defines its - management interface at run-time. For example, a configuration - MBean could determine the names and types of the attributes it - exposes by parsing an XML file.
+An MXBean is a variant of Standard MBean where complex + types are mapped to a standard set of types defined in the + {@link javax.management.openmbean} package. MXBeans are appropriate + if you would otherwise need to reference application-specific + classes in your MBean interface. They are described in detail + in the specification for {@link javax.management.MXBean MXBean}.
-Any Java object of a class that implements the {@link - javax.management.DynamicMBean DynamicMBean} interface is a - Dynamic MBean.
+You can define MXBeans using annotations as described + in the previous section, but + using the
-@MXBean
annotation instead of +@MBean
.Open MBeans
+Dynamic MBeans
-An Open MBean is a kind of Dynamic MBean where the - types of attributes and of operation parameters and return - values are built using a small set of predefined Java classes. - Open MBeans facilitate operation with remote management programs - that do not necessarily have access to application-specific - types, including non-Java programs. Open MBeans are defined by - the package
+- javax.management.openmbean
.A Dynamic MBean is an MBean that defines its + management interface at run-time. For example, a configuration + MBean could determine the names and types of the attributes it + exposes by parsing an XML file.
+ +Any Java object of a class that implements the {@link + javax.management.DynamicMBean DynamicMBean} interface is a + Dynamic MBean.
-Model MBeans
+Open MBeans
-A Model MBean is a kind of Dynamic MBean that acts - as a bridge between the management interface and the - underlying managed resource. Both the management interface and - the managed resource are specified as Java objects. The same - Model MBean implementation can be reused many times with - different management interfaces and managed resources, and it can - provide common functionality such as persistence and caching. - Model MBeans are defined by the package -
+- javax.management.modelmbean
.An Open MBean is a kind of Dynamic MBean where the + types of attributes and of operation parameters and return + values are built using a small set of predefined Java classes. + Open MBeans facilitate operation with remote management programs + that do not necessarily have access to application-specific + types, including non-Java programs. Open MBeans are defined by + the package
-+ javax.management.openmbean
.MBean Server
- -To be useful, an MBean must be registered in an MBean - Server. An MBean Server is a repository of MBeans. - Usually the only access to the MBeans is through the MBean - Server. In other words, code no longer accesses the Java - object implementing the MBean directly, but instead accesses - the MBean by name through the MBean Server. Each MBean has a - unique name within the MBean Server, defined by the {@link - javax.management.ObjectName ObjectName} class.
- -An MBean Server is an object implementing the interface - {@link javax.management.MBeanServer MBeanServer}. - The most convenient MBean Server to use is the - Platform MBean Server. This is a - single MBean Server that can be shared by different managed - components running within the same Java Virtual Machine. The - Platform MBean Server is accessed with the method {@link - java.lang.management.ManagementFactory#getPlatformMBeanServer()}.
+Model MBeans
-Application code can also create a new MBean Server, or - access already-created MBean Servers, using the {@link - javax.management.MBeanServerFactory MBeanServerFactory} class.
+A Model MBean is a kind of Dynamic MBean that acts + as a bridge between the management interface and the + underlying managed resource. Both the management interface and + the managed resource are specified as Java objects. The same + Model MBean implementation can be reused many times with + different management interfaces and managed resources, and it can + provide common functionality such as persistence and caching. + Model MBeans are defined by the package +
-+ javax.management.modelmbean
.Creating MBeans in the MBean Server
+MBean Server
-There are two ways to create an MBean. One is to construct a - Java object that will be the MBean, then use the {@link - javax.management.MBeanServer#registerMBean registerMBean} - method to register it in the MBean Server. The other is to - create and register the MBean in a single operation using one - of the {@link javax.management.MBeanServer#createMBean(String, - javax.management.ObjectName) createMBean} methods.
+To be useful, an MBean must be registered in an MBean + Server. An MBean Server is a repository of MBeans. + Usually the only access to the MBeans is through the MBean + Server. In other words, code no longer accesses the Java + object implementing the MBean directly, but instead accesses + the MBean by name through the MBean Server. Each MBean has a + unique name within the MBean Server, defined by the {@link + javax.management.ObjectName ObjectName} class.
-The
+registerMBean
method is simpler for local - use, but cannot be used remotely. The -createMBean
method can be used remotely, but - sometimes requires attention to class loading issues.An MBean Server is an object implementing the interface + {@link javax.management.MBeanServer MBeanServer}. + The most convenient MBean Server to use is the + Platform MBean Server. This is a + single MBean Server that can be shared by different managed + components running within the same Java Virtual Machine. The + Platform MBean Server is accessed with the method {@link + java.lang.management.ManagementFactory#getPlatformMBeanServer()}.
-An MBean can perform actions when it is registered in or - unregistered from an MBean Server if it implements the {@link - javax.management.MBeanRegistration MBeanRegistration} - interface.
+Application code can also create a new MBean Server, or + access already-created MBean Servers, using the {@link + javax.management.MBeanServerFactory MBeanServerFactory} class.
-Accessing MBeans in the MBean Server
+Creating MBeans in the MBean Server
-Given an
+ObjectName
name
and an -MBeanServer
mbs
, you can access - attributes and operations as in this example:There are two ways to create an MBean. One is to construct a + Java object that will be the MBean, then use the {@link + javax.management.MBeanServer#registerMBean registerMBean} + method to register it in the MBean Server. The other is to + create and register the MBean in a single operation using one + of the {@link javax.management.MBeanServer#createMBean(String, + javax.management.ObjectName) createMBean} methods.
-+The
+ +registerMBean
method is simpler for local + use, but cannot be used remotely. The +createMBean
method can be used remotely, but + sometimes requires attention to class loading issues.An MBean can perform actions when it is registered in or + unregistered from an MBean Server if it implements the {@link + javax.management.MBeanRegistration MBeanRegistration} + interface.
+ + +Accessing MBeans in the MBean Server
+ +Given an
+ +ObjectName
name
and an +MBeanServer
mbs
, you can access + attributes and operations as in this example:int cacheSize = mbs.getAttribute(name, "CacheSize"); {@link javax.management.Attribute Attribute} newCacheSize = new Attribute("CacheSize", new Integer(2000)); @@ -236,9 +277,9 @@ have any questions. mbs.invoke(name, "save", new Object[0], new Class[0]);-Alternatively, if you have a Java interface that corresponds - to the management interface for the MBean, you can use an - MBean proxy like this:
+Alternatively, if you have a Java interface that + corresponds to the management interface for the MBean, you can use an + MBean proxy like this:
ConfigurationMBean conf = @@ -264,66 +305,116 @@ have any questions. perform the query. -Notifications
+MBean lifecycle and resource injection
-A notification is an instance of the {@link - javax.management.Notification Notification} class or a - subclass. In addition to its Java class, it has a - type string that can distinguish it from other - notifications of the same class.
+An MBean can implement the {@link javax.management.MBeanRegistration + MBeanRegistration} interface in order to be told when it is registered + and unregistered in the MBean Server. Additionally, the {@link + javax.management.MBeanRegistration#preRegister preRegister} method + allows the MBean to get a reference to the
-MBeanServer
+ object and to get itsObjectName
within the MBean + Server.An MBean that will emit notifications must implement the - {@link javax.management.NotificationBroadcaster - NotificationBroadcaster} or {@link - javax.management.NotificationEmitter NotificationEmitter} - interface. Usually, it does this by subclassing {@link - javax.management.NotificationBroadcasterSupport - NotificationBroadcasterSupport} or by delegating to an instance - of that class.
- -Notifications can be received by a listener, which - is an object that implements the {@link - javax.management.NotificationListener NotificationListener} - interface. You can add a listener to an MBean with the method - {@link - javax.management.MBeanServer#addNotificationListener(ObjectName, - NotificationListener, NotificationFilter, Object)}. - You can optionally supply a filter to this method, to - select only notifications of interest. A filter is an object - that implements the {@link javax.management.NotificationFilter - NotificationFilter} interface.
- -An MBean can be a listener for notifications emitted by other - MBeans in the same MBean Server. In this case, it implements - {@link javax.management.NotificationListener - NotificationListener} and the method {@link - javax.management.MBeanServer#addNotificationListener(ObjectName, - ObjectName, NotificationFilter, Object)} is used to listen.
+If the only reason to implement
-MBeanRegistration
is to + discover theMBeanServer
andObjectName
, resource injection may be + more convenient.Remote Access to MBeans
+Notifications
-An MBean Server can be accessed remotely through a - connector. A connector allows a remote Java - application to access an MBean Server in essentially the same - way as a local one. The package -
+- javax.management.remote
defines connectors.A notification is an instance of the {@link + javax.management.Notification Notification} class or a + subclass. In addition to its Java class, it has a + type string that can distinguish it from other + notifications of the same class.
-The JMX specification also defines the notion of an - adaptor. An adaptor translates between requests in a - protocol such as SNMP or HTML and accesses to an MBean Server. - So for example an SNMP GET operation might result in a -
+getAttribute
on the MBean Server.If an MBean is to emit notifications, it must do one of two things.
-- @see - Java SE 6 Platform documentation on JMX technology - in particular the - - JMX Specification, version 1.4(pdf). +
The two classes below illustrate these two techniques:
+ ++ // Implementing NotificationEmitter (via NotificationBroadcasterSupport) + public class Configuration extends NotificationBroadcasterSupport + implements ConfigurationMBean { + ... + private void updated() { + Notification n = new Notification(...); + {@link javax.management.NotificationBroadcasterSupport#sendNotification + sendNotification}(n); + } + } + + // Getting a SendNotification through resource injection + public class Configuration implements ConfigurationMBean { + @Resource + private volatile SendNotification sender; + ... + private void updated() { + Notification n = new Notification(...); + sender.sendNotification(n); + } + } ++ + +
Notifications can be received by a listener, which + is an object that implements the {@link + javax.management.NotificationListener NotificationListener} + interface. You can add a listener to an MBean with the method + {@link + javax.management.MBeanServer#addNotificationListener(ObjectName, + NotificationListener, NotificationFilter, Object)}. + You can optionally supply a filter to this method, to + select only notifications of interest. A filter is an object + that implements the {@link javax.management.NotificationFilter + NotificationFilter} interface.
+ +An MBean can be a listener for notifications emitted by other + MBeans in the same MBean Server. In this case, it implements + {@link javax.management.NotificationListener + NotificationListener} and the method {@link + javax.management.MBeanServer#addNotificationListener(ObjectName, + ObjectName, NotificationFilter, Object)} is used to listen.
+ + +An MBean Server can be accessed remotely through a
+ connector. A connector allows a remote Java
+ application to access an MBean Server in essentially the same
+ way as a local one. The package
+
+ javax.management.remote
defines connectors.
The JMX specification also defines the notion of an
+ adaptor. An adaptor translates between requests in a
+ protocol such as SNMP or HTML and accesses to an MBean Server.
+ So for example an SNMP GET operation might result in a
+ getAttribute
on the MBean Server.
+ @see + Java SE 6 Platform documentation on JMX technology + in particular the + + JMX Specification, version 1.4(pdf). + + @since 1.5