xsd: datetime и XmlGregorianCalendar вызывает исключение NullPointerException - PullRequest
3 голосов
/ 23 марта 2010

работают следующие работы:

public Date getDate() {
    return date;
}

и производит что-то вроде:

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

И я могу использовать XmlGregorianCalendar для возврата xsd: date или xsd: time штрафов:

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

, который производит что-то вроде:

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

Но пытаюсь вернуть xsd: datetime, вот так:

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

Вызывает эту трассировку стека:

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)

Который вообще не упоминает мой код.

Я использую Tomcat 6.0.24, Java 1.6.0_16-b01

1 Ответ

9 голосов
/ 24 марта 2010

Ну, я нашел основную проблему: это должно быть "dateTime", а не "datetime", однако в этом есть ряд более глубоких аспектов.

Во-первых, трассировка дала мне очень мало помощи, и мне потребовалось некоторое время, чтобы найти правильный источник (jaxb-ri-2_2.src.zip). Строка 864 выглядит так:

int bitField = xmlGregorianCalendarFieldRef.get(type);

и xmlGregorianCalendarFieldRef определяется как:

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

Так что xmlGregorianCalendarFieldRef само по себе не может быть нулевым, но если get() вызывается с ключом, которого нет на карте, он вернет ноль, и NullPointerException будет сброшен при попытке JVM распаковать его.

Этот код немного неаккуратный; значение типа не проверяется, поэтому мы получаем это довольно загадочное сообщение.

Очевидно, я тогда посмотрел значение DatatypeConstants.DATETIME и обнаружил ошибку в регистре.

Это также заставляет меня поверить, что я, вероятно, должен использовать что-то вроде:

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

Для дополнительной защиты , но эта константа - QName, а не строка.

...