为什么NPE使用DatatypeConverter的静态方法?

时间:2012-09-19 15:47:09

标签: java string nullpointerexception base64 type-conversion

我已经盯着这个简短的代码太久了,并且不能在我的生活中看到它如何在第6行抛出NullPointerException。为什么是NPE?

class ConvertTest {

    public static void main(String[] args) throws Exception {
        byte[] b = "Ha".getBytes("UTF-8");
        System.out.println("bytes: " + b.length);
        javax.xml.bind.DatatypeConverter.printBase64Binary(b);  // NPE!
    }
}

输出

bytes: 2
Exception in thread "main" java.lang.NullPointerException
        at javax.xml.bind.DatatypeConverter.printBase64Binary(DatatypeConverter.java:547)
        at ConvertTest.main(ConvertTest.java:6)
Press any key to continue . . .

更新

虽然许多错误报告都指向1.7版本,但我很惊讶Eclipse已配置为使用1.6.0_32& TextPad找到了1.6.0-b105的版本(甚至没有意识到已经安装了!)。

两个JRE都因NPE而失败。

3 个答案:

答案 0 :(得分:3)

现在JDK7中的JAXB似乎有bug,正如Camel上的这个问题所证明的那样:

https://issues.apache.org/jira/browse/CAMEL-4893

最终链接到java.net上的JAXB项目中的此问题https://github.com/javaee/jaxb-v2/issues/860

我不完全确定你是否遇到了同样的事情,但也许尝试使用JDK6和最新的JAXB版本,看看是否发生了相同的NPE。

答案 1 :(得分:2)

如果没有环境的细节,我无法确定是否是这种情况,但如果您使用的是JAXB RI,则可能会遇到此JAXB错误所描述的问题:http://java.net/jira/browse/JAXB-761

虽然该bug没有专门解决您遇到的问题(它与parseDate方法有关),但根本原因可能相同。它在JAXB的2.2.1版本中检测到,但可能在2.1.x版本中预先存在,而JAXB 2.1.1似乎是集成到1.6中的最新版本(集成在1.6u14中)。

该问题表明它是通过JAXB 2.2.4解决的,它已集成到1.7中。

附加说明 - 有关parseBoolean尝试使用1.6u31的NPE时记录了一个相关问题,这可能是有意义的(虽然帮助不大,描述很短) :http://java.net/jira/browse/JAXB-902。这表明这仍然是一个持续的问题,具体取决于您是使用RI还是其他JAXB实现。

答案 2 :(得分:1)

public static String printBase64Binary( byte[] val ) {
    return theConverter.printBase64Binary( val );
}
  

JAXB提供程序需要调用setDatatypeConverter api   在第一次元帅或解散行动之前的一些点(也许是   在调用JAXBContext.newInstance期间)。这一步是必要的   配置应该用于执行打印的转换器   解析功能

尝试先设置转换器

/**
     * This method is for JAXB provider use only.
     * <p>
     * JAXB Providers are required to call this method at some point before
     * allowing any of the JAXB client marshal or unmarshal operations to
     * occur.  This is necessary to configure the datatype converter that 
     * should be used to perform the print and parse conversions.
     * 
     * <p>
     * Calling this api repeatedly will have no effect - the 
     * DatatypeConverterInterface instance passed into the first invocation is 
     * the one that will be used from then on.
     * 
     * @param converter an instance of a class that implements the 
     * DatatypeConverterInterface class - this parameter must not be null.
     * @throws IllegalArgumentException if the parameter is null
     */
    public static void setDatatypeConverter( DatatypeConverterInterface converter ) {
        if( converter == null ) {
            throw new IllegalArgumentException( 
                Messages.format( Messages.CONVERTER_MUST_NOT_BE_NULL ) );
        } else if( theConverter == null ) {
            theConverter = converter;
        }
    }