Merge
authormchung
Mon, 23 Nov 2009 14:59:55 -0800
changeset 4333 9ce9b3f70e3d
parent 4332 04c1e30ac004 (current diff)
parent 4330 6f3647ce712e (diff)
child 4334 7f1f76f6ab66
Merge
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/Introspector.java	Mon Nov 23 10:46:19 2009 -0800
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/Introspector.java	Mon Nov 23 14:59:55 2009 -0800
@@ -26,6 +26,7 @@
 package com.sun.jmx.mbeanserver;
 
 import java.lang.annotation.Annotation;
+import java.lang.ref.SoftReference;
 import java.lang.reflect.AnnotatedElement;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Method;
@@ -33,8 +34,13 @@
 import java.lang.reflect.Proxy;
 import java.lang.reflect.UndeclaredThrowableException;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.HashMap;
+import java.util.List;
+import java.util.LinkedList;
+import java.util.Locale;
 import java.util.Map;
+import java.util.WeakHashMap;
 
 import javax.management.Descriptor;
 import javax.management.DescriptorKey;
@@ -506,11 +512,25 @@
             } else {
                 // Java Beans introspection
                 //
-                BeanInfo bi = java.beans.Introspector.getBeanInfo(complex.getClass());
-                PropertyDescriptor[] pds = bi.getPropertyDescriptors();
-                for (PropertyDescriptor pd : pds)
-                    if (pd.getName().equals(element))
-                        return pd.getReadMethod().invoke(complex);
+                Class<?> clazz = complex.getClass();
+                Method readMethod = null;
+                if (BeansHelper.isAvailable()) {
+                    Object bi = BeansHelper.getBeanInfo(clazz);
+                    Object[] pds = BeansHelper.getPropertyDescriptors(bi);
+                    for (Object pd: pds) {
+                        if (BeansHelper.getPropertyName(pd).equals(element)) {
+                            readMethod = BeansHelper.getReadMethod(pd);
+                            break;
+                        }
+                    }
+                } else {
+                    // Java Beans not available so use simple introspection
+                    // to locate method
+                    readMethod = SimpleIntrospector.getReadMethod(clazz, element);
+                }
+                if (readMethod != null)
+                    return readMethod.invoke(complex);
+
                 throw new AttributeNotFoundException(
                     "Could not find the getter method for the property " +
                     element + " using the Java Beans introspector");
@@ -524,4 +544,235 @@
                 new AttributeNotFoundException(e.getMessage()), e);
         }
     }
+
+    /**
+     * A simple introspector that uses reflection to analyze a class and
+     * identify its "getter" methods. This class is intended for use only when
+     * Java Beans is not present (which implies that there isn't explicit
+     * information about the bean available).
+     */
+    private static class SimpleIntrospector {
+        private SimpleIntrospector() { }
+
+        private static final String GET_METHOD_PREFIX = "get";
+        private static final String IS_METHOD_PREFIX = "is";
+
+        // cache to avoid repeated lookups
+        private static final Map<Class<?>,SoftReference<List<Method>>> cache =
+            Collections.synchronizedMap(
+                new WeakHashMap<Class<?>,SoftReference<List<Method>>> ());
+
+        /**
+         * Returns the list of methods cached for the given class, or {@code null}
+         * if not cached.
+         */
+        private static List<Method> getCachedMethods(Class<?> clazz) {
+            // return cached methods if possible
+            SoftReference<List<Method>> ref = cache.get(clazz);
+            if (ref != null) {
+                List<Method> cached = ref.get();
+                if (cached != null)
+                    return cached;
+            }
+            return null;
+        }
+
+        /**
+         * Returns {@code true} if the given method is a "getter" method (where
+         * "getter" method is a public method of the form getXXX or "boolean
+         * isXXX")
+         */
+        static boolean isReadMethod(Method method) {
+            // ignore static methods
+            int modifiers = method.getModifiers();
+            if (Modifier.isStatic(modifiers))
+                return false;
+
+            String name = method.getName();
+            Class<?>[] paramTypes = method.getParameterTypes();
+            int paramCount = paramTypes.length;
+
+            if (paramCount == 0 && name.length() > 2) {
+                // boolean isXXX()
+                if (name.startsWith(IS_METHOD_PREFIX))
+                    return (method.getReturnType() == boolean.class);
+                // getXXX()
+                if (name.length() > 3 && name.startsWith(GET_METHOD_PREFIX))
+                    return (method.getReturnType() != void.class);
+            }
+            return false;
+        }
+
+        /**
+         * Returns the list of "getter" methods for the given class. The list
+         * is ordered so that isXXX methods appear before getXXX methods - this
+         * is for compatability with the JavaBeans Introspector.
+         */
+        static List<Method> getReadMethods(Class<?> clazz) {
+            // return cached result if available
+            List<Method> cachedResult = getCachedMethods(clazz);
+            if (cachedResult != null)
+                return cachedResult;
+
+            // get list of public methods, filtering out methods that have
+            // been overridden to return a more specific type.
+            List<Method> methods =
+                StandardMBeanIntrospector.getInstance().getMethods(clazz);
+            methods = MBeanAnalyzer.eliminateCovariantMethods(methods);
+
+            // filter out the non-getter methods
+            List<Method> result = new LinkedList<Method>();
+            for (Method m: methods) {
+                if (isReadMethod(m)) {
+                    // favor isXXX over getXXX
+                    if (m.getName().startsWith(IS_METHOD_PREFIX)) {
+                        result.add(0, m);
+                    } else {
+                        result.add(m);
+                    }
+                }
+            }
+
+            // add result to cache
+            cache.put(clazz, new SoftReference<List<Method>>(result));
+
+            return result;
+        }
+
+        /**
+         * Returns the "getter" to read the given property from the given class or
+         * {@code null} if no method is found.
+         */
+        static Method getReadMethod(Class<?> clazz, String property) {
+            // first character in uppercase (compatability with JavaBeans)
+            property = property.substring(0, 1).toUpperCase(Locale.ENGLISH) +
+                property.substring(1);
+            String getMethod = GET_METHOD_PREFIX + property;
+            String isMethod = IS_METHOD_PREFIX + property;
+            for (Method m: getReadMethods(clazz)) {
+                String name = m.getName();
+                if (name.equals(isMethod) || name.equals(getMethod)) {
+                    return m;
+                }
+            }
+            return null;
+        }
+    }
+
+    /**
+     * A class that provides access to the JavaBeans Introspector and
+     * PropertyDescriptors without creating a static dependency on java.beans.
+     */
+    private static class BeansHelper {
+        private static final Class<?> introspectorClass =
+            getClass("java.beans.Introspector");
+        private static final Class<?> beanInfoClass =
+            (introspectorClass == null) ? null : getClass("java.beans.BeanInfo");
+        private static final Class<?> getPropertyDescriptorClass =
+            (beanInfoClass == null) ? null : getClass("java.beans.PropertyDescriptor");
+
+        private static final Method getBeanInfo =
+            getMethod(introspectorClass, "getBeanInfo", Class.class);
+        private static final Method getPropertyDescriptors =
+            getMethod(beanInfoClass, "getPropertyDescriptors");
+        private static final Method getPropertyName =
+            getMethod(getPropertyDescriptorClass, "getName");
+        private static final Method getReadMethod =
+            getMethod(getPropertyDescriptorClass, "getReadMethod");
+
+        private static Class<?> getClass(String name) {
+            try {
+                return Class.forName(name, true, null);
+            } catch (ClassNotFoundException e) {
+                return null;
+            }
+        }
+        private static Method getMethod(Class<?> clazz,
+                                        String name,
+                                        Class<?>... paramTypes)
+        {
+            if (clazz != null) {
+                try {
+                    return clazz.getMethod(name, paramTypes);
+                } catch (NoSuchMethodException e) {
+                    throw new AssertionError(e);
+                }
+            } else {
+                return null;
+            }
+        }
+
+        private BeansHelper() { }
+
+        /**
+         * Returns {@code true} if java.beans is available.
+         */
+        static boolean isAvailable() {
+            return introspectorClass != null;
+        }
+
+        /**
+         * Invokes java.beans.Introspector.getBeanInfo(Class)
+         */
+        static Object getBeanInfo(Class<?> clazz) throws Exception {
+            try {
+                return getBeanInfo.invoke(null, clazz);
+            } catch (InvocationTargetException e) {
+                Throwable cause = e.getCause();
+                if (cause instanceof Exception)
+                    throw (Exception)cause;
+                throw new AssertionError(e);
+            } catch (IllegalAccessException iae) {
+                throw new AssertionError(iae);
+            }
+        }
+
+        /**
+         * Invokes java.beans.BeanInfo.getPropertyDescriptors()
+         */
+        static Object[] getPropertyDescriptors(Object bi) {
+            try {
+                return (Object[])getPropertyDescriptors.invoke(bi);
+            } catch (InvocationTargetException e) {
+                Throwable cause = e.getCause();
+                if (cause instanceof RuntimeException)
+                    throw (RuntimeException)cause;
+                throw new AssertionError(e);
+            } catch (IllegalAccessException iae) {
+                throw new AssertionError(iae);
+            }
+        }
+
+        /**
+         * Invokes java.beans.PropertyDescriptor.getName()
+         */
+        static String getPropertyName(Object pd) {
+            try {
+                return (String)getPropertyName.invoke(pd);
+            } catch (InvocationTargetException e) {
+                Throwable cause = e.getCause();
+                if (cause instanceof RuntimeException)
+                    throw (RuntimeException)cause;
+                throw new AssertionError(e);
+            } catch (IllegalAccessException iae) {
+                throw new AssertionError(iae);
+            }
+        }
+
+        /**
+         * Invokes java.beans.PropertyDescriptor.getReadMethod()
+         */
+        static Method getReadMethod(Object pd) {
+            try {
+                return (Method)getReadMethod.invoke(pd);
+            } catch (InvocationTargetException e) {
+                Throwable cause = e.getCause();
+                if (cause instanceof RuntimeException)
+                    throw (RuntimeException)cause;
+                throw new AssertionError(e);
+            } catch (IllegalAccessException iae) {
+                throw new AssertionError(iae);
+            }
+        }
+    }
 }
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanIntrospector.java	Mon Nov 23 10:46:19 2009 -0800
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanIntrospector.java	Mon Nov 23 14:59:55 2009 -0800
@@ -175,7 +175,7 @@
     /**
      * Get the methods to be analyzed to build the MBean interface.
      */
