Skip to content
This repository has been archived by the owner on Feb 5, 2019. It is now read-only.

Marshalling of negative years in XmlGregorianCalendar is incorrect #1191

Open
LanceAndersen opened this issue Apr 27, 2018 · 0 comments
Open

Comments

@LanceAndersen
Copy link

previously tracked via: https://bugs.openjdk.java.net/browse/JDK-8172162

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); 

}

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant