Details
Description
We have an element that is a Timestamp defined in a complex type like this.
<xs:element name="ContainingElement">
<xs:complexType>
<xs:sequence>
<xs:element name="SomeElement" type="xs:string" minOccurs="0"/>
<!-- ... more elements -->
<xs:element ref="SomeReference" minOccurs="0"/>
<!-- ... more references -->
<xs:element name="Timestamp" type="xs:dateTime" minOccurs="0"/>
<!-- ... more elements -->
<!-- ... more references -->
</xs:sequence>
</xs:complexType>
</xs:element>
We generate classes with the code generator.
We create an unmarshaller, turn off validation, and try to unmarshall the following bogus input. The last two digits are 44 instead of 00.
<ContainingElement>
<SomeElement>
<!-- ... more elements etc... -->
<Timestamp>2006-08-29T08:50:00.0-03:44</Timestamp>
<!-- ... more elements etc... -->
</ContainingElement>
Castor then bombs with an ArrayIndexOutOfBoundsException. We tried turning on validation, but the error still persists.
java.lang.ArrayIndexOutOfBoundsException: Array index out of range: 0
at org.exolab.castor.types.DateTimeBase.setDateFormatTimeZone(DateTimeBase.java:1318)
at org.exolab.castor.types.DateTime.toDate(DateTime.java:185)
at org.exolab.castor.xml.handlers.DateFieldHandler.parse(DateFieldHandler.java:368)
at org.exolab.castor.xml.handlers.DateFieldHandler.setValue(DateFieldHandler.java:166)
at org.exolab.castor.xml.UnmarshalHandler.endElement(UnmarshalHandler.java:1054)
at org.exolab.castor.xml.UnmarshalHandler.endElement(UnmarshalHandler.java:1119)
at org.apache.xerces.parsers.AbstractSAXParser.endElement(Unknown Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanEndElement(Unknown Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
at org.apache.xerces.parsers.DTDConfiguration.parse(Unknown Source)
at org.apache.xerces.parsers.DTDConfiguration.parse(Unknown Source)
at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
at org.exolab.castor.xml.Unmarshaller.unmarshal(Unmarshaller.java:729)
at org.exolab.castor.xml.Unmarshaller.unmarshal(Unmarshaller.java:621)
Other bad timestamps produce a meaningful error message in Castor, and this should too. If we fix the input and make the offset be "3:00" e.g.
<ContainingElement>
<SomeElement>
<!-- ... more elements etc... -->
<Timestamp>2006-08-29T08:50:00.0-03:00</Timestamp>
<!-- ... more elements etc... -->
</ContainingElement>
Things work just fine.
Thanks for all the fish.
-
Hide
- bug2017.zip
- 12/Jun/07 3:35 PM
- 7 kB
- Bill Robertson
-
- bug2017/Entity.java 4 kB
- bug2017/EntityDescriptor.java 5 kB
- bug2017/README.txt 0.2 kB
- bug2017/TestTemplate.java 1 kB
- bug2017/build.xml 2 kB
- bug2017/input.xml 0.2 kB
- bug2017/org/.../castorbuilder.properties 4 kB
- bug2017/schema.xsd 0.5 kB
Activity
Bill, can you please attach a working XML schema and a JUnit test case (incl. XML sample document) that I can use to replay the problem. If you followed the guidelines available in the XML HOW-TO section, that would be appreciated.
Just in case it works for you.
Here's the output that I get, and a list of the jar files that I used in case I got those wrong.
C:\bill\castor\castor-1.1.1\src\bugs\xml\bug2017>ant
Buildfile: build.xml
readme:
[echo] Please note, to run this build file, you must copy the castor jars, and necessary castor generator jars to ht lib direct
ory.
generate:
[delete] Deleting: C:\bill\castor\castor-1.1.1\src\bugs\xml\bug2017\Entity.java
[delete] Deleting: C:\bill\castor\castor-1.1.1\src\bugs\xml\bug2017\EntityDescriptor.java
[java] log4j:WARN No appenders could be found for logger (org.exolab.castor.builder.SourceGenerator).
[java] log4j:WARN Please initialize the log4j system properly.
compile:
[javac] Compiling 3 source files to C:\bill\castor\castor-1.1.1\src\bugs\xml\bug2017
test:
[java] .E.E
[java] Time: 0.406
[java] There were 2 errors:
[java] 1) testUnmarshalEntityNoValidation(TestTemplate)0
[java] at org.exolab.castor.xml.Unmarshaller.convertSAXExceptionToMarshalException(Unmarshaller.java:775)
[java] at org.exolab.castor.xml.Unmarshaller.unmarshal(Unmarshaller.java:741)
[java] at TestTemplate.testUnmarshalEntityNoValidation(Unknown Source)
[java] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[java] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:79)
[java] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:41)
[java] Caused by: java.lang.ArrayIndexOutOfBoundsException: 0
[java] at org.exolab.castor.types.DateTimeBase.setDateFormatTimeZone(DateTimeBase.java:1318)
[java] at org.exolab.castor.types.DateTime.toDate(DateTime.java:185)
[java] at org.exolab.castor.xml.handlers.DateFieldHandler.parse(DateFieldHandler.java:368)
[java] at org.exolab.castor.xml.handlers.DateFieldHandler.setValue(DateFieldHandler.java:166)
[java] at org.exolab.castor.xml.UnmarshalHandler.endElement(UnmarshalHandler.java:1054)
[java] at org.exolab.castor.xml.UnmarshalHandler.endElement(UnmarshalHandler.java:1119)
[java] at org.apache.xerces.parsers.AbstractSAXParser.endElement(Unknown Source)
[java] at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanEndElement(Unknown Source)
[java] at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
[java] at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
[java] at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
[java] at org.apache.xerces.parsers.DTDConfiguration.parse(Unknown Source)
[java] at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
[java] at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
[java] at org.exolab.castor.xml.Unmarshaller.unmarshal(Unmarshaller.java:729)
[java] ... 16 more
[java] Caused by: java.lang.ArrayIndexOutOfBoundsException: 0
[java] at org.exolab.castor.types.DateTimeBase.setDateFormatTimeZone(DateTimeBase.java:1318)
[java] at org.exolab.castor.types.DateTime.toDate(DateTime.java:185)
[java] at org.exolab.castor.xml.handlers.DateFieldHandler.parse(DateFieldHandler.java:368)
[java] at org.exolab.castor.xml.handlers.DateFieldHandler.setValue(DateFieldHandler.java:166)
[java] at org.exolab.castor.xml.UnmarshalHandler.endElement(UnmarshalHandler.java:1054)
[java] at org.exolab.castor.xml.UnmarshalHandler.endElement(UnmarshalHandler.java:1119)
[java] at org.apache.xerces.parsers.AbstractSAXParser.endElement(Unknown Source)
[java] at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanEndElement(Unknown Source)
[java] at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
[java] at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
[java] at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
[java] at org.apache.xerces.parsers.DTDConfiguration.parse(Unknown Source)
[java] at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
[java] at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
[java] at org.exolab.castor.xml.Unmarshaller.unmarshal(Unmarshaller.java:729)
[java] at TestTemplate.testUnmarshalEntityNoValidation(Unknown Source)
[java] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[java] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:79)
[java] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:41)
[java] 2) testUnmarshalEntity(TestTemplate)0
[java] at org.exolab.castor.xml.Unmarshaller.convertSAXExceptionToMarshalException(Unmarshaller.java:775)
[java] at org.exolab.castor.xml.Unmarshaller.unmarshal(Unmarshaller.java:741)
[java] at TestTemplate.testUnmarshalEntity(Unknown Source)
[java] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[java] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:79)
[java] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:41)
[java] Caused by: java.lang.ArrayIndexOutOfBoundsException: 0
[java] at org.exolab.castor.types.DateTimeBase.setDateFormatTimeZone(DateTimeBase.java:1318)
[java] at org.exolab.castor.types.DateTime.toDate(DateTime.java:185)
[java] at org.exolab.castor.xml.handlers.DateFieldHandler.parse(DateFieldHandler.java:368)
[java] at org.exolab.castor.xml.handlers.DateFieldHandler.setValue(DateFieldHandler.java:166)
[java] at org.exolab.castor.xml.UnmarshalHandler.endElement(UnmarshalHandler.java:1054)
[java] at org.exolab.castor.xml.UnmarshalHandler.endElement(UnmarshalHandler.java:1119)
[java] at org.apache.xerces.parsers.AbstractSAXParser.endElement(Unknown Source)
[java] at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanEndElement(Unknown Source)
[java] at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
[java] at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
[java] at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
[java] at org.apache.xerces.parsers.DTDConfiguration.parse(Unknown Source)
[java] at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
[java] at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
[java] at org.exolab.castor.xml.Unmarshaller.unmarshal(Unmarshaller.java:729)
[java] ... 16 more
[java] Caused by: java.lang.ArrayIndexOutOfBoundsException: 0
[java] at org.exolab.castor.types.DateTimeBase.setDateFormatTimeZone(DateTimeBase.java:1318)
[java] at org.exolab.castor.types.DateTime.toDate(DateTime.java:185)
[java] at org.exolab.castor.xml.handlers.DateFieldHandler.parse(DateFieldHandler.java:368)
[java] at org.exolab.castor.xml.handlers.DateFieldHandler.setValue(DateFieldHandler.java:166)
[java] at org.exolab.castor.xml.UnmarshalHandler.endElement(UnmarshalHandler.java:1054)
[java] at org.exolab.castor.xml.UnmarshalHandler.endElement(UnmarshalHandler.java:1119)
[java] at org.apache.xerces.parsers.AbstractSAXParser.endElement(Unknown Source)
[java] at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanEndElement(Unknown Source)
[java] at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
[java] at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
[java] at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
[java] at org.apache.xerces.parsers.DTDConfiguration.parse(Unknown Source)
[java] at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
[java] at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
[java] at org.exolab.castor.xml.Unmarshaller.unmarshal(Unmarshaller.java:729)
[java] at TestTemplate.testUnmarshalEntity(Unknown Source)
[java] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[java] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:79)
[java] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:41)
[java]
[java] FAILURES!!!
[java] Tests run: 2, Failures: 0, Errors: 2
[java]
BUILD FAILED
C:\bill\castor\castor-1.1.1\src\bugs\xml\bug2017\build.xml:34: Java returned: 1
Total time: 3 seconds
Having looked into this, I think that the following patch might address this problem:
Index: C:/workspace/castor112/src/main/java/org/exolab/castor/types/DateTimeBase.java
===================================================================
— C:/workspace/castor112/src/main/java/org/exolab/castor/types/DateTimeBase.java (revision 7038)
+++ C:/workspace/castor112/src/main/java/org/exolab/castor/types/DateTimeBase.java (working copy)
@@ -1315,7 +1315,10 @@
SimpleTimeZone timeZone = new SimpleTimeZone(0,"UTC");
timeZone.setRawOffset(offset);
- timeZone.setID(TimeZone.getAvailableIDs(offset)[0]);
+ String[] availableIDs = TimeZone.getAvailableIDs(offset);
+ if (availableIDs != null && availableIDs.length > 0) { + timeZone.setID(availableIDs[0]); + }calendar.setTimeZone(timeZone);
}
Are you in a position to apply this patch, build the binaries yourself and test ?
I will do that.
If I am reading the patch right, the black square in front of the line with timeZone.setID(...) means replace that line with the lines prefixed by plusses. i.e. the function would now look like this?
protected void setDateFormatTimeZone(Calendar calendar) {
// If no time zone, nothing to do
if (! isUTC()) {
return;
}
int offset = (this.getZoneMinute() + this.getZoneHour() * 60) * 60 * 1000;
offset = isZoneNegative() ? -offset : offset;
SimpleTimeZone timeZone = new SimpleTimeZone(0,"UTC");
timeZone.setRawOffset(offset);
String[] availableIDs = TimeZone.getAvailableIDs(offset);
if (availableIDs != null && availableIDs.length > 0) {
timeZone.setID(availableIDs[0]);
}
calendar.setTimeZone(timeZone);
}
The black dot originaly had been a minus which means the line gets removed while plus marks line that get added by the patch. The patch leads to the function code included with your comment.
The wiki formatting takes some getting used to I suppose. I replaced the method in DateTimeBase with the code above, and ran the unit tests o.k. I will test with our larger application and let you know, although it may not be until tomorrow.
clean:
BUILD SUCCESSFUL
Total time: 0 seconds
C:\bill\castor\castor-1.1.1\src\bugs\xml\bug2017>ant
Buildfile: build.xml
readme:
[echo] Please note, to run this build file, you must copy the castor jars, and necessary castor generator jars to ht lib direct
ory.
generate:
[delete] Deleting: C:\bill\castor\castor-1.1.1\src\bugs\xml\bug2017\Entity.java
[delete] Deleting: C:\bill\castor\castor-1.1.1\src\bugs\xml\bug2017\EntityDescriptor.java
[java] log4j:WARN No appenders could be found for logger (org.exolab.castor.builder.SourceGenerator).
[java] log4j:WARN Please initialize the log4j system properly.
compile:
[javac] Compiling 3 source files to C:\bill\castor\castor-1.1.1\src\bugs\xml\bug2017
test:
[java] log4j:WARN No appenders could be found for logger (org.exolab.castor.xml.ValidationContext).
[java] log4j:WARN Please initialize the log4j system properly.
[java] ..
[java] Time: 0.453
[java]
[java] OK (2 tests)
[java]
BUILD SUCCESSFUL
Total time: 3 seconds
C:\bill\castor\castor-1.1.1\src\bugs\xml\bug2017>
Good news. My morning cleared up, and I was able to test the larger application. It seems to work o.k.
Thanks, Bill, for the (positive) feedback. I will commit this to SVN later on today.
After doing a bit of research, it looks like it is acceptable to have minutes in your offset.
http://en.wikipedia.org/wiki/ISO_8601