7193302: Remove ConstructorProperties annotation from java.lang.management.LockInfo
authormchung
Fri, 14 Sep 2012 09:47:14 -0700
changeset 13803 889df16bef60
parent 13802 7e765d50416f
child 13804 443fd84a849a
7193302: Remove ConstructorProperties annotation from java.lang.management.LockInfo Reviewed-by: alanb, sla, egahlin
jdk/src/share/classes/java/lang/management/LockInfo.java
jdk/src/share/classes/java/lang/management/ThreadInfo.java
jdk/src/share/classes/sun/management/LockDataConverter.java
jdk/src/share/classes/sun/management/LockDataConverterMXBean.java
jdk/src/share/classes/sun/management/LockInfoCompositeData.java
jdk/src/share/classes/sun/management/MappedMXBeanType.java
jdk/src/share/classes/sun/management/MonitorInfoCompositeData.java
jdk/src/share/classes/sun/management/ThreadInfoCompositeData.java
jdk/test/java/lang/management/ManagementFactory/ThreadMXBeanProxy.java
--- a/jdk/src/share/classes/java/lang/management/LockInfo.java	Fri Sep 14 10:30:38 2012 -0400
+++ b/jdk/src/share/classes/java/lang/management/LockInfo.java	Fri Sep 14 09:47:14 2012 -0700
@@ -27,7 +27,7 @@
 
 import javax.management.openmbean.CompositeData;
 import java.util.concurrent.locks.*;
-import java.beans.ConstructorProperties;
+import sun.management.LockInfoCompositeData;
 
 /**
  * Information about a <em>lock</em>.  A lock can be a built-in object monitor,
@@ -44,8 +44,7 @@
  *
  * <h4><a name="MappedType">MXBean Mapping</a></h4>
  * <tt>LockInfo</tt> is mapped to a {@link CompositeData CompositeData}
- * as specified in the <a href="../../../javax/management/MXBean.html#mapping-rules">
- * type mapping rules</a> of {@linkplain javax.management.MXBean MXBeans}.
+ * as specified in the {@link #from from} method.
  *
  * @see java.util.concurrent.locks.AbstractOwnableSynchronizer
  * @see java.util.concurrent.locks.Condition
@@ -66,7 +65,6 @@
      * @param identityHashCode the {@link System#identityHashCode
      *                         identity hash code} of the lock object.
      */
-    @ConstructorProperties({"className", "identityHashCode"})
     public LockInfo(String className, int identityHashCode) {
         if (className == null) {
             throw new NullPointerException("Parameter className cannot be null");
@@ -103,6 +101,50 @@
     }
 
     /**
+     * Returns a {@code LockInfo} object represented by the
+     * given {@code CompositeData}.
+     * The given {@code CompositeData} must contain the following attributes:
+     * <blockquote>
+     * <table border>
+     * <tr>
+     *   <th align=left>Attribute Name</th>
+     *   <th align=left>Type</th>
+     * </tr>
+     * <tr>
+     *   <td>className</td>
+     *   <td><tt>java.lang.String</tt></td>
+     * </tr>
+     * <tr>
+     *   <td>identityHashCode</td>
+     *   <td><tt>java.lang.Integer</tt></td>
+     * </tr>
+     * </table>
+     * </blockquote>
+     *
+     * @param cd {@code CompositeData} representing a {@code LockInfo}
+     *
+     * @throws IllegalArgumentException if {@code cd} does not
+     *   represent a {@code LockInfo} with the attributes described
+     *   above.
+     * @return a {@code LockInfo} object represented
+     *         by {@code cd} if {@code cd} is not {@code null};
+     *         {@code null} otherwise.
+     *
+     * @since 1.8
+     */
+    public static LockInfo from(CompositeData cd) {
+        if (cd == null) {
+            return null;
+        }
+
+        if (cd instanceof LockInfoCompositeData) {
+            return ((LockInfoCompositeData) cd).getLockInfo();
+        } else {
+            return LockInfoCompositeData.toLockInfo(cd);
+        }
+    }
+
+    /**
      * Returns a string representation of a lock.  The returned
      * string representation consists of the name of the class of the
      * lock object, the at-sign character `@', and the unsigned
--- a/jdk/src/share/classes/java/lang/management/ThreadInfo.java	Fri Sep 14 10:30:38 2012 -0400
+++ b/jdk/src/share/classes/java/lang/management/ThreadInfo.java	Fri Sep 14 09:47:14 2012 -0700
@@ -696,9 +696,7 @@
      *   <td>lockInfo</td>
      *   <td><tt>javax.management.openmbean.CompositeData</tt>
      *       - the mapped type for {@link LockInfo} as specified in the
-     *       <a href="../../../javax/management/MXBean.html#mapping-rules">
-     *       type mapping rules</a> of
-     *       {@linkplain javax.management.MXBean MXBeans}.
+     *         {@link LockInfo#from} method.
      *       <p>
      *       If <tt>cd</tt> does not contain this attribute,
      *       the <tt>LockInfo</tt> object will be constructed from
@@ -766,10 +764,7 @@
      *   <td>lockedSynchronizers</td>
      *   <td><tt>javax.management.openmbean.CompositeData[]</tt>
      *       whose element type is the mapped type for
-     *       {@link LockInfo} as specified in the
-     *       <a href="../../../javax/management/MXBean.html#mapping-rules">
-     *       type mapping rules</a> of
-     *       {@linkplain javax.management.MXBean MXBeans}.
+     *       {@link LockInfo} as specified in the {@link LockInfo#from} method.
      *       <p>
      *       If <tt>cd</tt> does not contain this attribute,
      *       this attribute will be set to an empty array. </td>
@@ -830,7 +825,6 @@
      * @since 1.6
      */
     public LockInfo[] getLockedSynchronizers() {
-       // represents an <a href="LockInfo.html#OwnableSynchronizer">
         return lockedSynchronizers;
     }
 
--- a/jdk/src/share/classes/sun/management/LockDataConverter.java	Fri Sep 14 10:30:38 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,111 +0,0 @@
-/*
- * Copyright (c) 2005, 2008, 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 sun.management;
-
-import java.lang.management.LockInfo;
-import java.lang.management.ThreadInfo;
-import javax.management.Attribute;
-import javax.management.StandardMBean;
-import javax.management.openmbean.CompositeData;
-
-/**
- * This MXBean is used for data conversion from LockInfo
- * to CompositeData (its mapped type) or vice versa.
- */
-class LockDataConverter extends StandardMBean
-         implements LockDataConverterMXBean {
-    private LockInfo      lockInfo;
-    private LockInfo[]    lockedSyncs;
-
-    LockDataConverter() {
-        super(LockDataConverterMXBean.class, true);
-        this.lockInfo = null;
-        this.lockedSyncs = null;
-    }
-
-    LockDataConverter(ThreadInfo ti) {
-        super(LockDataConverterMXBean.class, true);
-        this.lockInfo = ti.getLockInfo();
-        this.lockedSyncs = ti.getLockedSynchronizers();
-    }
-
-    public void setLockInfo(LockInfo l) {
-        this.lockInfo = l;
-    }
-
-    public LockInfo getLockInfo() {
-        return this.lockInfo;
-    }
-
-    public void setLockedSynchronizers(LockInfo[] l) {
-        this.lockedSyncs = l;
-    }
-
-    public LockInfo[] getLockedSynchronizers() {
-        return this.lockedSyncs;
-    }
-
-    // helper methods
-    CompositeData toLockInfoCompositeData() {
-        try {
-            return (CompositeData) getAttribute("LockInfo");
-        } catch (Exception e) {
-            throw new AssertionError(e);
-        }
-    }
-
-    CompositeData[] toLockedSynchronizersCompositeData() {
-        try {
-            return (CompositeData[]) getAttribute("LockedSynchronizers");
-        } catch (Exception e) {
-            throw new AssertionError(e);
-        }
-    }
-
-    LockInfo toLockInfo(CompositeData cd) {
-        try {
-            setAttribute(new Attribute("LockInfo", cd));
-        } catch (Exception e) {
-            throw new AssertionError(e);
-        }
-        return getLockInfo();
-    }
-
-    LockInfo[] toLockedSynchronizers(CompositeData[] cd) {
-        try {
-            setAttribute(new Attribute("LockedSynchronizers", cd));
-        } catch (Exception e) {
-            throw new AssertionError(e);
-        }
-        return getLockedSynchronizers();
-    }
-
-    static CompositeData toLockInfoCompositeData(LockInfo l) {
-        LockDataConverter ldc = new LockDataConverter();
-        ldc.setLockInfo(l);
-        return ldc.toLockInfoCompositeData();
-    }
-}
--- a/jdk/src/share/classes/sun/management/LockDataConverterMXBean.java	Fri Sep 14 10:30:38 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2005, 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 sun.management;
-
-import java.lang.management.LockInfo;
-
-/**
- * This interface is used for data conversion from LockInfo
- * to CompositeData (its mapped type) or vice versa.
- */
-public interface LockDataConverterMXBean {
-    public void setLockInfo(LockInfo l);
-    public LockInfo getLockInfo();
-
-    public void setLockedSynchronizers(LockInfo[] l);
-    public LockInfo[] getLockedSynchronizers();
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/management/LockInfoCompositeData.java	Fri Sep 14 09:47:14 2012 -0700
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2012, 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 sun.management;
+
+import java.lang.management.LockInfo;
+import javax.management.openmbean.CompositeType;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.CompositeDataSupport;
+import javax.management.openmbean.OpenDataException;
+
+/**
+ * A CompositeData for LockInfo for the local management support.
+ * This class avoids the performance penalty paid to the
+ * construction of a CompositeData use in the local case.
+ */
+public class LockInfoCompositeData extends LazyCompositeData {
+    private final LockInfo lock;
+
+    private LockInfoCompositeData(LockInfo li) {
+        this.lock = li;
+    }
+
+    public LockInfo getLockInfo() {
+        return lock;
+    }
+
+    public static CompositeData toCompositeData(LockInfo li) {
+        if (li == null) {
+            return null;
+        }
+
+        LockInfoCompositeData licd = new LockInfoCompositeData(li);
+        return licd.getCompositeData();
+    }
+
+    protected CompositeData getCompositeData() {
+        // CONTENTS OF THIS ARRAY MUST BE SYNCHRONIZED WITH
+        // lockInfoItemNames!
+        final Object[] lockInfoItemValues = {
+            new String(lock.getClassName()),
+            new Integer(lock.getIdentityHashCode()),
+        };
+
+        try {
+            return new CompositeDataSupport(lockInfoCompositeType,
+                                            lockInfoItemNames,
+                                            lockInfoItemValues);
+        } catch (OpenDataException e) {
+            // Should never reach here
+            throw Util.newException(e);
+        }
+    }
+
+    private static final CompositeType lockInfoCompositeType;
+    static {
+        try {
+            lockInfoCompositeType = (CompositeType)
+                MappedMXBeanType.toOpenType(LockInfo.class);
+        } catch (OpenDataException e) {
+            // Should never reach here
+            throw Util.newException(e);
+        }
+    }
+
+    static CompositeType getLockInfoCompositeType() {
+        return lockInfoCompositeType;
+    }
+
+    private static final String CLASS_NAME         = "className";
+    private static final String IDENTITY_HASH_CODE = "identityHashCode";
+    private static final String[] lockInfoItemNames = {
+        CLASS_NAME,
+        IDENTITY_HASH_CODE,
+    };
+
+    /*
+     * Returns a LockInfo object mapped from the given CompositeData.
+     */
+    public static LockInfo toLockInfo(CompositeData cd) {
+        if (cd == null) {
+            throw new NullPointerException("Null CompositeData");
+        }
+
+        if (!isTypeMatched(lockInfoCompositeType, cd.getCompositeType())) {
+            throw new IllegalArgumentException(
+                "Unexpected composite type for LockInfo");
+        }
+
+        String className = getString(cd, CLASS_NAME);
+        int identityHashCode = getInt(cd, IDENTITY_HASH_CODE);
+        return new LockInfo(className, identityHashCode);
+    }
+
+    private static final long serialVersionUID = -6374759159749014052L;
+}
--- a/jdk/src/share/classes/sun/management/MappedMXBeanType.java	Fri Sep 14 10:30:38 2012 -0400
+++ b/jdk/src/share/classes/sun/management/MappedMXBeanType.java	Fri Sep 14 09:47:14 2012 -0700
@@ -703,7 +703,7 @@
                 if (data instanceof java.lang.management.MonitorInfo) {
                     return MonitorInfoCompositeData.toCompositeData((MonitorInfo) data);
                 }
-                return LockDataConverter.toLockInfoCompositeData((LockInfo) data);
+                return LockInfoCompositeData.toCompositeData((LockInfo) data);
             }
 
             if (data instanceof MemoryNotificationInfo) {
--- a/jdk/src/share/classes/sun/management/MonitorInfoCompositeData.java	Fri Sep 14 10:30:38 2012 -0400
+++ b/jdk/src/share/classes/sun/management/MonitorInfoCompositeData.java	Fri Sep 14 09:47:14 2012 -0700
@@ -59,7 +59,7 @@
 
         int len = monitorInfoItemNames.length;
         Object[] values = new Object[len];
-        CompositeData li = LockDataConverter.toLockInfoCompositeData(lock);
+        CompositeData li = LockInfoCompositeData.toCompositeData(lock);
 
         for (int i = 0; i < len; i++) {
             String item = monitorInfoItemNames[i];
--- a/jdk/src/share/classes/sun/management/ThreadInfoCompositeData.java	Fri Sep 14 10:30:38 2012 -0400
+++ b/jdk/src/share/classes/sun/management/ThreadInfoCompositeData.java	Fri Sep 14 09:47:14 2012 -0700
@@ -85,11 +85,18 @@
         }
 
         // Convert MonitorInfo[] and LockInfo[] to CompositeData[]
-        LockDataConverter converter = new LockDataConverter(threadInfo);
-        CompositeData lockInfoData = converter.toLockInfoCompositeData();
-        CompositeData[] lockedSyncsData = converter.toLockedSynchronizersCompositeData();
+        CompositeData lockInfoData =
+            LockInfoCompositeData.toCompositeData(threadInfo.getLockInfo());
 
-        // Convert MonitorInfo[] to CompositeData[]
+        // Convert LockInfo[] and MonitorInfo[] to CompositeData[]
+        LockInfo[] lockedSyncs = threadInfo.getLockedSynchronizers();
+        CompositeData[] lockedSyncsData =
+            new CompositeData[lockedSyncs.length];
+        for (int i = 0; i < lockedSyncs.length; i++) {
+            LockInfo li = lockedSyncs[i];
+            lockedSyncsData[i] = LockInfoCompositeData.toCompositeData(li);
+        }
+
         MonitorInfo[] lockedMonitors = threadInfo.getLockedMonitors();
         CompositeData[] lockedMonitorsData =
             new CompositeData[lockedMonitors.length];
@@ -98,7 +105,6 @@
             lockedMonitorsData[i] = MonitorInfoCompositeData.toCompositeData(mi);
         }
 
-
         // CONTENTS OF THIS ARRAY MUST BE SYNCHRONIZED WITH
         // threadInfoItemNames!
         final Object[] threadInfoItemValues = {
@@ -216,11 +222,11 @@
         // with it.  So we can get the CompositeType representing LockInfo
         // from a mapped CompositeData for any LockInfo object.
         // Thus we construct a random LockInfo object and pass it
-        // to LockDataConverter to do the conversion.
+        // to LockInfoCompositeData to do the conversion.
         Object o = new Object();
         LockInfo li = new LockInfo(o.getClass().getName(),
                                    System.identityHashCode(o));
-        CompositeData cd = LockDataConverter.toLockInfoCompositeData(li);
+        CompositeData cd = LockInfoCompositeData.toCompositeData(li);
         lockInfoCompositeType = cd.getCompositeType();
     }
 
@@ -315,9 +321,8 @@
 
     // 6.0 new attributes
     public LockInfo lockInfo() {
-        LockDataConverter converter = new LockDataConverter();
         CompositeData lockInfoData = (CompositeData) cdata.get(LOCK_INFO);
-        return converter.toLockInfo(lockInfoData);
+        return LockInfo.from(lockInfoData);
     }
 
     public MonitorInfo[] lockedMonitors() {
@@ -336,13 +341,17 @@
     }
 
     public LockInfo[] lockedSynchronizers() {
-        LockDataConverter converter = new LockDataConverter();
         CompositeData[] lockedSyncsData =
             (CompositeData[]) cdata.get(LOCKED_SYNCS);
 
         // The LockedSynchronizers item cannot be null, but if it is we will
         // get a NullPointerException when we ask for its length.
-        return converter.toLockedSynchronizers(lockedSyncsData);
+        LockInfo[] locks = new LockInfo[lockedSyncsData.length];
+        for (int i = 0; i < lockedSyncsData.length; i++) {
+            CompositeData cdi = lockedSyncsData[i];
+            locks[i] = LockInfo.from(cdi);
+        }
+        return locks;
     }
 
     /** Validate if the input CompositeData has the expected
--- a/jdk/test/java/lang/management/ManagementFactory/ThreadMXBeanProxy.java	Fri Sep 14 10:30:38 2012 -0400
+++ b/jdk/test/java/lang/management/ManagementFactory/ThreadMXBeanProxy.java	Fri Sep 14 09:47:14 2012 -0700
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug     5086470 6358247
+ * @bug     5086470 6358247 7193302
  * @summary Test type conversion when invoking ThreadMXBean.dumpAllThreads
  *          through proxy.
  *
@@ -173,6 +173,10 @@
                 throw new RuntimeException("LockInfo: " + syncs[0] +
                     " IdentityHashCode not matched. Expected: " + hcode);
             }
+            LockInfo li = info.getLockInfo();
+            if (li == null) {
+                throw new RuntimeException("Expected non-null LockInfo");
+            }
         }
     }
     static class Mutex implements Lock, java.io.Serializable {