7198070: Eliminate static dependency from JMX to java.beans.ConstructorProperties
authormchung
Tue, 18 Sep 2012 15:06:14 -0700
changeset 13820 a7148b4ceb0a
parent 13819 bea90847ee7e
child 13821 02266c2bf3a8
7198070: Eliminate static dependency from JMX to java.beans.ConstructorProperties Reviewed-by: alanb
jdk/src/share/classes/com/sun/jmx/mbeanserver/DefaultMXBeanMappingFactory.java
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/DefaultMXBeanMappingFactory.java	Tue Sep 18 14:45:09 2012 -0700
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/DefaultMXBeanMappingFactory.java	Tue Sep 18 15:06:14 2012 -0700
@@ -32,14 +32,15 @@
 
 import com.sun.jmx.remote.util.EnvHelp;
 
-import java.beans.ConstructorProperties;
 import java.io.InvalidObjectException;
+import java.lang.annotation.Annotation;
 import java.lang.annotation.ElementType;
 import java.lang.ref.WeakReference;
 import java.lang.reflect.Array;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
 import java.lang.reflect.GenericArrayType;
+import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 import java.lang.reflect.ParameterizedType;
@@ -1129,14 +1130,56 @@
         to getters.  */
     private static final class CompositeBuilderViaConstructor
             extends CompositeBuilder {
+        static class AnnotationHelper {
+            private static Class<? extends Annotation> constructorPropertiesClass;
+            private static Method valueMethod;
+            static {
+                findConstructorPropertiesClass();
+            }
+
+            @SuppressWarnings("unchecked")
+            private static void findConstructorPropertiesClass() {
+                try {
+                    constructorPropertiesClass = (Class<? extends Annotation>)
+                        Class.forName("java.beans.ConstructorProperties", false,
+                                      DefaultMXBeanMappingFactory.class.getClassLoader());
+                    valueMethod = constructorPropertiesClass.getMethod("value");
+                } catch (ClassNotFoundException cnf) {
+                    // java.beans not present
+                } catch (NoSuchMethodException e) {
+                    // should not reach here
+                    throw new InternalError(e);
+                }
+            }
+
+            static boolean isAvailable() {
+                return constructorPropertiesClass != null;
+            }
+
+            static String[] getPropertyNames(Constructor<?> constr) {
+                if (!isAvailable())
+                    return null;
+
+                Annotation a = constr.getAnnotation(constructorPropertiesClass);
+                if (a == null) return null;
+
+                try {
+                    return (String[]) valueMethod.invoke(a);
+                } catch (InvocationTargetException e) {
+                    throw new InternalError(e);
+                } catch (IllegalAccessException e) {
+                    throw new InternalError(e);
+                }
+            }
+        }
 
         CompositeBuilderViaConstructor(Class<?> targetClass, String[] itemNames) {
             super(targetClass, itemNames);
         }
 
         String applicable(Method[] getters) throws InvalidObjectException {
-
-            final Class<ConstructorProperties> propertyNamesClass = ConstructorProperties.class;
+            if (!AnnotationHelper.isAvailable())
+                return "@ConstructorProperties annotation not available";
 
             Class<?> targetClass = getTargetClass();
             Constructor<?>[] constrs = targetClass.getConstructors();
@@ -1145,7 +1188,7 @@
             List<Constructor<?>> annotatedConstrList = newList();
             for (Constructor<?> constr : constrs) {
                 if (Modifier.isPublic(constr.getModifiers())
-                        && constr.getAnnotation(propertyNamesClass) != null)
+                        && AnnotationHelper.getPropertyNames(constr) != null)
                     annotatedConstrList.add(constr);
             }
 
@@ -1174,8 +1217,7 @@
             // so we can test unambiguity.
             Set<BitSet> getterIndexSets = newSet();
             for (Constructor<?> constr : annotatedConstrList) {
-                String[] propertyNames =
-                    constr.getAnnotation(propertyNamesClass).value();
+                String[] propertyNames = AnnotationHelper.getPropertyNames(constr);
 
                 Type[] paramTypes = constr.getGenericParameterTypes();
                 if (paramTypes.length != propertyNames.length) {