This commit is contained in:
Alejandro Murillo 2015-06-01 10:15:21 -07:00
commit 3db56c53a0
6 changed files with 132 additions and 93 deletions

View File

@ -25,8 +25,26 @@
package sun.misc;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
public interface JavaBeansIntrospectorAccess {
public interface JavaBeansAccess {
/**
* Returns the getter method for a property of the given name
* @param clazz The JavaBeans class
* @param property The property name
* @return The resolved property getter method
* @throws Exception
*/
Method getReadMethod(Class<?> clazz, String property) throws Exception;
/**
* Return the <b>value</b> attribute of the associated
* <code>@ConstructorProperties</code> annotation if that is present.
* @param ctr The constructor to extract the annotation value from
* @return The {@code value} attribute of the <code>@ConstructorProperties</code>
* annotation or {@code null} if the constructor is not annotated by
* this annotation or the annotation is not accessible.
*/
String[] getConstructorPropertiesValue(Constructor<?> ctr);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 2015, Oracle and/or its affiliates. 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
@ -56,7 +56,7 @@ public class SharedSecrets {
private static JavaUtilZipFileAccess javaUtilZipFileAccess;
private static JavaAWTAccess javaAWTAccess;
private static JavaAWTFontAccess javaAWTFontAccess;
private static JavaBeansIntrospectorAccess javaBeansIntrospectorAccess;
private static JavaBeansAccess javaBeansAccess;
public static JavaUtilJarAccess javaUtilJarAccess() {
if (javaUtilJarAccess == null) {
@ -194,11 +194,11 @@ public class SharedSecrets {
return javaAWTFontAccess;
}
public static JavaBeansIntrospectorAccess getJavaBeansIntrospectorAccess() {
return javaBeansIntrospectorAccess;
public static JavaBeansAccess getJavaBeansAccess() {
return javaBeansAccess;
}
public static void setJavaBeansIntrospectorAccess(JavaBeansIntrospectorAccess access) {
javaBeansIntrospectorAccess = access;
public static void setJavaBeansAccess(JavaBeansAccess access) {
javaBeansAccess = access;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2015, Oracle and/or its affiliates. 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
@ -35,16 +35,19 @@ import java.awt.Component;
import java.lang.ref.Reference;
import java.lang.ref.SoftReference;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.Map;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.EventObject;
import java.util.List;
import java.util.TreeMap;
import sun.misc.JavaBeansAccess;
import sun.misc.SharedSecrets;
import sun.reflect.misc.ReflectUtil;
@ -146,15 +149,25 @@ public class Introspector {
// register with SharedSecrets for JMX usage
static {
SharedSecrets.setJavaBeansIntrospectorAccess((clazz, property) -> {
BeanInfo bi = Introspector.getBeanInfo(clazz);
PropertyDescriptor[] pds = bi.getPropertyDescriptors();
for (PropertyDescriptor pd: pds) {
if (pd.getName().equals(property)) {
return pd.getReadMethod();
SharedSecrets.setJavaBeansAccess(new JavaBeansAccess() {
@Override
public Method getReadMethod(Class<?> clazz, String property) throws Exception {
BeanInfo bi = Introspector.getBeanInfo(clazz);
PropertyDescriptor[] pds = bi.getPropertyDescriptors();
for (PropertyDescriptor pd: pds) {
if (pd.getName().equals(property)) {
return pd.getReadMethod();
}
}
return null;
}
@Override
public String[] getConstructorPropertiesValue(Constructor<?> ctr) {
ConstructorProperties cp = ctr.getAnnotation(ConstructorProperties.class);
String [] ret = cp != null ? cp.value() : null;
return ret;
}
return null;
});
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. 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
@ -33,14 +33,12 @@ import static javax.management.openmbean.SimpleType.*;
import com.sun.jmx.remote.util.EnvHelp;
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;
@ -1138,55 +1136,13 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
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 {
if (!AnnotationHelper.isAvailable())
if (!JavaBeansAccessor.isAvailable())
return "@ConstructorProperties annotation not available";
Class<?> targetClass = getTargetClass();
@ -1196,7 +1152,7 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
List<Constructor<?>> annotatedConstrList = newList();
for (Constructor<?> constr : constrs) {
if (Modifier.isPublic(constr.getModifiers())
&& AnnotationHelper.getPropertyNames(constr) != null)
&& JavaBeansAccessor.getConstructorPropertiesValue(constr) != null)
annotatedConstrList.add(constr);
}
@ -1225,7 +1181,7 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
// so we can test unambiguity.
Set<BitSet> getterIndexSets = newSet();
for (Constructor<?> constr : annotatedConstrList) {
String[] propertyNames = AnnotationHelper.getPropertyNames(constr);
String[] propertyNames = JavaBeansAccessor.getConstructorPropertiesValue(constr);
Type[] paramTypes = constr.getGenericParameterTypes();
if (paramTypes.length != propertyNames.length) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2015, Oracle and/or its affiliates. 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
@ -56,7 +56,7 @@ import java.security.AccessController;
import javax.management.AttributeNotFoundException;
import javax.management.openmbean.CompositeData;
import sun.misc.JavaBeansIntrospectorAccess;
import sun.misc.JavaBeansAccess;
import sun.misc.SharedSecrets;
import sun.reflect.misc.MethodUtil;
import sun.reflect.misc.ReflectUtil;
@ -552,10 +552,8 @@ public class Introspector {
// Java Beans introspection
//
Class<?> clazz = complex.getClass();
Method readMethod;
if (BeansIntrospector.isAvailable()) {
readMethod = BeansIntrospector.getReadMethod(clazz, element);
} else {
Method readMethod = JavaBeansAccessor.getReadMethod(clazz, element);
if (readMethod == null) {
// Java Beans not available so use simple introspection
// to locate method
readMethod = SimpleIntrospector.getReadMethod(clazz, element);
@ -579,30 +577,6 @@ public class Introspector {
}
}
/**
* Provides access to java.beans.Introspector if available.
*/
private static class BeansIntrospector {
private static final JavaBeansIntrospectorAccess JBIA;
static {
// ensure that java.beans.Introspector is initialized (if present)
try {
Class.forName("java.beans.Introspector", true,
BeansIntrospector.class.getClassLoader());
} catch (ClassNotFoundException ignore) { }
JBIA = SharedSecrets.getJavaBeansIntrospectorAccess();
}
static boolean isAvailable() {
return JBIA != null;
}
static Method getReadMethod(Class<?> clazz, String property) throws Exception {
return JBIA.getReadMethod(clazz, property);
}
}
/**
* A simple introspector that uses reflection to analyze a class and
* identify its "getter" methods. This class is intended for use only when

View File

@ -0,0 +1,78 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.jmx.mbeanserver;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import sun.misc.JavaBeansAccess;
import sun.misc.SharedSecrets;
/**
* A centralized place for gaining access to java.beans related functionality -
* if available.
*/
class JavaBeansAccessor {
static {
// ensure that java.beans.Introspector is initialized (if present)
// it will fill in the SharedSecrets
try {
Class.forName("java.beans.Introspector", true,
JavaBeansAccessor.class.getClassLoader());
} catch (ClassNotFoundException ignore) { }
}
private static JavaBeansAccess getJavaBeansAccess() {
return SharedSecrets.getJavaBeansAccess();
}
static boolean isAvailable() {
return getJavaBeansAccess() != null;
}
/**
* Returns the getter method for a property of the given name
* @param clazz The JavaBeans class
* @param property The property name
* @return The resolved property getter name or null
* @throws Exception
*/
static Method getReadMethod(Class<?> clazz, String property) throws Exception {
JavaBeansAccess jba = getJavaBeansAccess();
return jba != null ? jba.getReadMethod(clazz, property) : null;
}
/**
* Return the <b>value</b> attribute of the associated
* <code>@ConstructorProperties</code> annotation if that is present.
* @param ctr The constructor to extract the annotation value from
* @return The {@code value} attribute of the <code>@ConstructorProperties</code>
* annotation or {@code null} if the constructor is not annotated by
* this annotation or the annotation is not accessible.
*/
static String[] getConstructorPropertiesValue(Constructor<?> ctr) {
JavaBeansAccess jba = getJavaBeansAccess();
return jba != null ? jba.getConstructorPropertiesValue(ctr) : null;
}
}