【问题标题】:Why the NPE using static method of DatatypeConverter?为什么 NPE 使用 DatatypeConverter 的静态方法?
【发布时间】:2012-09-11 23:18:33
【问题描述】:

我已经盯着这个短代码太久了,我一辈子都看不到它如何在第 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 而失败。

【问题讨论】:

  • 哇!安德鲁汤普森在问一个问题:D
  • 我没有收到任何 NPE。输出字节数:2. 在 Netbeans 中运行完全相同的代码。
  • @Eng.Fouad 你不认为我建立了 50K 代表。你一无所有?我用它作为我的问题的赏金。 ;)
  • 会不会和this有关?
  • 查看 jdk 源代码,DatatypeConverter 使用内部 impl。这个 impl 为 null 是唯一可能导致 NPE 的事情。这似乎与@RoddyoftheFrozenPeas 的建议一致,即该问题与混淆/冲突的 jaxb 库有关。

标签: java string nullpointerexception base64 type-conversion


【解决方案1】:

现在 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。

【讨论】:

    【解决方案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 的 NPE 相关的相关问题,这可能很有趣(虽然帮助不大,但描述非常简短):@ 987654322@。这表明这可能仍然是一个持续存在的问题,具体取决于您使用的是 RI 还是其他 JAXB 实现。

    【讨论】:

      【解决方案3】:
      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;
              }
          }
      

      【讨论】:

      • 您不必自己打这个电话。 jaxb 提供者应该这样做。
      • 但此时可能 jaxb 提供程序未正确初始化/配置。
      猜你喜欢
      • 2018-10-27
      • 2011-03-02
      • 1970-01-01
      • 2015-04-05
      • 2015-08-04
      • 2015-11-13
      • 2016-12-23
      • 1970-01-01
      相关资源
      最近更新 更多