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

java.beans.Introspector.decapitalize does not correctly decapitalize strings starting with two capitals and continueing camel-cased

    Details

    • Subcomponent:
    • CPU:
      generic
    • OS:
      generic

      Description

      FULL PRODUCT VERSION :
      java version "1.8.0_144"
      Java(TM) SE Runtime Environment (build 1.8.0_144-b01)
      Java HotSpot(TM) 64-Bit Server VM (build 25.144-b01, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      Probably all operating systems, but mine is:
      Darwin eve.atlantis.local 16.7.0 Darwin Kernel Version 16.7.0: Thu Jun 15 17:36:27 PDT 2017; root:xnu-3789.70.16~2/RELEASE_X86_64 x86_64


      A DESCRIPTION OF THE PROBLEM :
      Introspector.getBeanInfo(type) is executed to get a BeanInfo object, which contains a PropertyDescriptor[] array.

      PropertyDescriptor contains a constructor that sets the name of the property using Introspector.decapitalize(base). The decapitalize method contains a rule that sets the first letter in the name to lowercase, if the first character is upper and the second character is not - if the original name contains two or more consecutive uppercase characters in the beginning, it will return the name as is, unmodified.

      The initial base name passed to the PropertyDescriptor constructor is actually name.substring(2) (in the case of a boolean method like "isSomething") or name.substring(3) (in the case of "getSomething" / "setSomething", see Introspector.java, lines 512, 515 and 522).

      This means that the initial name that is used to construct the PropertyDescriptor is not a field name somehow associated with the is/get/set methods, but litterally a part of the is/get/set method.

      The constructor of PropertyDescriptor seems to expect that and belatedly tries to decapitalize the string passed (PropertyDescriptor.java, line 159: setName(Introspector.decapitalize(base)); ), however, this never happens in the case that two or more characters in the beginning of the are capitalized, leaving the string as is, resulting in a wrong field name, and explaining the haphazard diffferences in properties starting with a lowercase letter and some starting with capitals.

      I think that the PropertyDescriptors[] object should contain property objects that actually reflect the fieldnames that the is/get/set methods operate for.

      If that is not possible, at the very least, I would expect the decapitalize method to handle a name like XAdRecord or UrlDecryptor or SOMETHING correctly (I.e, XAdRecord -> xAdRecord, UrlDecryptor -> urlDecryptor, SOMETHING -> SOMETHING).

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Have a class with a field named xAdRecord, and a getter/setter to match (i.e, getXAdRecord, setXAdRecord). Create a BeanInfo object for that class using Introspector.getBeanInfo(class);

      Look at the PropertyDescriptor object in the above BeanInfo object. Observe that you will have a "class" entry, lowercased correctly due to getClass probably, and a XAdRecord entry, incorrectly cased not reflecting the property name that the getter and setter operate for.


      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      xAdRecord instead of XAdRecord in PropertyDescriptors[].
      ACTUAL -
      XAdRecord (not decapitalized) in PropertyDescriptors[].

      REPRODUCIBILITY :
      This bug can be reproduced always.

        Attachments

          Activity

            People

            • Assignee:
              serb Sergey Bylokhov
              Reporter:
              webbuggrp Webbug Group
            • Votes:
              0 Vote for this issue
              Watchers:
              6 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: