8010285: Enforce the requirement of Management Interfaces being public
authorjbachorik
Thu, 11 Jul 2013 21:11:03 +0200
changeset 18805 b359f8adc8ad
parent 18804 8561f2098727
child 18806 c094f5a236ba
8010285: Enforce the requirement of Management Interfaces being public Reviewed-by: sjiang, dfuchs, mchung
jdk/src/share/classes/com/sun/jmx/mbeanserver/Introspector.java
jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanAnalyzer.java
jdk/src/share/classes/javax/management/JMX.java
jdk/src/share/classes/javax/management/MBeanServerInvocationHandler.java
jdk/src/share/classes/javax/management/MXBean.java
jdk/src/share/classes/javax/management/package.html
jdk/src/share/classes/sun/management/ManagementFactoryHelper.java
jdk/test/javax/management/MBeanServer/MBeanFallbackTest.java
jdk/test/javax/management/MBeanServer/MBeanTest.java
jdk/test/javax/management/mxbean/MXBeanFallbackTest.java
jdk/test/javax/management/mxbean/MXBeanTest.java
jdk/test/javax/management/proxy/JMXProxyFallbackTest.java
jdk/test/javax/management/proxy/JMXProxyTest.java
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/Introspector.java	Thu Jul 11 11:43:23 2013 -0700
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/Introspector.java	Thu Jul 11 21:11:03 2013 +0200
@@ -52,6 +52,7 @@
 import com.sun.jmx.remote.util.EnvHelp;
 import java.lang.reflect.Array;
 import java.lang.reflect.InvocationTargetException;
+import java.security.AccessController;
 import javax.management.AttributeNotFoundException;
 import javax.management.openmbean.CompositeData;
 import sun.reflect.misc.MethodUtil;
@@ -64,7 +65,11 @@
  * @since 1.5
  */
 public class Introspector {
-
+    final public static boolean ALLOW_NONPUBLIC_MBEAN;
+    static {
+        String val = AccessController.doPrivileged(new GetPropertyAction("jdk.jmx.mbeans.allowNonPublic"));
+        ALLOW_NONPUBLIC_MBEAN = Boolean.parseBoolean(val);
+    }
 
      /*
      * ------------------------------------------
@@ -223,11 +228,27 @@
         return testCompliance(baseClass, null);
     }
 
+    /**
+     * Tests the given interface class for being a compliant MXBean interface.
+     * A compliant MXBean interface is any publicly accessible interface
+     * following the {@link MXBean} conventions.
+     * @param interfaceClass An interface class to test for the MXBean compliance
+     * @throws NotCompliantMBeanException Thrown when the tested interface
+     * is not public or contradicts the {@link MXBean} conventions.
+     */
     public static void testComplianceMXBeanInterface(Class<?> interfaceClass)
             throws NotCompliantMBeanException {
         MXBeanIntrospector.getInstance().getAnalyzer(interfaceClass);
     }
 
+    /**
+     * Tests the given interface class for being a compliant MBean interface.
+     * A compliant MBean interface is any publicly accessible interface
+     * following the {@code MBean} conventions.
+     * @param interfaceClass An interface class to test for the MBean compliance
+     * @throws NotCompliantMBeanException Thrown when the tested interface
+     * is not public or contradicts the {@code MBean} conventions.
+     */
     public static void testComplianceMBeanInterface(Class<?> interfaceClass)
             throws NotCompliantMBeanException{
         StandardMBeanIntrospector.getInstance().getAnalyzer(interfaceClass);
@@ -299,18 +320,18 @@
      * not a JMX compliant Standard MBean.
      */
     public static <T> Class<? super T> getStandardMBeanInterface(Class<T> baseClass)
-    throws NotCompliantMBeanException {
-        Class<? super T> current = baseClass;
-        Class<? super T> mbeanInterface = null;
-        while (current != null) {
-            mbeanInterface =
-                findMBeanInterface(current, current.getName());
-            if (mbeanInterface != null) break;
-            current = current.getSuperclass();
-        }
-        if (mbeanInterface != null) {
-            return mbeanInterface;
-        } else {
+        throws NotCompliantMBeanException {
+            Class<? super T> current = baseClass;
+            Class<? super T> mbeanInterface = null;
+            while (current != null) {
+                mbeanInterface =
+                    findMBeanInterface(current, current.getName());
+                if (mbeanInterface != null) break;
+                current = current.getSuperclass();
+            }
+                if (mbeanInterface != null) {
+                    return mbeanInterface;
+            } else {
             final String msg =
                 "Class " + baseClass.getName() +
                 " is not a JMX compliant Standard MBean";
@@ -507,8 +528,11 @@
         }
         Class<?>[] interfaces = c.getInterfaces();
         for (int i = 0;i < interfaces.length; i++) {
-            if (interfaces[i].getName().equals(clMBeanName))
+            if (interfaces[i].getName().equals(clMBeanName) &&
+                (Modifier.isPublic(interfaces[i].getModifiers()) ||
+                 ALLOW_NONPUBLIC_MBEAN)) {
                 return Util.cast(interfaces[i]);
+            }
         }
 
         return null;
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanAnalyzer.java	Thu Jul 11 11:43:23 2013 -0700
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanAnalyzer.java	Thu Jul 11 21:11:03 2013 +0200
@@ -28,6 +28,8 @@
 import static com.sun.jmx.mbeanserver.Util.*;
 
 import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.security.AccessController;
 import java.util.Arrays;
 import java.util.Comparator;
 import java.util.List;
@@ -50,7 +52,6 @@
  * @since 1.6
  */
 class MBeanAnalyzer<M> {
-
     static interface MBeanVisitor<M> {
         public void visitAttribute(String attributeName,
                 M getter,
@@ -107,6 +108,10 @@
         if (!mbeanType.isInterface()) {
             throw new NotCompliantMBeanException("Not an interface: " +
                     mbeanType.getName());
+        } else if (!Modifier.isPublic(mbeanType.getModifiers()) &&
+                   !Introspector.ALLOW_NONPUBLIC_MBEAN) {
+            throw new NotCompliantMBeanException("Interface is not public: " +
+                mbeanType.getName());
         }
 
         try {
--- a/jdk/src/share/classes/javax/management/JMX.java	Thu Jul 11 11:43:23 2013 -0700
+++ b/jdk/src/share/classes/javax/management/JMX.java	Thu Jul 11 21:11:03 2013 +0200
@@ -160,6 +160,10 @@
      * example, then the return type is {@code MyMBean}.
      *
      * @return the new proxy instance.
+     *
+     * @throws IllegalArgumentException if {@code interfaceClass} is not
+     * a <a href="package-summary.html#mgIface">compliant MBean
+     * interface</a>
      */
     public static <T> T newMBeanProxy(MBeanServerConnection connection,
                                       ObjectName objectName,
@@ -200,6 +204,10 @@
      * example, then the return type is {@code MyMBean}.
      *
      * @return the new proxy instance.
+     *
+     * @throws IllegalArgumentException if {@code interfaceClass} is not
+     * a <a href="package-summary.html#mgIface">compliant MBean
+     * interface</a>
      */
     public static <T> T newMBeanProxy(MBeanServerConnection connection,
                                       ObjectName objectName,
@@ -298,6 +306,9 @@
      * example, then the return type is {@code MyMXBean}.
      *
      * @return the new proxy instance.
+     *
+     * @throws IllegalArgumentException if {@code interfaceClass} is not
+     * a {@link javax.management.MXBean compliant MXBean interface}
      */
     public static <T> T newMXBeanProxy(MBeanServerConnection connection,
                                        ObjectName objectName,
@@ -338,6 +349,9 @@
      * example, then the return type is {@code MyMXBean}.
      *
      * @return the new proxy instance.
+     *
+     * @throws IllegalArgumentException if {@code interfaceClass} is not
+     * a {@link javax.management.MXBean compliant MXBean interface}
      */
     public static <T> T newMXBeanProxy(MBeanServerConnection connection,
                                        ObjectName objectName,
@@ -348,21 +362,25 @@
 
     /**
      * <p>Test whether an interface is an MXBean interface.
-     * An interface is an MXBean interface if it is annotated
-     * {@link MXBean &#64;MXBean} or {@code @MXBean(true)}
+     * An interface is an MXBean interface if it is public,
+     * annotated {@link MXBean &#64;MXBean} or {@code @MXBean(true)}
      * or if it does not have an {@code @MXBean} annotation
      * and its name ends with "{@code MXBean}".</p>
      *
      * @param interfaceClass The candidate interface.
      *
-     * @return true if {@code interfaceClass} is an interface and
-     * meets the conditions described.
+     * @return true if {@code interfaceClass} is a
+     * {@link javax.management.MXBean compliant MXBean interface}
      *
      * @throws NullPointerException if {@code interfaceClass} is null.
      */
     public static boolean isMXBeanInterface(Class<?> interfaceClass) {
         if (!interfaceClass.isInterface())
             return false;
+        if (!Modifier.isPublic(interfaceClass.getModifiers()) &&
+            !Introspector.ALLOW_NONPUBLIC_MBEAN) {
+            return false;
+        }
         MXBean a = interfaceClass.getAnnotation(MXBean.class);
         if (a != null)
             return a.value();
@@ -389,9 +407,6 @@
                                      boolean notificationEmitter,
                                      boolean isMXBean) {
 
-        if (System.getSecurityManager() != null) {
-            checkProxyInterface(interfaceClass);
-        }
         try {
             if (isMXBean) {
                 // Check interface for MXBean compliance
@@ -419,17 +434,4 @@
                 handler);
         return interfaceClass.cast(proxy);
     }
-
-    /**
-     * Checks for the M(X)Bean proxy interface being public and not restricted
-     * @param interfaceClass MBean proxy interface
-     * @throws SecurityException when the proxy interface comes from a restricted
-     *                           package or is not public
-     */
-    private static void checkProxyInterface(Class<?> interfaceClass) {
-        if (!Modifier.isPublic(interfaceClass.getModifiers())) {
-            throw new SecurityException("mbean proxy interface non-public");
-        }
-        ReflectUtil.checkPackageAccess(interfaceClass);
-    }
 }
--- a/jdk/src/share/classes/javax/management/MBeanServerInvocationHandler.java	Thu Jul 11 11:43:23 2013 -0700
+++ b/jdk/src/share/classes/javax/management/MBeanServerInvocationHandler.java	Thu Jul 11 21:11:03 2013 +0200
@@ -225,7 +225,7 @@
      *
      * @return the new proxy instance.
      *
-     * @see JMX#newMBeanProxy(MBeanServerConnection, ObjectName, Class)
+     * @see JMX#newMBeanProxy(MBeanServerConnection, ObjectName, Class, boolean)
      */
     public static <T> T newProxyInstance(MBeanServerConnection connection,
                                          ObjectName objectName,
--- a/jdk/src/share/classes/javax/management/MXBean.java	Thu Jul 11 11:43:23 2013 -0700
+++ b/jdk/src/share/classes/javax/management/MXBean.java	Thu Jul 11 21:11:03 2013 +0200
@@ -54,9 +54,9 @@
 /**
     <p>Annotation to mark an interface explicitly as being an MXBean
     interface, or as not being an MXBean interface.  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:</p>
+    interface is an MXBean interface if it is public and its name ends
+    with {@code MXBean}, as in {@code SomethingMXBean}.  The following
+    interfaces are MXBean interfaces:</p>
 
     <pre>
     public interface WhatsitMXBean {}
@@ -71,6 +71,8 @@
     <p>The following interfaces are not MXBean interfaces:</p>
 
     <pre>
+    interface NonPublicInterfaceNotMXBean{}
+
     public interface Whatsit3Interface{}
 
     &#64;MXBean(false)
--- a/jdk/src/share/classes/javax/management/package.html	Thu Jul 11 11:43:23 2013 -0700
+++ b/jdk/src/share/classes/javax/management/package.html	Thu Jul 11 21:11:03 2013 +0200
@@ -53,8 +53,8 @@
 
         <p>The fundamental notion of the JMX API is the <em>MBean</em>.
             An MBean is a named <em>managed object</em> representing a
-            resource.  It has a <em>management interface</em> consisting
-        of:</p>
+            resource.  It has a <em id="mgIface">management interface</em>
+            which must be <em>public</em> and consist of:</p>
 
         <ul>
             <li>named and typed attributes that can be read and/or
--- a/jdk/src/share/classes/sun/management/ManagementFactoryHelper.java	Thu Jul 11 11:43:23 2013 -0700
+++ b/jdk/src/share/classes/sun/management/ManagementFactoryHelper.java	Thu Jul 11 21:11:03 2013 +0200
@@ -147,18 +147,20 @@
         }
     }
 
-    // The logging MXBean object is an instance of
-    // PlatformLoggingMXBean and java.util.logging.LoggingMXBean
-    // but it can't directly implement two MXBean interfaces
-    // as a compliant MXBean implements exactly one MXBean interface,
-    // or if it implements one interface that is a subinterface of
-    // all the others; otherwise, it is a non-compliant MXBean
-    // and MBeanServer will throw NotCompliantMBeanException.
-    // See the Definition of an MXBean section in javax.management.MXBean spec.
-    //
-    // To create a compliant logging MXBean, define a LoggingMXBean interface
-    // that extend PlatformLoggingMXBean and j.u.l.LoggingMXBean
-    interface LoggingMXBean
+    /**
+     * The logging MXBean object is an instance of
+     * PlatformLoggingMXBean and java.util.logging.LoggingMXBean
+     * but it can't directly implement two MXBean interfaces
+     * as a compliant MXBean implements exactly one MXBean interface,
+     * or if it implements one interface that is a subinterface of
+     * all the others; otherwise, it is a non-compliant MXBean
+     * and MBeanServer will throw NotCompliantMBeanException.
+     * See the Definition of an MXBean section in javax.management.MXBean spec.
+     *
+     * To create a compliant logging MXBean, define a LoggingMXBean interface
+     * that extend PlatformLoggingMXBean and j.u.l.LoggingMXBean
+    */
+    public interface LoggingMXBean
         extends PlatformLoggingMXBean, java.util.logging.LoggingMXBean {
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/MBeanServer/MBeanFallbackTest.java	Thu Jul 11 21:11:03 2013 +0200
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2013, 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.
+ *
+ * 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.
+ */
+
+import javax.management.MBeanServer;
+import javax.management.MBeanServerFactory;
+import javax.management.NotCompliantMBeanException;
+import javax.management.ObjectName;
+
+/*
+ * @test
+ * @bug 8010285
+ * @summary Test fallback for private MBean interfaces.
+ *          It needs to be a separate class because the "jdk.jmx.mbeans.allowNonPublic"
+ *          system property must be set before c.s.j.m.MBeanAnalyzer has been loaded.
+ * @author Jaroslav Bachorik
+ * @run clean MBeanFallbackTest
+ * @run build MBeanFallbackTest
+ * @run main MBeanFallbackTest
+ */
+public class MBeanFallbackTest {
+    private static interface PrivateMBean {
+        public int[] getInts();
+    }
+
+    public static class Private implements PrivateMBean {
+        public int[] getInts() {
+            return new int[]{1,2,3};
+        }
+    }
+
+    private static int failures = 0;
+
+    public static void main(String[] args) throws Exception {
+        System.setProperty("jdk.jmx.mbeans.allowNonPublic", "true");
+        testPrivate(PrivateMBean.class, new Private());
+
+        if (failures == 0)
+            System.out.println("Test passed");
+        else
+            throw new Exception("TEST FAILURES: " + failures);
+    }
+
+    private static void fail(String msg) {
+        failures++;
+        System.out.println("FAIL: " + msg);
+    }
+
+    private static void success(String msg) {
+        System.out.println("OK: " + msg);
+    }
+
+    private static void testPrivate(Class<?> iface, Object bean) throws Exception {
+        try {
+            System.out.println("Registering a private MBean " +
+                                iface.getName() + " ...");
+
+            MBeanServer mbs = MBeanServerFactory.newMBeanServer();
+            ObjectName on = new ObjectName("test:type=Compliant");
+
+            mbs.registerMBean(bean, on);
+            success("Registered a private MBean - " + iface.getName());
+        } catch (Exception e) {
+            Throwable t = e;
+            while (t != null && !(t instanceof NotCompliantMBeanException)) {
+                t = t.getCause();
+            }
+            if (t != null) {
+                fail("MBean not registered");
+            } else {
+                throw e;
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/MBeanServer/MBeanTest.java	Thu Jul 11 21:11:03 2013 +0200
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2013, 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.
+ *
+ * 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.
+ */
+
+import javax.management.MBeanServer;
+import javax.management.MBeanServerFactory;
+import javax.management.NotCompliantMBeanException;
+import javax.management.ObjectName;
+
+/*
+ * @test
+ * @bug 8010285
+ * @summary General MBean test.
+ * @author Jaroslav Bachorik
+ * @run clean MBeanTest
+ * @run build MBeanTest
+ * @run main MBeanTest
+ */
+public class MBeanTest {
+    private static interface PrivateMBean {
+        public int[] getInts();
+    }
+
+    public static class Private implements PrivateMBean {
+        public int[] getInts() {
+            return new int[]{1,2,3};
+        }
+    }
+
+    public static interface NonCompliantMBean {
+        public boolean getInt();
+        public boolean isInt();
+        public void setInt(int a);
+        public void setInt(long b);
+    }
+
+    public static class NonCompliant implements NonCompliantMBean {
+        public boolean getInt() {
+            return false;
+        }
+
+        public boolean isInt() {
+            return true;
+        }
+
+        public void setInt(int a) {
+        }
+
+        public void setInt(long b) {
+        }
+    }
+
+    public static interface CompliantMBean {
+        public boolean isFlag();
+        public int getInt();
+        public void setInt(int value);
+    }
+
+    public static class Compliant implements CompliantMBean {
+        public boolean isFlag() {
+            return false;
+        }
+
+        public int getInt() {
+            return 1;
+        }
+
+        public void setInt(int value) {
+        }
+    }
+
+    private static int failures = 0;
+
+    public static void main(String[] args) throws Exception {
+        testCompliant(CompliantMBean.class, new Compliant());
+        testNonCompliant(PrivateMBean.class, new Private());
+        testNonCompliant(NonCompliantMBean.class, new NonCompliant());
+
+        if (failures == 0)
+            System.out.println("Test passed");
+        else
+            throw new Exception("TEST FAILURES: " + failures);
+    }
+
+    private static void fail(String msg) {
+        failures++;
+        System.out.println("FAIL: " + msg);
+    }
+
+    private static void success(String msg) {
+        System.out.println("OK: " + msg);
+    }
+
+    private static void testNonCompliant(Class<?> iface, Object bean) throws Exception {
+        try {
+            System.out.println("Registering a non-compliant MBean " +
+                                iface.getName() + " ...");
+
+            MBeanServer mbs = MBeanServerFactory.newMBeanServer();
+            ObjectName on = new ObjectName("test:type=NonCompliant");
+
+            mbs.registerMBean(bean, on);
+
+            fail("Registered a non-compliant MBean - " + iface.getName());
+        } catch (Exception e) {
+            Throwable t = e;
+            while (t != null && !(t instanceof NotCompliantMBeanException)) {
+                t = t.getCause();
+            }
+            if (t != null) {
+                success("MBean not registered");
+            } else {
+                throw e;
+            }
+        }
+    }
+    private static void testCompliant(Class<?> iface, Object bean) throws Exception {
+        try {
+            System.out.println("Registering a compliant MBean " +
+                                iface.getName() + " ...");
+
+            MBeanServer mbs = MBeanServerFactory.newMBeanServer();
+            ObjectName on = new ObjectName("test:type=Compliant");
+
+            mbs.registerMBean(bean, on);
+            success("Registered a compliant MBean - " + iface.getName());
+        } catch (Exception e) {
+            Throwable t = e;
+            while (t != null && !(t instanceof NotCompliantMBeanException)) {
+                t = t.getCause();
+            }
+            if (t != null) {
+                fail("MBean not registered");
+            } else {
+                throw e;
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/mxbean/MXBeanFallbackTest.java	Thu Jul 11 21:11:03 2013 +0200
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2005, 2013, 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 8010285
+ * @summary Test for the private MXBean interface fallback.
+ *          It needs to be a separate class because the "jdk.jmx.mbeans.allowNonPublic"
+ *          system property must be set before c.s.j.m.MBeanAnalyzer has been loaded.
+ * @author Jaroslav Bachorik
+ * @run clean MXBeanFallbackTest
+ * @run build MXBeanFallbackTest
+ * @run main MXBeanFallbackTest
+ */
+
+import javax.management.MBeanServer;
+import javax.management.MBeanServerFactory;
+import javax.management.NotCompliantMBeanException;
+import javax.management.ObjectName;
+
+public class MXBeanFallbackTest {
+    public static void main(String[] args) throws Exception {
+        System.setProperty("jdk.jmx.mbeans.allowNonPublic", "true");
+        testPrivateMXBean("Private", new Private());
+
+        if (failures == 0)
+            System.out.println("Test passed");
+        else
+            throw new Exception("TEST FAILURES: " + failures);
+    }
+
+    private static int failures = 0;
+
+    private static interface PrivateMXBean {
+        public int[] getInts();
+    }
+
+    public static class Private implements PrivateMXBean {
+        public int[] getInts() {
+            return new int[]{1,2,3};
+        }
+    }
+
+    private static void testPrivateMXBean(String type, Object bean) throws Exception {
+        System.out.println(type + " MXBean test...");
+        MBeanServer mbs = MBeanServerFactory.newMBeanServer();
+        ObjectName on = new ObjectName("test:type=" + type);
+        try {
+            mbs.registerMBean(bean, on);
+            success("Private MXBean registered");
+        } catch (NotCompliantMBeanException e) {
+            failure("Failed to register the private MXBean - " +
+                     bean.getClass().getInterfaces()[0].getName());
+        }
+    }
+
+    private static void success(String what) {
+        System.out.println("OK: " + what);
+    }
+
+    private static void failure(String what) {
+        System.out.println("FAILED: " + what);
+        failures++;
+    }
+}
--- a/jdk/test/javax/management/mxbean/MXBeanTest.java	Thu Jul 11 11:43:23 2013 -0700
+++ b/jdk/test/javax/management/mxbean/MXBeanTest.java	Thu Jul 11 21:11:03 2013 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013, 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
@@ -23,9 +23,10 @@
 
 /*
  * @test
- * @bug 6175517 6278707 6318827 6305746 6392303 6600709
+ * @bug 6175517 6278707 6318827 6305746 6392303 6600709 8010285
  * @summary General MXBean test.
  * @author Eamonn McManus
+ * @author Jaroslav Bachorik
  * @run clean MXBeanTest MerlinMXBean TigerMXBean
  * @run build MXBeanTest MerlinMXBean TigerMXBean
  * @run main MXBeanTest
@@ -51,6 +52,7 @@
 import javax.management.MBeanServerConnection;
 import javax.management.MBeanServerFactory;
 import javax.management.MBeanServerInvocationHandler;
+import javax.management.NotCompliantMBeanException;
 import javax.management.ObjectName;
 import javax.management.StandardMBean;
 import javax.management.openmbean.ArrayType;
@@ -75,6 +77,8 @@
         testExplicitMXBean();
         testSubclassMXBean();
         testIndirectMXBean();
+        testNonCompliantMXBean("Private", new Private());
+        testNonCompliantMXBean("NonCompliant", new NonCompliant());
 
         if (failures == 0)
             System.out.println("Test passed");
@@ -84,6 +88,39 @@
 
     private static int failures = 0;
 
+    private static interface PrivateMXBean {
+        public int[] getInts();
+    }
+
+    public static class Private implements PrivateMXBean {
+        public int[] getInts() {
+            return new int[]{1,2,3};
+        }
+    }
+
+    public static interface NonCompliantMXBean {
+        public boolean getInt();
+        public boolean isInt();
+        public void setInt(int a);
+        public void setInt(long b);
+    }
+
+    public static class NonCompliant implements NonCompliantMXBean {
+        public boolean getInt() {
+            return false;
+        }
+
+        public boolean isInt() {
+            return true;
+        }
+
+        public void setInt(int a) {
+        }
+
+        public void setInt(long b) {
+        }
+    }
+
     public static interface ExplicitMXBean {
         public int[] getInts();
     }
@@ -110,6 +147,19 @@
         }
     }
 
+    private static void testNonCompliantMXBean(String type, Object bean) throws Exception {
+        System.out.println(type + " MXBean test...");
+        MBeanServer mbs = MBeanServerFactory.newMBeanServer();
+        ObjectName on = new ObjectName("test:type=" + type);
+        try {
+            mbs.registerMBean(bean, on);
+            failure(bean.getClass().getInterfaces()[0].getName() + " is not a compliant "
+                + "MXBean interface");
+        } catch (NotCompliantMBeanException e) {
+            success("Non-compliant MXBean not registered");
+        }
+    }
+
     private static void testExplicitMXBean() throws Exception {
         System.out.println("Explicit MXBean test...");
         MBeanServer mbs = MBeanServerFactory.newMBeanServer();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/proxy/JMXProxyFallbackTest.java	Thu Jul 11 21:11:03 2013 +0200
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2013, 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.
+ *
+ * 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.
+ */
+
+import javax.management.JMX;
+import javax.management.MBeanServer;
+import javax.management.MBeanServerFactory;
+import javax.management.NotCompliantMBeanException;
+import javax.management.ObjectName;
+
+/*
+ * @test
+ * @bug 8010285
+ * @summary Tests the fallback for creating JMX proxies for private interfaces
+ *          It needs to be a separate class because the "jdk.jmx.mbeans.allowNonPublic"
+ *          system property must be set before c.s.j.m.MBeanAnalyzer has been loaded.
+ * @author Jaroslav Bachorik
+ * @run clean JMXProxyFallbackTest
+ * @run build JMXProxyFallbackTest
+ * @run main JMXProxyFallbackTest
+ */
+public class JMXProxyFallbackTest {
+    private static interface PrivateMBean {
+        public int[] getInts();
+    }
+
+    private static interface PrivateMXBean {
+        public int[] getInts();
+    }
+
+    public static class Private implements PrivateMXBean, PrivateMBean {
+        public int[] getInts() {
+            return new int[]{1,2,3};
+        }
+    }
+
+    private static int failures = 0;
+
+    public static void main(String[] args) throws Exception {
+        System.setProperty("jdk.jmx.mbeans.allowNonPublic", "true");
+        testPrivate(PrivateMBean.class);
+        testPrivate(PrivateMXBean.class);
+
+        if (failures == 0)
+            System.out.println("Test passed");
+        else
+            throw new Exception("TEST FAILURES: " + failures);
+    }
+
+    private static void fail(String msg) {
+        failures++;
+        System.out.println("FAIL: " + msg);
+    }
+
+    private static void success(String msg) {
+        System.out.println("OK: " + msg);
+    }
+
+    private static void testPrivate(Class<?> iface) throws Exception {
+        try {
+            System.out.println("Creating a proxy for private M(X)Bean " +
+                                iface.getName() + " ...");
+
+            MBeanServer mbs = MBeanServerFactory.newMBeanServer();
+            ObjectName on = new ObjectName("test:type=Proxy");
+
+            JMX.newMBeanProxy(mbs, on, iface);
+            success("Created a proxy for private M(X)Bean - " + iface.getName());
+        } catch (Exception e) {
+            Throwable t = e;
+            while (t != null && !(t instanceof NotCompliantMBeanException)) {
+                t = t.getCause();
+            }
+            if (t != null) {
+                fail("Proxy not created");
+            } else {
+                throw e;
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/proxy/JMXProxyTest.java	Thu Jul 11 21:11:03 2013 +0200
@@ -0,0 +1,191 @@
+/*
+ * Copyright (c) 2013, 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.
+ *
+ * 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.
+ */
+
+import javax.management.JMX;
+import javax.management.MBeanServer;
+import javax.management.MBeanServerFactory;
+import javax.management.NotCompliantMBeanException;
+import javax.management.ObjectName;
+
+/*
+ * @test
+ * @bug 8010285
+ * @summary Tests that javax.management.JMX creates proxies only for the
+ *          compliant MBeans/MXBeans
+ * @author Jaroslav Bachorik
+ * @run clean JMXProxyTest
+ * @run build JMXProxyTest
+ * @run main JMXProxyTest
+ */
+public class JMXProxyTest {
+    private static interface PrivateMBean {
+        public int[] getInts();
+    }
+
+    private static interface PrivateMXBean {
+        public int[] getInts();
+    }
+
+    public static class Private implements PrivateMXBean, PrivateMBean {
+        public int[] getInts() {
+            return new int[]{1,2,3};
+        }
+    }
+
+    public static interface NonCompliantMBean {
+        public boolean getInt();
+        public boolean isInt();
+        public void setInt(int a);
+        public void setInt(long b);
+    }
+
+    public static interface NonCompliantMXBean {
+        public boolean getInt();
+        public boolean isInt();
+        public void setInt(int a);
+        public void setInt(long b);
+    }
+
+    public static class NonCompliant implements NonCompliantMXBean, NonCompliantMBean {
+        public boolean getInt() {
+            return false;
+        }
+
+        public boolean isInt() {
+            return true;
+        }
+
+        public void setInt(int a) {
+        }
+
+        public void setInt(long b) {
+        }
+    }
+
+    public static interface CompliantMBean {
+        public boolean isFlag();
+        public int getInt();
+        public void setInt(int value);
+    }
+
+    public static interface CompliantMXBean {
+        public boolean isFlag();
+        public int getInt();
+        public void setInt(int value);
+    }
+
+    public static class Compliant implements CompliantMXBean, CompliantMBean {
+        public boolean isFlag() {
+            return false;
+        }
+
+        public int getInt() {
+            return 1;
+        }
+
+        public void setInt(int value) {
+        }
+    }
+
+    private static int failures = 0;
+
+    public static void main(String[] args) throws Exception {
+        testCompliant(CompliantMBean.class, false);
+        testCompliant(CompliantMXBean.class, true);
+        testNonCompliant(PrivateMBean.class, false);
+        testNonCompliant(PrivateMXBean.class, true);
+        testNonCompliant(NonCompliantMBean.class, false);
+        testNonCompliant(NonCompliantMXBean.class, true);
+
+        if (failures == 0)
+            System.out.println("Test passed");
+        else
+            throw new Exception("TEST FAILURES: " + failures);
+    }
+
+    private static void fail(String msg) {
+        failures++;
+        System.out.println("FAIL: " + msg);
+    }
+
+    private static void success(String msg) {
+        System.out.println("OK: " + msg);
+    }
+
+    private static void testNonCompliant(Class<?> iface, boolean isMx) throws Exception {
+        try {
+            System.out.println("Creating a proxy for non-compliant " +
+                               (isMx ? "MXBean" : "MBean") + " " +
+                               iface.getName() + " ...");
+
+            MBeanServer mbs = MBeanServerFactory.newMBeanServer();
+            ObjectName on = new ObjectName("test:type=Proxy");
+
+            if (isMx) {
+                JMX.newMXBeanProxy(mbs, on, iface);
+            } else {
+                JMX.newMBeanProxy(mbs, on, iface);
+            }
+            fail("Created a proxy for non-compliant " +
+                 (isMx ? "MXBean" : "MBean") + " - " + iface.getName());
+        } catch (Exception e) {
+            Throwable t = e;
+            while (t != null && !(t instanceof NotCompliantMBeanException)) {
+                t = t.getCause();
+            }
+            if (t != null) {
+                success("Proxy not created");
+            } else {
+                throw e;
+            }
+        }
+    }
+    private static void testCompliant(Class<?> iface, boolean isMx) throws Exception {
+        try {
+            System.out.println("Creating a proxy for compliant " +
+                               (isMx ? "MXBean" : "MBean") + " " +
+                               iface.getName() + " ...");
+
+            MBeanServer mbs = MBeanServerFactory.newMBeanServer();
+            ObjectName on = new ObjectName("test:type=Proxy");
+
+            if (isMx) {
+                JMX.newMXBeanProxy(mbs, on, iface);
+            } else {
+                JMX.newMBeanProxy(mbs, on, iface);
+            }
+            success("Created a proxy for compliant " +
+                    (isMx ? "MXBean" : "MBean") + " - " + iface.getName());
+        } catch (Exception e) {
+            Throwable t = e;
+            while (t != null && !(t instanceof NotCompliantMBeanException)) {
+                t = t.getCause();
+            }
+            if (t != null) {
+                fail("Proxy not created");
+            } else {
+                throw e;
+            }
+        }
+    }
+}