JiBX is not ready to work with xsd:date XML type

Details

Description

This is my third bugreport on JiBX (two are here and one is in Axis2 bugtracking system). I think it is because we are using JiBX for datmopping only on one side of webservices communication.

This time i have found two problems that appear to have the same root. First problem deals with datamapping when JiBX marshals value for xsd:date element. So JiBX is marshaling Date to the XML where xsd:date is expected by using it's default mapping for Date. As i have found after discovering the problem, in such case JiBX 1) uses standard transformation as for xsd:dateTime type, and 2) when writing to XML, JiBX converts date to UTC timezone. Combination of these two features makes other side to receive a date value that is different from the sent value (the received date is one day before the date which was sent) when the timezone on a host making request is set ahead UTC (e.g., UTC+1 in my case). This is because, e.g. to sent the date "1st of January, 2008" on the host having UTC+1 timezone, the jibix marshals the date as datewithtime and then converts to UTC, as a result one will have somewhat like "2007-12-31T23:00:00Z" in the XML. Then the receiving side, that expects xsd:date here, reads just date "2007-12-31" from that XML and usially ignores the timezone specified. So the result in this example usially will be "31st of December, 2007".

The second problem arises when JiBX is on the receiving side and is unmarshaling the value that was sent as a value of xsd:date. The sender sends an XML value like "2005-12-21+02:00". Then the JiBX, looking at the type in valueobject (the type is usially java.util.Date) by default unmarshals the xml value as a value for xsd:dateTime... and raises exception JiBXException("Missing 'T' separator in dateTime"). This is done inside org.jibx.runtime.Utility.parseDateTime(String).

Finally, i've tried the changes in runtime... and got JiBXException("Invalid date format") on the Utility:711. The text in my case was "2005-12-21+02:00", the validity flag was set to false on the line Utility:707, and when executing the line 706 the value of split was 10. So the text.charAt(Split) in my case was '+' and i wonder what for is the comparation text.charAt(split+3) != '-' at the line 706...
703: if (text.length() < minc)

In summary, there is no method in org.jibx.runtime.Utility that is ready to deserialize xsd:date value. And to have such method is a must since xsd:date is quite common type in webservices definitions. Please add such method. And i think that the way one should write XSD to work with xsd:date is worth going to JiBX FAQ.

Activity

And here is the patch for this problem: it's the validateDate(String text) which is confused that the text is longer than it expects due to timezone at the end. So the only we need is to change the next line in validateDate():
int split = text.length() - 6;
to be:
int split = minc - 6;

Michael Bannij
added a comment - 06/Jun/08 8:32 AM And here is the patch for this problem: it's the validateDate(String text) which is confused that the text is longer than it expects due to timezone at the end. So the only we need is to change the next line in validateDate():
int split = text.length() - 6;
to be:
int split = minc - 6;
Dennis, please check this change and incorporate it into JiBX code.

Unfortunately the serialization side of the problem is still there in 1.1.6/1.1.6a. I'll get this fixed for the upcoming 1.2 beta release.
I think the approach I'll use is to convert to the current date in UTC (and use the Z suffix).

The Java Calendar-based code is a horrible mess, and rarely works well for XML processing. In this case it may be what many people expect to have happen, though, so I can perhaps provide the Calendar-based serializer and deserializer as an alternative format. But what would you suggest the deserializer should do? Unless you happen to be in the same timezone as the originator of the XML, when you deserialize a date value with time zone you'll get a java.util.Date which may not represent the same day. That's why I think always using UTC makes much more sense.

Dennis Sosnoski
added a comment - 09/Jun/08 5:58 AM Unfortunately the serialization side of the problem is still there in 1.1.6/1.1.6a. I'll get this fixed for the upcoming 1.2 beta release.
I think the approach I'll use is to convert to the current date in UTC (and use the Z suffix).
The Java Calendar-based code is a horrible mess, and rarely works well for XML processing. In this case it may be what many people expect to have happen, though, so I can perhaps provide the Calendar-based serializer and deserializer as an alternative format. But what would you suggest the deserializer should do? Unless you happen to be in the same timezone as the originator of the XML, when you deserialize a date value with time zone you'll get a java.util.Date which may not represent the same day. That's why I think always using UTC makes much more sense.

On second thought, for xsd:Date it probably makes the most sense to always have it without a timezone specification. That way it can always be converted to midnight of the given date in local time (which is essentially how this works now when using the java.sql.Date deserializer).

So perhaps my default approach should be to serialize the local date without timezone specification, then ignore timezone specifications on an input value and deserialize the date to the local timezone. But if there are other alternative conversions which you think make sense I can implement them as alternative formats.

Dennis Sosnoski
added a comment - 09/Jun/08 6:03 AM On second thought, for xsd:Date it probably makes the most sense to always have it without a timezone specification. That way it can always be converted to midnight of the given date in local time (which is essentially how this works now when using the java.sql.Date deserializer).
So perhaps my default approach should be to serialize the local date without timezone specification, then ignore timezone specifications on an input value and deserialize the date to the local timezone. But if there are other alternative conversions which you think make sense I can implement them as alternative formats.

Just checked - there is no more problem with deserialization in 1.1.6, but the problem with serializing 31 of December instead of 1st of January is still there...

What about how it should work - in my opinion by default the serialization should be done in local timezone with or without appending that timezone to the end of the string. The deserialization should ignore the timezone specifiend in the string and use local one instead.

Also probably you should look into other datamapping frameworks. And if there are some general conventions about this problem, then you probably should also use that one. Anyway, if developers can somehow manage and customize the process of Date (un)marshaling, that would be nice. Since currently it is only possible to choose a serializer/deserializer, so at least a few serializer-deserializer methods for most friquenlty used conventions should be present in JiBX by default IMHO.

Michael Bannij
added a comment - 09/Jun/08 6:40 AM Just checked - there is no more problem with deserialization in 1.1.6, but the problem with serializing 31 of December instead of 1st of January is still there...
What about how it should work - in my opinion by default the serialization should be done in local timezone with or without appending that timezone to the end of the string. The deserialization should ignore the timezone specifiend in the string and use local one instead.
Also probably you should look into other datamapping frameworks. And if there are some general conventions about this problem, then you probably should also use that one. Anyway, if developers can somehow manage and customize the process of Date (un)marshaling, that would be nice. Since currently it is only possible to choose a serializer/deserializer, so at least a few serializer-deserializer methods for most friquenlty used conventions should be present in JiBX by default IMHO.

I've added support for the Joda date/time library, which provides more complete representations than the standard Java classes, and have also implemented a selection of conversions so that you can easily chose the way to handle time zones. That should take care of it.

Dennis Sosnoski
added a comment - 24/Sep/09 7:26 AM I've added support for the Joda date/time library, which provides more complete representations than the standard Java classes, and have also implemented a selection of conversions so that you can easily chose the way to handle time zones. That should take care of it.

These are the steps I did
1. Took latest release( 1.2.2)
2. Ran Codegen tool to generate default binding/java classes from schema.
3. Ran Binding compiler
4. Ran my test program and it still gave me same problem.

Rohit Verma
added a comment - 15/Mar/10 8:07 AM Dennis,
I still face this issue.
These are the steps I did
1. Took latest release( 1.2.2)
2. Ran Codegen tool to generate default binding/java classes from schema.
3. Ran Binding compiler
4. Ran my test program and it still gave me same problem.
Do I need to do something else?
Best Regards,
Rohit