-    List<Method> getMethods(final Class<?> mbeanType) throws Exception {
+    List<Method> getMethods(final Class<?> mbeanType) {
         return Arrays.asList(mbeanType.getMethods());
     }
 
--- a/jdk/src/share/classes/sun/security/validator/PKIXValidator.java	Mon Nov 23 10:46:19 2009 -0800
+++ b/jdk/src/share/classes/sun/security/validator/PKIXValidator.java	Mon Nov 23 14:59:55 2009 -0800
@@ -150,9 +150,17 @@
                 ("null or zero-length certificate chain");
         }
         if (TRY_VALIDATOR) {
-            // check if chain contains trust anchor
+            // check that chain is in correct order and check if chain contains
+            // trust anchor
+            X500Principal prevIssuer = null;
             for (int i = 0; i < chain.length; i++) {
-                if (trustedCerts.contains(chain[i])) {
+                X509Certificate cert = chain[i];
+                if (i != 0 &&
+                    !cert.getSubjectX500Principal().equals(prevIssuer)) {
+                    // chain is not ordered correctly, call builder instead
+                    return doBuild(chain, otherCerts);
+                }
+                if (trustedCerts.contains(cert)) {
                     if (i == 0) {
                         return new X509Certificate[] {chain[0]};
                     }
@@ -161,6 +169,7 @@
                     System.arraycopy(chain, 0, newChain, 0, i);
                     return doValidate(newChain);
                 }
+                prevIssuer = cert.getIssuerX500Principal();
             }
 
             // apparently issued by trust anchor?
@@ -303,5 +312,4 @@
                 ("PKIX path building failed: " + e.toString(), e);
         }
     }
-
 }
--- a/jdk/test/Makefile	Mon Nov 23 10:46:19 2009 -0800
+++ b/jdk/test/Makefile	Mon Nov 23 14:59:55 2009 -0800
@@ -337,9 +337,11 @@
 # jtreg tests
 
 # Expect JT_HOME to be set for jtreg tests. (home for jtreg)
-JT_HOME = $(SLASH_JAVA)/re/jtreg/4.0/promoted/latest/binaries/jtreg
-ifdef JPRT_JTREG_HOME
-  JT_HOME = $(JPRT_JTREG_HOME)
+ifndef JT_HOME
+  JT_HOME = $(SLASH_JAVA)/re/jtreg/4.0/promoted/latest/binaries/jtreg
+  ifdef JPRT_JTREG_HOME
+    JT_HOME = $(JPRT_JTREG_HOME)
+  endif
 endif
 
 # Expect JPRT to set TESTDIRS to the jtreg test dirs
@@ -361,21 +363,22 @@
 
 # Some tests annoy me and fail frequently
 PROBLEM_LIST=ProblemList.txt
+PROBLEM_LISTS=$(PROBLEM_LIST) $(wildcard closed/$(PROBLEM_LIST))
 EXCLUDELIST=$(ABS_TEST_OUTPUT_DIR)/excludelist.txt
 
 # Create exclude list for this platform and arch
 ifdef NO_EXCLUDES
-$(EXCLUDELIST): $(PROBLEM_LIST) $(TESTDIRS)
+$(EXCLUDELIST): $(PROBLEM_LISTS) $(TESTDIRS)
 	@$(ECHO) "NOTHING_EXCLUDED" > $@
 else
-$(EXCLUDELIST): $(PROBLEM_LIST) $(TESTDIRS)
+$(EXCLUDELIST): $(PROBLEM_LISTS) $(TESTDIRS)
 	@$(RM) $@ $@.temp1 $@.temp2
