2010-03-23 5 views
3

Les travaux suivants:xsd: datetime et XmlGregorianCalendar provoque NullPointerException

public Date getDate() { 
    return date; 
} 

et produit quelque chose comme:

<date>2010-03-23T17:43:50.879Z</date> 

Et je peux utiliser un XmlGregorianCalendar pour revenir xsd: date ou xsd: types temps bien :

@XmlSchemaType(name="date") 
public XmlGregorianCalendar getDate() { 
    return date; 
} 

qui produit quelque chose comme:

<date>2010-03-23</date> 

Mais en essayant de revenir xsd: datetime comme ceci:

@XmlSchemaType(name="datetime") 
public XmlGregorianCalendar getDate() { 
    return date; 
} 

Causes cette trace de la pile:

java.lang.NullPointerException 
    at com.sun.xml.bind.v2.model.impl.RuntimeBuiltinLeafInfoImpl.checkXmlGregorianCalendarFieldRef(RuntimeBuiltinLeafInfoImpl.java:864) 
    at com.sun.xml.bind.v2.model.impl.RuntimeBuiltinLeafInfoImpl.access$200(RuntimeBuiltinLeafInfoImpl.java:111) 
    at com.sun.xml.bind.v2.model.impl.RuntimeBuiltinLeafInfoImpl$13.print(RuntimeBuiltinLeafInfoImpl.java:536) 
...snip... 
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852) 
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588) 
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489) 
    at java.lang.Thread.run(Thread.java:619) 

qui ne mentionne pas mon code du tout.

J'utilise tomcat 6.0.24, java 1.6.0_16-b01

Répondre

8

Eh bien, je trouve le problème fondamental: Il devrait être "dateTime" pas "datetime", mais il y a un certain nombre d'aspects plus profonds à ce sujet. D'abord, la trace m'a donné très peu d'aide, et il m'a fallu un certain temps pour trouver la bonne source (jaxb-ri-2_2.src.zip). Ligne 864 est la suivante:

int bitField = xmlGregorianCalendarFieldRef.get(type); 

et xmlGregorianCalendarFieldRef est défini comme:

private static final Map<QName, Integer> xmlGregorianCalendarFieldRef = 
      new HashMap<QName, Integer>(); 
    static { 
      Map<QName, Integer> f = xmlGregorianCalendarFieldRef; 
      f.put(DatatypeConstants.DATETIME, 0x1111111); 
      f.put(DatatypeConstants.DATE,  0x1111000); 
      f.put(DatatypeConstants.TIME,  0x1000111); 
      f.put(DatatypeConstants.GDAY,  0x1001000); 
      f.put(DatatypeConstants.GMONTH,  0x1010000); 
      f.put(DatatypeConstants.GYEAR,  0x1100000); 
      f.put(DatatypeConstants.GYEARMONTH, 0x1110000); 
      f.put(DatatypeConstants.GMONTHDAY, 0x1011000); 
    } 

Alors xmlGregorianCalendarFieldRef ne peut lui-même être nul, mais si get() est appelée avec une clé qui ne figure pas sur la carte , il renverra null, et le NullPointerException sera jeté quand la JVM essaye de la déballer.

Ce code est un peu bâclé; la valeur du type n'est pas vérifiée, c'est pourquoi nous obtenons ce message plutôt cryptique.

Évidemment, j'ai alors recherché la valeur de DatatypeConstants.DATETIME et trouvé l'erreur de cas.

Il me conduit également à croire que je devrais probablement utiliser quelque chose comme:

@XmlSchemaType(name=DatatypeConstants.DATETIME) 
public XmlGregorianCalendar getDate() { 
    return date; 
} 

Pour une meilleure protection, mais cette constante est un QName pas une chaîne.