10

我已经盯着这个短代码太久了,我一生都看不到它如何NullPointerException在第 6 行抛出一个。为什么是 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 而失败。

4

3 回答 3

3

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

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

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

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

于 2012-09-19T15:54:33.463 回答
2

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

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

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

附加说明-在尝试与 1.6u31 一起使用时记录了一个相关问题,parseBoolean这可能会引起人们的兴趣(尽管帮助不大,但描述非常简短):http: //java.net/jira/browse/JAXB- 902 . 这表明这可能仍然是一个持续存在的问题,具体取决于您使用的是 RI 还是其他 JAXB 实现。

于 2012-09-19T18:26:57.407 回答
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;
        }
    }
于 2012-09-19T15:54:26.743 回答