8023529: OpenMBeanInfoSupport.equals/hashCode throw NPE
authorsjiang
Thu, 12 Sep 2013 09:41:28 +0200
changeset 19845 6f149007b02c
parent 19844 c124c3d601ba
child 19846 ee72cd8a1085
8023529: OpenMBeanInfoSupport.equals/hashCode throw NPE Reviewed-by: dholmes, dfuchs
jdk/src/share/classes/javax/management/openmbean/OpenMBeanInfoSupport.java
jdk/test/javax/management/openmbean/OpenMBeanInfoEqualsNPETest.java
jdk/test/javax/management/openmbean/OpenMBeanInfoHashCodeNPETest.java
--- a/jdk/src/share/classes/javax/management/openmbean/OpenMBeanInfoSupport.java	Wed Sep 11 11:25:14 2013 -0700
+++ b/jdk/src/share/classes/javax/management/openmbean/OpenMBeanInfoSupport.java	Thu Sep 12 09:41:28 2013 +0200
@@ -31,6 +31,7 @@
 //
 import java.util.Arrays;
 import java.util.HashSet;
+import java.util.Objects;
 
 import javax.management.Descriptor;
 import javax.management.MBeanAttributeInfo;
@@ -269,8 +270,9 @@
         //
 
         // their MBean className should be equal
-        if ( ! this.getClassName().equals(other.getClassName()) )
+        if (!Objects.equals(this.getClassName(), other.getClassName())) {
             return false;
+        }
 
         // their infos on attributes should be equal (order not
         // significant => equality between sets, not arrays or lists)
@@ -342,7 +344,9 @@
         //
         if (myHashCode == null) {
             int value = 0;
-            value += this.getClassName().hashCode();
+            if (this.getClassName() != null) {
+                value += this.getClassName().hashCode();
+            }
             value += arraySetHash(this.getAttributes());
             value += arraySetHash(this.getConstructors());
             value += arraySetHash(this.getOperations());
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/openmbean/OpenMBeanInfoEqualsNPETest.java	Thu Sep 12 09:41:28 2013 +0200
@@ -0,0 +1,196 @@
+/*
+ * 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.MBeanNotificationInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.modelmbean.DescriptorSupport;
+import javax.management.openmbean.OpenMBeanAttributeInfo;
+import javax.management.openmbean.OpenMBeanAttributeInfoSupport;
+import javax.management.openmbean.OpenMBeanConstructorInfo;
+import javax.management.openmbean.OpenMBeanConstructorInfoSupport;
+import javax.management.openmbean.OpenMBeanInfo;
+import javax.management.openmbean.OpenMBeanInfoSupport;
+import javax.management.openmbean.OpenMBeanOperationInfo;
+import javax.management.openmbean.OpenMBeanOperationInfoSupport;
+import javax.management.openmbean.OpenMBeanParameterInfo;
+import javax.management.openmbean.OpenMBeanParameterInfoSupport;
+import javax.management.openmbean.SimpleType;
+
+/*
+ * @test
+ * @bug 8023529
+ * @summary Test that OpenMBean*Info.equals do not throw NPE
+ * @author Shanliang JIANG
+ * @run clean OpenMBeanInfoEqualsNPETest
+ * @run build OpenMBeanInfoEqualsNPETest
+ * @run main OpenMBeanInfoEqualsNPETest
+ */
+public class OpenMBeanInfoEqualsNPETest {
+    private static int failed = 0;
+
+    public static void main(String[] args) throws Exception {
+        System.out.println("---OpenMBeanInfoEqualsNPETest-main ...");
+
+        // ----
+        System.out.println("\n---Testing on OpenMBeanAttributeInfoSupport...");
+        OpenMBeanAttributeInfo openMBeanAttributeInfo0 = new OpenMBeanAttributeInfoSupport(
+                "name", "description", SimpleType.INTEGER, true, true, false, 1, new Integer[]{1, 2, 3});
+        OpenMBeanAttributeInfo openMBeanAttributeInfo = new OpenMBeanAttributeInfoSupport(
+                "name", "description", SimpleType.INTEGER, true, true, false, null, new Integer[]{1, 2, 3});
+        test(openMBeanAttributeInfo0, openMBeanAttributeInfo, "defaultValue");
+
+        openMBeanAttributeInfo = new OpenMBeanAttributeInfoSupport(
+                "name", "description", SimpleType.INTEGER, true, true, false, 1, null);
+        test(openMBeanAttributeInfo0, openMBeanAttributeInfo, "legalValues");
+
+        // ----
+        System.out.println("\n---Testing on OpenMBeanConstructorInfoSupport...");
+        OpenMBeanConstructorInfo openMBeanConstructorInfo0 = new OpenMBeanConstructorInfoSupport(
+                "name", "description", new OpenMBeanParameterInfo[]{}, new DescriptorSupport());
+        OpenMBeanConstructorInfo openMBeanConstructorInfo;
+
+        openMBeanConstructorInfo = new OpenMBeanConstructorInfoSupport(
+                "name", "description", null, new DescriptorSupport());
+        test(openMBeanConstructorInfo0, openMBeanConstructorInfo, "sigs");
+
+        openMBeanConstructorInfo = new OpenMBeanConstructorInfoSupport(
+                "name", "description", new OpenMBeanParameterInfo[]{}, null);
+        test(openMBeanConstructorInfo0, openMBeanConstructorInfo, "Descriptor");
+
+        // ----
+        System.out.println("\n---Testing on OpenMBeanOperationInfoSupport...");
+        OpenMBeanOperationInfo openMBeanOperationInfo0 = new OpenMBeanOperationInfoSupport(
+                "name", "description", new OpenMBeanParameterInfo[]{},  SimpleType.INTEGER, 1, new DescriptorSupport());
+        OpenMBeanOperationInfo openMBeanOperationInfo;
+
+        openMBeanOperationInfo = new OpenMBeanOperationInfoSupport(
+                "name", "description", null,  SimpleType.INTEGER, 1, new DescriptorSupport());
+        test(openMBeanOperationInfo0, openMBeanOperationInfo, "sigs");
+
+        openMBeanOperationInfo = new OpenMBeanOperationInfoSupport(
+                "name", "description", new OpenMBeanParameterInfo[]{},  SimpleType.INTEGER, MBeanOperationInfo.UNKNOWN, null);
+        test(openMBeanOperationInfo0, openMBeanOperationInfo, "Descriptor");
+
+        // ----
+        System.out.println("\n---Testing on OpenMBeanParameterInfoSupport 1...");
+        OpenMBeanParameterInfo openMBeanParameterInfo0 = new OpenMBeanParameterInfoSupport(
+                "name", "description", SimpleType.INTEGER, 0, -1, 1);
+        OpenMBeanParameterInfo openMBeanParameterInfo;
+
+        openMBeanParameterInfo = new OpenMBeanParameterInfoSupport(
+                "name", "description", SimpleType.INTEGER, null, -1, 1);
+        test(openMBeanParameterInfo0, openMBeanParameterInfo, "default value");
+
+        openMBeanParameterInfo = new OpenMBeanParameterInfoSupport(
+                "name", "description", SimpleType.INTEGER, 0, null, 1);
+        test(openMBeanParameterInfo0, openMBeanParameterInfo, "min value");
+
+        openMBeanParameterInfo = new OpenMBeanParameterInfoSupport(
+                "name", "description", SimpleType.INTEGER, 0, -1, null);
+        test(openMBeanParameterInfo0, openMBeanParameterInfo, "max value");
+
+        // ----
+        System.out.println("\n---Testing on OpenMBeanParameterInfoSupport 2...");
+        openMBeanParameterInfo0 = new OpenMBeanParameterInfoSupport(
+                "name", "description", SimpleType.INTEGER, 1, new Integer[]{-1, 1, 2});
+
+        openMBeanParameterInfo = new OpenMBeanParameterInfoSupport(
+                "name", "description", SimpleType.INTEGER, null, new Integer[]{-1, 1, 2});
+        test(openMBeanParameterInfo0, openMBeanParameterInfo, "default value");
+
+        openMBeanParameterInfo = new OpenMBeanParameterInfoSupport(
+                "name", "description", SimpleType.INTEGER, 1, null);
+        test(openMBeanParameterInfo0, openMBeanParameterInfo, "legal values");
+
+        // ----
+        System.out.println("\n---Testing on OpenMBeanInfoSupport...");
+        String className = "toto";
+        String description = "titi";
+        OpenMBeanAttributeInfo[] attrInfos = new OpenMBeanAttributeInfo[]{};
+        OpenMBeanConstructorInfo[] constrInfos = new OpenMBeanConstructorInfo[]{};
+        OpenMBeanOperationInfo[] operaInfos = new OpenMBeanOperationInfo[]{};
+        MBeanNotificationInfo[] notifInfos = new MBeanNotificationInfo[]{};
+
+        OpenMBeanInfo ominfo0 = new OpenMBeanInfoSupport("toto", description, attrInfos, constrInfos, operaInfos, notifInfos);
+        OpenMBeanInfo ominfo = new OpenMBeanInfoSupport(null, description, attrInfos, constrInfos, operaInfos, notifInfos);
+        test(ominfo0, ominfo, "class name");
+
+        ominfo = new OpenMBeanInfoSupport(className, null, attrInfos, constrInfos, operaInfos, notifInfos);
+        test(ominfo0, ominfo, "description");
+
+        ominfo = new OpenMBeanInfoSupport(className, description, null, constrInfos, operaInfos, notifInfos);
+        test(ominfo0, ominfo, "attrInfos");
+
+        ominfo = new OpenMBeanInfoSupport(className, description, attrInfos, null, operaInfos, notifInfos);
+        test(ominfo0, ominfo, "constructor infos");
+
+        ominfo = new OpenMBeanInfoSupport(className, description, attrInfos, constrInfos, null, notifInfos);
+        test(ominfo0, ominfo, "operation infos");
+
+        ominfo = new OpenMBeanInfoSupport(className, description, attrInfos, constrInfos, operaInfos, null);
+        test(ominfo0, ominfo, "notif infos");
+
+        if (failed > 0) {
+            throw new RuntimeException("Test failed: "+failed);
+        } else {
+            System.out.println("---Test: PASSED");
+        }
+    }
+
+    private static void test(Object obj1, Object obj2, String param) {
+        try {
+            obj1.equals(obj2);
+            System.out.println("OK-1: "+obj1.getClass().getSimpleName()+
+                    ".equals worked with a null field: "+param);
+        } catch (NullPointerException npe) {
+            System.out.println("--->KO-1!!! "+obj1.getClass().getSimpleName()+
+                    ".equals got NPE with a null field: "+param);
+            npe.printStackTrace();
+            failed++;
+        }
+
+        try {
+            obj2.equals(obj1);
+            System.out.println("OK-2: "+obj2.getClass().getSimpleName()+
+                    ".equals worked with a null field: "+param);
+        } catch (NullPointerException npe) {
+            System.out.println("--->KO-2!!! "+obj2.getClass().getSimpleName()+
+                    ".equals got NPE with a null field: "+param);
+            npe.printStackTrace();
+            failed++;
+        }
+
+        try {
+            obj1.equals(null);
+            obj2.equals(null);
+
+            System.out.println("OK-3: "+obj1.getClass().getSimpleName()+
+                    ".equals worked with a null object.");
+        } catch (NullPointerException npe) {
+            System.out.println("--->KO-3!!! "+obj1.getClass().getSimpleName()+
+                    ".equals got NPE with a null object.");
+            npe.printStackTrace();
+            failed++;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/openmbean/OpenMBeanInfoHashCodeNPETest.java	Thu Sep 12 09:41:28 2013 +0200
@@ -0,0 +1,173 @@
+/*
+ * 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.MBeanNotificationInfo;
+import javax.management.modelmbean.DescriptorSupport;
+import javax.management.openmbean.OpenMBeanAttributeInfo;
+import javax.management.openmbean.OpenMBeanAttributeInfoSupport;
+import javax.management.openmbean.OpenMBeanConstructorInfo;
+import javax.management.openmbean.OpenMBeanConstructorInfoSupport;
+import javax.management.openmbean.OpenMBeanInfo;
+import javax.management.openmbean.OpenMBeanInfoSupport;
+import javax.management.openmbean.OpenMBeanOperationInfo;
+import javax.management.openmbean.OpenMBeanOperationInfoSupport;
+import javax.management.openmbean.OpenMBeanParameterInfo;
+import javax.management.openmbean.OpenMBeanParameterInfoSupport;
+import javax.management.openmbean.SimpleType;
+
+/*
+ * @test
+ * @bug 8023529
+ * @summary Test that OpenMBean*Info.hashCode do not throw NPE
+ * @author Shanliang JIANG
+ * @run clean OpenMBeanInfoHashCodeNPETest
+ * @run build OpenMBeanInfoHashCodeNPETest
+ * @run main OpenMBeanInfoHashCodeNPETest
+ */
+public class OpenMBeanInfoHashCodeNPETest {
+    private static int failed = 0;
+
+    public static void main(String[] args) throws Exception {
+        System.out.println("---OpenMBeanInfoHashCodeNPETest-main ...");
+
+        // ----
+        System.out.println("\n---Testing on OpenMBeanInfohashCodeTest...");
+        OpenMBeanAttributeInfo openMBeanAttributeInfo = new OpenMBeanAttributeInfoSupport(
+                "name", "description", SimpleType.INTEGER, true, true, false, null, new Integer[]{1, 2, 3});
+        test(openMBeanAttributeInfo, "defaultValue");
+
+        openMBeanAttributeInfo = new OpenMBeanAttributeInfoSupport(
+                "name", "description", SimpleType.INTEGER, true, true, false, 1, null);
+        test(openMBeanAttributeInfo, "legalValues");
+
+        // ----
+        System.out.println("\n---Testing on OpenMBeanConstructorInfoSupport...");
+        OpenMBeanConstructorInfo openMBeanConstructorInfo;
+
+        openMBeanConstructorInfo = new OpenMBeanConstructorInfoSupport(
+                "name", "description", null, new DescriptorSupport());
+        test(openMBeanConstructorInfo, "sigs");
+
+        openMBeanConstructorInfo = new OpenMBeanConstructorInfoSupport(
+                "name", "description", new OpenMBeanParameterInfo[]{}, null);
+        test(openMBeanConstructorInfo, "Descriptor");
+
+        // ----
+        System.out.println("\n---Testing on OpenMBeanOperationInfoSupport...");
+        OpenMBeanOperationInfo openMBeanOperationInfo;
+
+        openMBeanOperationInfo = new OpenMBeanOperationInfoSupport(
+                "name", "description", null,  SimpleType.INTEGER, 1, new DescriptorSupport());
+        test(openMBeanOperationInfo, "sigs");
+
+        openMBeanOperationInfo = new OpenMBeanOperationInfoSupport(
+                "name", "description", new OpenMBeanParameterInfo[]{},  SimpleType.INTEGER, 1, null);
+        test(openMBeanOperationInfo, "Descriptor");
+
+        // ----
+        System.out.println("\n---Testing on OpenMBeanParameterInfoSupport 1...");
+        OpenMBeanParameterInfo openMBeanParameterInfo;
+
+        openMBeanParameterInfo = new OpenMBeanParameterInfoSupport(
+                "name", "description", SimpleType.INTEGER, null, -1, 1);
+        test(openMBeanParameterInfo, "default value");
+
+        openMBeanParameterInfo = new OpenMBeanParameterInfoSupport(
+                "name", "description", SimpleType.INTEGER, 0, null, 1);
+        test(openMBeanParameterInfo, "min value");
+
+        openMBeanParameterInfo = new OpenMBeanParameterInfoSupport(
+                "name", "description", SimpleType.INTEGER, 0, -1, null);
+        test(openMBeanParameterInfo, "max value");
+
+        // ----
+        System.out.println("\n---Testing on OpenMBeanParameterInfoSupport 2...");
+        openMBeanParameterInfo = new OpenMBeanParameterInfoSupport(
+                "name", "description", SimpleType.INTEGER, 1, new Integer[]{-1, 1, 2});
+
+        openMBeanParameterInfo = new OpenMBeanParameterInfoSupport(
+                "name", "description", SimpleType.INTEGER, null, new Integer[]{-1, 1, 2});
+        test(openMBeanParameterInfo, "default value");
+
+        openMBeanParameterInfo = new OpenMBeanParameterInfoSupport(
+                "name", "description", SimpleType.INTEGER, 1, null);
+        test(openMBeanParameterInfo, "legal values");
+
+        // ----
+        System.out.println("\n---Testing on OpenMBeanInfoSupport...");
+        String className = "toto";
+        String description = "titi";
+        OpenMBeanAttributeInfo[] attrInfos = new OpenMBeanAttributeInfo[]{};
+        OpenMBeanConstructorInfo[] constrInfos = new OpenMBeanConstructorInfo[]{};
+        OpenMBeanOperationInfo[] operaInfos = new OpenMBeanOperationInfo[]{};
+        MBeanNotificationInfo[] notifInfos = new MBeanNotificationInfo[]{};
+
+        OpenMBeanInfo ominfo = new OpenMBeanInfoSupport(null, description, attrInfos, constrInfos, operaInfos, notifInfos);
+        test(ominfo, "class name");
+
+        ominfo = new OpenMBeanInfoSupport(className, null, attrInfos, constrInfos, operaInfos, notifInfos);
+        test(ominfo, "description");
+
+        ominfo = new OpenMBeanInfoSupport(className, description, null, constrInfos, operaInfos, notifInfos);
+        test(ominfo, "attrInfos");
+
+        ominfo = new OpenMBeanInfoSupport(className, description, attrInfos, null, operaInfos, notifInfos);
+        test(ominfo, "constructor infos");
+
+        ominfo = new OpenMBeanInfoSupport(className, description, attrInfos, constrInfos, null, notifInfos);
+        test(ominfo, "operation infos");
+
+        ominfo = new OpenMBeanInfoSupport(className, description, attrInfos, constrInfos, operaInfos, null);
+        test(ominfo, "notif infos");
+
+        if (failed > 0) {
+            throw new RuntimeException("Test failed: "+failed);
+        } else {
+            System.out.println("---Test: PASSED");
+        }
+    }
+
+    private static void test(Object obj, String param) {
+        try {
+            obj.hashCode();
+            System.out.println("OK-1: "+obj.getClass().getSimpleName()+
+                    ".hashCode worked with a null paramer: "+param);
+        } catch (NullPointerException npe) {
+            System.out.println("--->KO-1!!! "+obj.getClass().getSimpleName()+
+                    ".hashCode got NPE with null paramer: "+param);
+            npe.printStackTrace();
+            failed++;
+        }
+
+        try {
+            obj.toString();
+            System.out.println("OK-1: "+obj.getClass().getSimpleName()+
+                    ".toString worked with a null paramer: "+param);
+        } catch (NullPointerException npe) {
+            System.out.println("--->KO-1!!! "+obj.getClass().getSimpleName()+
+                    ".toString got NPE with null paramer: "+param);
+            npe.printStackTrace();
+            failed++;
+        }
+    }
+}