-	@( ( $(EGREP) -- '$(OS_NAME)-all'           $< ) ;\
-	   ( $(EGREP) -- '$(OS_NAME)-$(OS_ARCH)'    $< ) ;\
-	   ( $(EGREP) -- '$(OS_NAME)-$(OS_VERSION)' $< ) ;\
-	   ( $(EGREP) -- 'generic-$(OS_ARCH)'       $< ) ;\
-           ( $(EGREP) -- 'generic-all'              $< ) ;\
-           ( $(ECHO) "#") ;\
+	@(($(CAT) $(PROBLEM_LISTS) | $(EGREP) -- '$(OS_NAME)-all'          ) ;\
+	  ($(CAT) $(PROBLEM_LISTS) | $(EGREP) -- '$(OS_NAME)-$(OS_ARCH)'   ) ;\
+	  ($(CAT) $(PROBLEM_LISTS) | $(EGREP) -- '$(OS_NAME)-$(OS_VERSION)') ;\
+	  ($(CAT) $(PROBLEM_LISTS) | $(EGREP) -- 'generic-$(OS_ARCH)'      ) ;\
+          ($(CAT) $(PROBLEM_LISTS) | $(EGREP) -- 'generic-all'             ) ;\
+          ($(ECHO) "#") ;\
         ) | $(SED) -e 's@^[\ ]*@@' \
           | $(EGREP) -v '^#' > $@.temp1
 	@for tdir in $(TESTDIRS) ; do \
@@ -386,14 +389,18 @@
 	@$(ECHO) "Excluding list contains `$(EXPAND) $@ | $(WC) -l` items"
 endif
 
+# Select list of directories that exist
+define TestDirs
+$(foreach i,$1,$(wildcard ${i})) $(foreach i,$1,$(wildcard closed/${i}))
+endef
 # Running batches of tests with or without samevm
 define RunSamevmBatch
-$(ECHO) "Running tests in samevm mode: $?"
-$(MAKE) TESTDIRS="$?" USE_JTREG_SAMEVM=true  UNIQUE_DIR=$@ jtreg_tests
+$(ECHO) "Running tests in samevm mode: $(call TestDirs, $?)"
+$(MAKE) TESTDIRS="$(call TestDirs, $?)" USE_JTREG_SAMEVM=true  UNIQUE_DIR=$@ jtreg_tests
 endef
 define RunOthervmBatch
-$(ECHO) "Running tests in othervm mode: $?"
-$(MAKE) TESTDIRS="$?" USE_JTREG_SAMEVM=false UNIQUE_DIR=$@ jtreg_tests
+$(ECHO) "Running tests in othervm mode: $(call TestDirs, $?)"
+$(MAKE) TESTDIRS="$(call TestDirs, $?)" USE_JTREG_SAMEVM=false UNIQUE_DIR=$@ jtreg_tests
 endef
 define SummaryInfo
 $(ECHO) "Summary for: $?"
@@ -428,6 +435,9 @@
 jdk_beans3: java/beans/XMLEncoder
 	$(call RunOthervmBatch)
 
+jdk_beans: jdk_beans1 jdk_beans2 jdk_beans3
+	@$(SummaryInfo)
+
 # Stable samevm testruns (minus items from PROBLEM_LIST)
 JDK_ALL_TARGETS += jdk_io
 jdk_io: java/io
@@ -450,6 +460,9 @@
 jdk_management2: com/sun/jmx com/sun/management sun/management
 	$(call RunOthervmBatch)
 
+jdk_management: jdk_management1 jdk_management2
+	@$(SummaryInfo)
+
 # Stable samevm testruns (minus items from PROBLEM_LIST)
 JDK_ALL_TARGETS += jdk_math
 jdk_math: java/math
@@ -482,6 +495,9 @@
 jdk_nio3: com/sun/nio sun/nio
 	$(call RunOthervmBatch)
 
+jdk_nio: jdk_nio1 jdk_nio2 jdk_nio3
+	@$(SummaryInfo)
+
 # Stable othervm testruns (minus items from PROBLEM_LIST)
 #   Using samevm has serious problems with these tests
 JDK_ALL_TARGETS += jdk_rmi
@@ -502,6 +518,9 @@
 jdk_security3: com/sun/security lib/security javax/security sun/security
 	$(call RunOthervmBatch)
 
+jdk_security: jdk_security1 jdk_security2 jdk_security3
+	@$(SummaryInfo)
+
 # Stable othervm testruns (minus items from PROBLEM_LIST)
 #   Using samevm has problems, and doesn't help performance as much as others.
 JDK_ALL_TARGETS += jdk_swing
@@ -522,6 +541,9 @@
 jdk_tools2: com/sun/tools sun/jvmstat sun/tools tools vm com/sun/servicetag com/sun/tracing
 	$(call RunOthervmBatch)
 
+jdk_tools: jdk_tools1 jdk_tools2
+	@$(SummaryInfo)
+
 # Stable samevm testruns (minus items from PROBLEM_LIST)
 JDK_ALL_TARGETS += jdk_util
 jdk_util: java/util sun/util
--- a/jdk/test/ProblemList.txt	Mon Nov 23 10:46:19 2009 -0800
+++ b/jdk/test/ProblemList.txt	Mon Nov 23 14:59:55 2009 -0800
@@ -344,6 +344,9 @@
 # Some of these tests (like java/lang/management) may just need to be marked
 #   othervm, but that is partially speculation.
 
+# Samevm failure on OpenSolaris, security manager?
+java/lang/ClassLoader/UninitializedParent.java			generic-all
+
 # Times out on solaris 10 sparc
 java/lang/ClassLoader/Assert.java				generic-all
 
@@ -538,6 +541,18 @@
 # Missing close on file wbmp*, windows samevm
 javax/imageio/plugins/wbmp/CanDecodeTest.java			generic-all
 
+# Failures on OpenSolaris, cannot read input files? samevm issues?
+javax/imageio/metadata/BooleanAttributes.java			generic-all
+javax/imageio/plugins/bmp/BMPSubsamplingTest.java		generic-all
+javax/imageio/plugins/bmp/TopDownTest.java			generic-all
+javax/imageio/plugins/gif/EncodeSubImageTest.java		generic-all
+javax/imageio/plugins/gif/GifTransparencyTest.java		generic-all
+javax/imageio/plugins/png/GrayPngTest.java			generic-all
+javax/imageio/plugins/png/ItxtUtf8Test.java			generic-all
+javax/imageio/plugins/png/MergeStdCommentTest.java		generic-all
+javax/imageio/plugins/png/ShortHistogramTest.java		generic-all
+javax/imageio/plugins/shared/BitDepth.java			generic-all
+
 # Exclude all javax/print tests, even if they passed, they may need samevm work
 
 # Times out on solaris-sparc, sparcv9, x64 -server, some on i586 -client