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

Marshalling of negative years in XmlGregorianCalendar is incorrect

XMLWordPrintable

    • generic
    • generic

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

      ADDITIONAL OS VERSION INFORMATION :
      Microsoft Windows [Version 10.0.14393]

      A DESCRIPTION OF THE PROBLEM :
      1. I have JAXB-annotated class where I have some field of type javax.xml.datatype.XMLGregorianCalendar with annotations @XmlElement(name = "dateTimeField") @XmlSchemaType(name = "dateTime")
      2. I have valid xml representation of instance of class from item (1) where the value of XMLGregorianCalendar field contains negative year value (-0001 for example)
      3. I am unmarshal the xml and receive the instance JAXB-annotated class.
      4. The value of year is correct in instance.
      5. I am marshal the object and see that negative year is printed as "00-1"

      Comments:
      1. If I remove annotation @XmlSchemaType(name = "dateTime") the everything work as expected.
      2. Full runnable example is attached.


      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Run the source code below

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      -0001-12-31T23:59:59.999Z
      ACTUAL -
      00-1-12-31T23:59:59.999Z

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      package com.afilin.java8;

      import javax.xml.bind.JAXBContext;
      import javax.xml.bind.Marshaller;
      import javax.xml.bind.Unmarshaller;
      import javax.xml.bind.annotation.XmlElement;
      import javax.xml.bind.annotation.XmlRootElement;
      import javax.xml.bind.annotation.XmlSchemaType;
      import javax.xml.datatype.XMLGregorianCalendar;
      import java.io.StringReader;
      import java.io.StringWriter;

      public class NegativeYearsBug {

          @XmlRootElement(name="root")
          private static class JaxbExample {
              @XmlElement(name = "dateTimeField")
              @XmlSchemaType(name = "dateTime")
              private XMLGregorianCalendar dateTimeField;

              public XMLGregorianCalendar getDateTimeField() {
                  return dateTimeField;
              }
          }
          public static void main(String[] args) throws Exception {
              String xml = "<root><dateTimeField>-0001-12-31T23:59:59.999Z</dateTimeField></root>";
              JAXBContext jaxbContext = JAXBContext.newInstance(JaxbExample.class);
              Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
              JaxbExample unmarshalledObject = (JaxbExample) unmarshaller.unmarshal(new StringReader(xml));
              Marshaller marshaller = jaxbContext.createMarshaller();
              StringWriter stringWriter = new StringWriter();
              marshaller.marshal(unmarshalledObject, stringWriter);
              assert xml.equals(stringWriter.toString()) : "Actual value: " + stringWriter.toString();
          }
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      change implementation of
      com.sun.xml.internal.bind.v2.model.impl.RuntimeBuiltinLeafInfoImpl#printNumber(StringBuilder out, BigInteger number, int nDigits) {
              BigInteger absoluteValue = number.abs();
              String s = absoluteValue.toString();
              if(number.signum() < 0) {
                  out.append("-");
              }
              for(int i = s.length(); i < nDigits; ++i) {
                  out.append('0');
              }

              out.append(s);
      }


            zli Zheng Jun Li (Inactive)
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: