Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8339559

Remove serialVersionUID compatibility logic from JMX

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Approved
    • Icon: P4 P4
    • 24
    • core-svc
    • None
    • behavioral
    • minimal
    • Applications using JMX releases from before it was integrated into the JDK in JDK 5, and simultaneously interacting with JMX in the latest JDK, are surely scarce to non-existent.
    • System or security property, File or wire format
    • Implementation

      Summary

      Remove JMX Serialization compatibility with very old JMX releases (1.0, 1.1, 1.2), which are from before JMX was an integrated part of the JDK.

      Problem

      Various JMX classes are serializable, but unlike most serializable classes, they compute a serialVersionUID value instead of defining that value as a constant. The reason for this is for serialization compatibility with JMX 1.0. These classes used certain SVUID values in 1.0 and different values in 1.1 and later; thus, by default, 1.0 was serialization incompatible with 1.1 and later.

      There is a switch to change the behavior. If the jmx.serial.form system property is set to "1.0" these classes will use the "old" SVUID values corresponding to those used in 1.0; otherwise they will use the "new" SVUID values for 1.1 and later. This enables the JMX running in a given JVM to be compatible with 1.0 or with 1.1-and-later, but not both.

      Additionally, in JMX 1.2, field names are forced to lower-case before being written, contradicting the specification, and the jmx.serial.form property enabled bug-compatibility with that (see src/java.management/share/classes/javax/management/modelmbean/DescriptorSupport.java).

      This compatibility logic adds unnecessary complexity to many classes and their serialization operations.

      Solution

      Simply remove the feature. It is reasonable to remove this compatibility courtesy given that it is around 20 years old. There is no reason for a JMX application running JDK 24 to be compatible with JMX distributions from before JMX was integrated into JDK 5 (released in September 2004).

      Specification

      The System property jmx.serial.form will be ignored.

      Github PR: https://github.com/openjdk/jdk/pull/20856

      The diff of the ObjectName class which has "serialData" information which is published in api/serialized-form.html is as follows. Screenshots are attached as they may be easier to read than the javadoc/html.

           /**
            * Deserializes an {@link ObjectName} from an {@link ObjectInputStream}.
      -     * @serialData <ul>
      -     *               <li>In the current serial form (value of property
      -     *                   <code>jmx.serial.form</code> differs from
      -     *                   <code>1.0</code>): the string
      -     *                   &quot;&lt;domain&gt;:&lt;properties&gt;&lt;wild&gt;&quot;,
      -     *                   where: <ul>
      -     *                            <li>&lt;domain&gt; represents the domain part
      -     *                                of the {@link ObjectName}</li>
      -     *                            <li>&lt;properties&gt; represents the list of
      -     *                                properties, as returned by
      -     *                                {@link #getKeyPropertyListString}
      -     *                            <li>&lt;wild&gt; is empty if not
      -     *                                <code>isPropertyPattern</code>, or
      -     *                                is the character "<code>*</code>" if
      -     *                                <code>isPropertyPattern</code>
      -     *                                and &lt;properties&gt; is empty, or
      -     *                                is "<code>,*</code>" if
      -     *                                <code>isPropertyPattern</code> and
      -     *                                &lt;properties&gt; is not empty.
      -     *                            </li>
      -     *                          </ul>
      -     *                   The intent is that this string could be supplied
      -     *                   to the {@link #ObjectName(String)} constructor to
      -     *                   produce an equivalent {@link ObjectName}.
      -     *               </li>
      -     *               <li>In the old serial form (value of property
      -     *                   <code>jmx.serial.form</code> is
      -     *                   <code>1.0</code>): &lt;domain&gt; &lt;propertyList&gt;
      -     *                   &lt;propertyListString&gt; &lt;canonicalName&gt;
      -     *                   &lt;pattern&gt; &lt;propertyPattern&gt;,
      -     *                   where: <ul>
      -     *                            <li>&lt;domain&gt; represents the domain part
      -     *                                of the {@link ObjectName}</li>
      -     *                            <li>&lt;propertyList&gt; is the
      -     *                                {@link Hashtable} that contains all the
      -     *                                pairs (key,value) for this
      -     *                                {@link ObjectName}</li>
      -     *                            <li>&lt;propertyListString&gt; is the
      -     *                                {@link String} representation of the
      -     *                                list of properties in any order (not
      -     *                                mandatorily a canonical representation)
      -     *                                </li>
      -     *                            <li>&lt;canonicalName&gt; is the
      -     *                                {@link String} containing this
      -     *                                {@link ObjectName}'s canonical name</li>
      -     *                            <li>&lt;pattern&gt; is a boolean which is
      -     *                                <code>true</code> if this
      -     *                                {@link ObjectName} contains a pattern</li>
      -     *                            <li>&lt;propertyPattern&gt; is a boolean which
      -     *                                is <code>true</code> if this
      -     *                                {@link ObjectName} contains a pattern in
      -     *                                the list of properties</li>
      -     *                          </ul>
      -     *               </li>
      +     * @serialData The string &quot;&lt;domain&gt;:&lt;properties&gt;&lt;wild&gt;&quot;, where:
      +     *             <ul>
      +     *               <li>&lt;domain&gt; represents the domain part
      +     *                   of the {@link ObjectName}</li>
      +     *               <li>&lt;properties&gt; represents the list of
      +     *                   properties, as returned by
      +     *                   {@link #getKeyPropertyListString}</li>
      +     *               <li>&lt;wild&gt; is empty if not
      +     *                   <code>isPropertyPattern</code>, or
      +     *                   is the character "<code>*</code>" if
      +     *                   <code>isPropertyPattern</code>
      +     *                   and &lt;properties&gt; is empty, or
      +     *                   is "<code>,*</code>" if
      +     *                   <code>isPropertyPattern</code> and
      +     *                   &lt;properties&gt; is not empty.</li>
            *             </ul>
      +     *             The intent is that this string could be supplied
      +     *             to the {@link #ObjectName(String)} constructor to
      +     *             produce an equivalent {@link ObjectName}.
            */
           private void readObject(ObjectInputStream in)
               throws IOException, ClassNotFoundException {
      
      
           /**
            * Serializes an {@link ObjectName} to an {@link ObjectOutputStream}.
      -     * @serialData <ul>
      -     *               <li>In the current serial form (value of property
      -     *                   <code>jmx.serial.form</code> differs from
      -     *                   <code>1.0</code>): the string
      -     *                   &quot;&lt;domain&gt;:&lt;properties&gt;&lt;wild&gt;&quot;,
      -     *                   where: <ul>
      -     *                            <li>&lt;domain&gt; represents the domain part
      -     *                                of the {@link ObjectName}</li>
      -     *                            <li>&lt;properties&gt; represents the list of
      -     *                                properties, as returned by
      -     *                                {@link #getKeyPropertyListString}
      -     *                            <li>&lt;wild&gt; is empty if not
      -     *                                <code>isPropertyPattern</code>, or
      -     *                                is the character "<code>*</code>" if
      -     *                                this <code>isPropertyPattern</code>
      -     *                                and &lt;properties&gt; is empty, or
      -     *                                is "<code>,*</code>" if
      -     *                                <code>isPropertyPattern</code> and
      -     *                                &lt;properties&gt; is not empty.
      -     *                            </li>
      -     *                          </ul>
      -     *                   The intent is that this string could be supplied
      -     *                   to the {@link #ObjectName(String)} constructor to
      -     *                   produce an equivalent {@link ObjectName}.
      -     *               </li>
      -     *               <li>In the old serial form (value of property
      -     *                   <code>jmx.serial.form</code> is
      -     *                   <code>1.0</code>): &lt;domain&gt; &lt;propertyList&gt;
      -     *                   &lt;propertyListString&gt; &lt;canonicalName&gt;
      -     *                   &lt;pattern&gt; &lt;propertyPattern&gt;,
      -     *                   where: <ul>
      -     *                            <li>&lt;domain&gt; represents the domain part
      -     *                                of the {@link ObjectName}</li>
      -     *                            <li>&lt;propertyList&gt; is the
      -     *                                {@link Hashtable} that contains all the
      -     *                                pairs (key,value) for this
      -     *                                {@link ObjectName}</li>
      -     *                            <li>&lt;propertyListString&gt; is the
      -     *                                {@link String} representation of the
      -     *                                list of properties in any order (not
      -     *                                mandatorily a canonical representation)
      -     *                                </li>
      -     *                            <li>&lt;canonicalName&gt; is the
      -     *                                {@link String} containing this
      -     *                                {@link ObjectName}'s canonical name</li>
      -     *                            <li>&lt;pattern&gt; is a boolean which is
      -     *                                <code>true</code> if this
      -     *                                {@link ObjectName} contains a pattern</li>
      -     *                            <li>&lt;propertyPattern&gt; is a boolean which
      -     *                                is <code>true</code> if this
      -     *                                {@link ObjectName} contains a pattern in
      -     *                                the list of properties</li>
      -     *                          </ul>
      -     *               </li>
      +     * @serialData The string &quot;&lt;domain&gt;:&lt;properties&gt;&lt;wild&gt;&quot;, where:
      +     *             <ul>
      +     *               <li>&lt;domain&gt; represents the domain part
      +     *                   of the {@link ObjectName}</li>
      +     *               <li>&lt;properties&gt; represents the list of
      +     *                   properties, as returned by
      +     *                   {@link #getKeyPropertyListString}</li>
      +     *               <li>&lt;wild&gt; is empty if not
      +     *                   <code>isPropertyPattern</code>, or
      +     *                   is the character "<code>*</code>" if
      +     *                   this <code>isPropertyPattern</code>
      +     *                   and &lt;properties&gt; is empty, or
      +     *                   is "<code>,*</code>" if
      +     *                   <code>isPropertyPattern</code> and
      +     *                   &lt;properties&gt; is not empty.</li>
            *             </ul>
      +     *             The intent is that this string could be supplied
      +     *             to the {@link #ObjectName(String)} constructor to
      +     *             produce an equivalent {@link ObjectName}.
            */
           private void writeObject(ObjectOutputStream out)
                   throws IOException {

            kevinw Kevin Walls
            smarks Stuart Marks
            Daniel Fuchs, Stuart Marks
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: