one java code behave differ on 2 differ pc

空扰寡人 提交于 2019-12-11 19:26:55

问题


I have simple JAXB unmarshalling code.

package com.example;
import java.io.StringReader;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import javax.xml.transform.stream.StreamSource;

public class Main {

    public static void main(String[] args) {

        try {
        StringBuilder xml = new StringBuilder();
        xml.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>")
            .append("<item><pubDate>Thu, 12 May 2016 08:44:05 +0000</pubDate></item>");

        JAXBContext jaxbContext = JAXBContext.newInstance(Item.class);
        Unmarshaller jaxbMarshaller = jaxbContext.createUnmarshaller();

        StreamSource ss = new StreamSource(new StringReader( xml.toString()));
        Item example = (Item) jaxbMarshaller.unmarshal(ss);
        System.out.println(example);
      } catch (Exception e) {
        System.out.println("exception "+e);
            e.printStackTrace();
          }
    }
}

Item class:

package com.example;

import java.util.Date;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

@XmlRootElement(name = "item")
@XmlAccessorType(XmlAccessType.NONE)
public class Item {

    @XmlElement(name = "pubDate")
    @XmlJavaTypeAdapter(MyDateFormatAdapter.class)
    private Date pubDate;

    public String toString() {
        return "Item:"+this.pubDate.toString();
    }

    public Date getPubDate() {
        return pubDate;
    }

    public void setPubDate(Date pubDate) {
        this.pubDate = pubDate;
    }


}

and MyDateFormatAdapter class

package com.example;


import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.xml.bind.annotation.adapters.XmlAdapter;

public class MyDateFormatAdapter extends XmlAdapter<String, Date> {

    private static final String FORMAT = "EEE, dd MMM yyyy HH:mm:ss Z";

    public Date unmarshal(String v) throws Exception {
        DateFormat dateFormat = new SimpleDateFormat(FORMAT);
        return dateFormat.parse(v);
    }

    public String marshal(Date d) throws Exception { 
        DateFormat dateFormat = new SimpleDateFormat(FORMAT);
        String formattedDate = dateFormat.format(d);
        return formattedDate; 

    }

}

So, on the first pc(windows 7, jdk 1.7) code fails with NullPointerException at line System.out.println(example); on the second pc(windows 7, jdk 1.7) it work ok. Returns Item:Thu May 12 10:44:05 CEST 2016 I can't figure out what is the reason of such behavior. Maybe some assumption?

UPDATED: When I'm removing annotation @XmlJavaTypeAdapter(MyDateFormatAdapter.class) the code become work as on laptop and throws the same exceptions

 exception java.lang.NullPointerException
    java.lang.NullPointerException
        at com.example.Item.toString(Item.java:21)
        at java.lang.String.valueOf(String.java:2849)
        at java.io.PrintStream.println(PrintStream.java:821)
        at com.example.Main.main(Main.java:27)
        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:606)
        at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)

回答1:


Your MyDateFormatAdapter depends on the default platform locale of the JVM.

If that locale is not an english locale it will not be able to parse Thu for date pattern EEE. In this case dateFormat.parse will throw a ParseException. The Unmarshaller catches that exception but then the pubDate member will be initialized to null.

As a consequence your Item.toString raises a NPE since it relies on a non null pubDate value.

Solution: Specify a locale when you create the DateFormat.

public class MyDateFormatAdapter extends XmlAdapter<String, Date> {

    private static final DateFormat dateFormat = 
        new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z", Locale.US);

    @Override public Date unmarshal(String v) throws Exception {
        return dateFormat.parse(v);
    }

    @Override public String marshal(Date d) throws Exception { 
        return dateFormat.format(d);
    }
}


来源:https://stackoverflow.com/questions/37701854/one-java-code-behave-differ-on-2-differ-pc

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!