Closed wolfkang closed 11 years ago
Thanks for bringing this to our attention!
As a workaround, to unblock your app, you can set the thread locale to UTC or US locale.
We will investigate the root cause of this issue and try to issue a fix soon.
I started digging into this issue, and StdDeserializationContext
uses StdDateFormat
, which uses the standard SimpleDateFormat
but does not set its calendar
field:
Subclasses should initialize this field to a Calendar appropriate for the Locale associated with this DateFormat.
So, it seems like the fix will need to inject a serializer that uses a locale-invariant calendar.
I ran the unit tests after setting my Windows Control Panel\Clock, Language, and Region\Language date,time,format settings as Arabic (Saudi Arabic). Here are the failures,along with the test that failed:
java.lang.IllegalArgumentException: org.codehaus.jackson.map.JsonMappingException: Can not construct instance of java.util.Date from String value ' Fri, 14 Oct 2011 12:34:56 GMT': not a valid representation (error: Can not parse date "Fri, 14 Oct 2011 12:34:56 GMT": not compatible with any of standard forms ("yyyy-MM-dd'T'HH:mm:ss.SSSZ", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "EEE, dd MMM yyyy HH:mm:ss zzz", "yyyy-MM-dd"))
org.junit.ComparisonFailure: expected:<"[Thu, 14 Oct] 1971 12:34:56 GMT"> but was:<"[خ, 14 أكت] 1971 12:34:56 GMT">
java.lang.ClassCastException: java.lang.String cannot be cast to java.util.Date
It looks like they are all localized to the SB serializer (haha, I crack myself up)
candidate
Also see the MSDN forum here. I believe it was started by @wolfkang but there is another person running into this issue.
the msdn forum post was written by Donghyeok Kang, the same family name different first name. They could be brothers.
In the above document, there is a setLocale method of ObjectMapper, which may be usful. Why it doesn't show up in my Eclipse?
we do not reference jackson explicitly in hte code, how do we figure out which version of jackson that we are using.
we use 1.9.2 ...
it seems in 1.9.4, the setLocale method still hasn't been implemented. http://jackson.codehaus.org/1.9.4/javadoc/
another approach appears to be more promising http://stackoverflow.com/questions/5591967/jackson-date-deserialization
here is the official guide. http://wiki.fasterxml.com/JacksonFAQDateHandling
next question, what date format we should use...
here is a sample date Thu, 21 Mar 2013 01:01:11 GMT
EEE, dd MMM yyyy HH:mm:ss zzz
Eee, dd Mmm yyyy hh:mm:ss ZZZ
That looks like RFC-1123
I end up using EEE, dd MMM yyyy HH:mm:ss zzz, which is identical to a format in the original message saying "doesn't work". Yes, I believe it is RFC1123
next step, change the locale of my machine to korea, then run the unit tests again.
doesn't fix the problem on my korea machine ... :(
java.lang.IllegalArgumentException: org.codehaus.jackson.map.JsonMappingException: Can not construct instance of java.util.Date from String value 'Thu, 21 Mar 2013 18:03:43 GMT': not a valid representation (error: Unparseable date: "Thu, 21 Mar 2013 18:03:43 GMT") at [Source: [B@1218cdf2; line: 1, column: 97](through reference chain: com.microsoft.windowsazure.services.serviceBus.implementation.BrokerProperties["LockedUntilUtc"]) at com.microsoft.windowsazure.services.serviceBus.implementation.BrokerPropertiesMapper.fromString(BrokerPropertiesMapper.java:41) at com.microsoft.windowsazure.services.serviceBus.implementation.ServiceBusRestProxy.receiveMessage(ServiceBusRestProxy.java:188) at com.microsoft.windowsazure.services.serviceBus.implementation.ServiceBusRestProxy.receiveQueueMessage(ServiceBusRestProxy.java:152) at com.microsoft.windowsazure.services.serviceBus.implementation.ServiceBusExceptionProcessor.receiveQueueMessage(ServiceBusExceptionProcessor.java:109) at com.microsoft.windowsazure.services.serviceBus.ServiceBusIntegrationTest.peekLockMessageWorks(ServiceBusIntegrationTest.java:183) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:601) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28) at org.junit.runners.ParentRunner.run(ParentRunner.java:300) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) Caused by: org.codehaus.jackson.map.JsonMappingException: Can not construct instance of java.util.Date from String value 'Thu, 21 Mar 2013 18:03:43 GMT': not a valid representation (error: Unparseable date: "Thu, 21 Mar 2013 18:03:43 GMT") at [Source: [B@1218cdf2; line: 1, column: 97](through reference chain: com.microsoft.windowsazure.services.serviceBus.implementation.BrokerProperties["LockedUntilUtc"]) at org.codehaus.jackson.map.JsonMappingException.from(JsonMappingException.java:163) at org.codehaus.jackson.map.deser.StdDeserializationContext.weirdStringException(StdDeserializationContext.java:243) at org.codehaus.jackson.map.deser.std.StdDeserializer._parseDate(StdDeserializer.java:553) at org.codehaus.jackson.map.deser.std.DateDeserializer.deserialize(DateDeserializer.java:28) at org.codehaus.jackson.map.deser.std.DateDeserializer.deserialize(DateDeserializer.java:19) at org.codehaus.jackson.map.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:299) at org.codehaus.jackson.map.deser.SettableBeanProperty$MethodProperty.deserializeAndSet(SettableBeanProperty.java:414) at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:697) at org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:580) at org.codehaus.jackson.map.ObjectMapper._readMapAndClose(ObjectMapper.java:2723) at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:1926) at com.microsoft.windowsazure.services.serviceBus.implementation.BrokerPropertiesMapper.fromString(BrokerPropertiesMapper.java:35) ... 29 more
I can repro the problem in unit test now, do not need to keep my machine in korean locale all the time.
strange, according to the documentation, it should support RFC-1123 whatever http://jackson.codehaus.org/1.1.2/javadoc/org/codehaus/jackson/map/util/StdDateFormat.html
it turns out to be a problem of the underlying library.
The above record shows that this issue has been fixed in version 2.0 of jackson, time for an upgrade?
I fixed it on our side anyway.
Set locale of my machine to Chinese (Simplified, China) and the Service Bus tests.
com.microsoft.windowsazure.services.serviceBus
all pass!com.microsoft.windowsazure.services.serviceBus.implementation
, which indicates that those tests are not actually testing the BrokerPropertiesMapper
directly. I suspect that if the tests use BrokerPropertiesMapper
, they would pass.supportedFormatsHaveExpectedJavaTypes(com.microsoft.windowsazure.services.serviceBus.implementation.CustomPropertiesMapperTest)
java.lang.ClassCastException: java.lang.String cannot be cast to java.util.Date
at com.microsoft.windowsazure.services.serviceBus.implementation.CustomPropertiesMapperTest.supportedFormatsHaveExpectedJavaTypes(CustomPropertiesMapperTest.java:119)
...
supportedJavaTypesHaveExpectedRepresentations(com.microsoft.windowsazure.services.serviceBus.implementation.CustomPropertiesMapperTest)
org.junit.ComparisonFailure: expected:<"[Thu, 14 Oct] 1971 12:34:56 GMT"> but was:<"[星期四, 14 十月] 1971 12:34:56 GMT">
at org.junit.Assert.assertEquals(Assert.java:125)
at org.junit.Assert.assertEquals(Assert.java:147)
at com.microsoft.windowsazure.services.serviceBus.implementation.CustomPropertiesMapperTest.supportedJavaTypesHaveExpectedRepresentations(CustomPropertiesMapperTest.java:83)
...
Same errors when using Arabic (Saudi Arabia)
supportedFormatsHaveExpectedJavaTypes(com.microsoft.windowsazure.services.serviceBus.implementation.CustomPropertiesMapperTest)
java.lang.ClassCastException: java.lang.String cannot be cast to java.util.Date
...
supportedJavaTypesHaveExpectedRepresentations(com.microsoft.windowsazure.services.serviceBus.implementation.CustomPropertiesMapperTest)
org.junit.ComparisonFailure: expected:<"[Thu, 14 Oct] 1971 12:34:56 GMT"> but was:<"[خ, 14 أكت] 1971 12:34:56 GMT">
...
Looks good!
Dev estimate: 3 Test estimate: 1
Hi. I'm from Korea and the time locale of my computer is not set as UTC. I got the exception like this when receiving a message from the service bus queue.
org.codehaus.jackson.map.JsonMappingException: Can not construct instance of java.util.Date from String value 'Tue, 05 Mar 2013 10:30:52 GMT': not a valid representation (error: Can not parse date "Tue, 05 Mar 2013 10:30:52 GMT": not compatible with any of standard forms ("yyyy-MM-dd'T'HH:mm:ss.SSSZ", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "EEE, dd MMM yyyy HH:mm:ss zzz", "yyyy-MM-dd")) at [Source: [B@3e68cd21; line: 1, column: 97](through reference chain: com.microsoft.windowsazure.services.serviceBus.implementation.BrokerProperties["LockedUntilUtc"]) at org.codehaus.jackson.map.JsonMappingException.from(JsonMappingException.java:163) at org.codehaus.jackson.map.deser.StdDeserializationContext.weirdStringException(StdDeserializationContext.java:243) at org.codehaus.jackson.map.deser.std.StdDeserializer._parseDate(StdDeserializer.java:577) at org.codehaus.jackson.map.deser.std.DateDeserializer.deserialize(DateDeserializer.java:28) at org.codehaus.jackson.map.deser.std.DateDeserializer.deserialize(DateDeserializer.java:19) at org.codehaus.jackson.map.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:299) at org.codehaus.jackson.map.deser.SettableBeanProperty$MethodProperty.deserializeAndSet(SettableBeanProperty.java:414) at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:697) at org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:580) at org.codehaus.jackson.map.ObjectMapper._readMapAndClose(ObjectMapper.java:2732) at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:1935) at com.microsoft.windowsazure.services.serviceBus.implementation.BrokerPropertiesMapper.fromString(BrokerPropertiesMapper.java:31) at com.microsoft.windowsazure.services.serviceBus.implementation.ServiceBusRestProxy.receiveMessage(ServiceBusRestProxy.java:187) at com.microsoft.windowsazure.services.serviceBus.implementation.ServiceBusRestProxy.receiveQueueMessage(ServiceBusRestProxy.java:151) at com.microsoft.windowsazure.services.serviceBus.implementation.ServiceBusExceptionProcessor.receiveQueueMessage(ServiceBusExceptionProcessor.java:109)
Thanks.