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

DatatypeFactory is poorly designed, and promotes bad code

    Details

    • Type: Enhancement
    • Status: Open
    • Priority: P3
    • Resolution: Unresolved
    • Affects Version/s: 5.0
    • Fix Version/s: 5.0
    • Component/s: xml
    • Labels:
    • Subcomponent:
    • CPU:
      generic
    • OS:
      generic

      Description

      DatatypeFactory is poorly designed both in terms of usability and performance.

      From the usability point of view, it's suffice to show the following code that average developers have to write to get one XMLGregorianCalendar instance created:

        XMLGregorianCalendar cal;
        try {
           cal = DatatypeFactory.newInstance().newXMLGregorianCalendar(...);
        } catch(DatatypeConfigurationException e) {
          // huh?
          assert false;
        }

      This is ridiculously long compared to other common value object creation, such as "new URL(String)" or even to "new Date()".

      Another problem is that DatatypeFactory.newInstance() throws a checked DatatypeConfigurationException, which forces users to handle it, even though this is simply a deployment error and nothing a running application can meaningfully handle. It's worth pointing out that neither SAXParserFactory.newInstance() nor DocumentBuilderFactory.newInstance() throws any checked exception (correctly!)

      The other usability issue is the lack of convenience methods to create XMLGregorianCalendar in various formats. For example, there's no easy way to create an XMLGregorianCalendar instance that represents today in xs:gDate. Even creating xs:dateTime representation of Today requires the user to create a new GregorianCalendar instance, then to XMLGregorianCalendar.


      The performance aspect of this is equally bad, as DatatypeFactory.newInstance() goes through the complete service look up mechanism. See the comment section for the performance numbers.

      On a relevant performance note, the spec should require that DatatypeFactory be thread safe. Since DatatypeFactory is stateless today, this shouldn't be a problem (The JAXP RI implements this in a thread-safe way.) If there's any implementation that cannot make this thread-safe, they only need to put synchronized keyword on their methods.


      All in all, I suggest the following change to DatatypeFactory.

       - Require that DatatypeFactory be reentrant by multiple threads.
       
       - Deprecate DatatypeFactory, citing performance and usability reasons.

       - Move newXXX methods from DatatypeFactory to Duration and XMLGregorianCalendar and make them static.
         With is, the user would now say something like this:

           XMLGregorianCalendar.createToday();

         XMLGregorianCalendar class should maintain one static final DatatypeFactory instance to delegate
         all static createXXX method invocations to. The same for Duration.

      - When you move factory methods, this is also a good opporunity to think hard about the kind of
         methods you want to define. For example, creating uninitialized XMLGregorianCalendar is far less
         common than creating the XMLGregorianCalendar that represents "now". So the no-arg factory method
         should be probably used for creating "now" as opposed to creating uninitialized one.

      These changes together make XMLGregorianCalendar and Duration more usable and performant, without adding any more work to the developers.

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                joehw Joe Wang
                Reporter:
                kkawagucsunw Kohsuke Kawaguchi (Inactive)
              • Votes:
                0 Vote for this issue
                Watchers:
                0 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Imported:
                  Indexed: