0

我最近升级到 Java 7,我注意到 XML 序列化的一个奇怪问题。基本上,我有一个测试实用程序类,它使用 XML 编码器进行对象到 XML 的转换。

请参阅下面的示例代码:

public static String toXML(Object obj) {
    String retval = null;

    if(obj != null) {
        XMLEncoder encoder = null;
        ByteArrayOutputStream bos;

        try {
            bos = new ByteArrayOutputStream();
            encoder = new XMLEncoder(bos);
            encoder.writeObject(obj);
            encoder.close();
            byte[] bytes = bos.toByteArray();
            if(bytes != null) {
                retval = new String(bytes);
            }

        } catch(Exception e) {
            e.printStackTrace();

        } finally {
            if(encoder != null) {
                encoder.close();
            }
        }
    }
    return retval;
}

这在 Java 1.6 上运行良好,但是自从我升级到 Java 1.7 后,我注意到 XML 编码器操作在日志中引发了 IOException:

java.io.IOException: Stream closed
at sun.nio.cs.StreamEncoder.ensureOpen(StreamEncoder.java:45)
at sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:140)
at java.io.OutputStreamWriter.flush(OutputStreamWriter.java:229)
at java.beans.XMLEncoder.flush(XMLEncoder.java:497)
at java.beans.XMLEncoder.close(XMLEncoder.java:530)
at com.mytestcode.server.common.util.TestSerializer.toXML(TestSerializer.java:87)

我查看了 XMLEncoder 代码,发现 StreamEncoder.ensureOpen 对 isOpen 进行了检查,这似乎是错误的。

这个问题看起来很相似,尽管它没有使用 Java 1.7 XML 编码器。我没有看到 XML 编码器或这种方法的这个问题,有什么我可以在代码中修复的问题,或者这看起来更下游吗?我错过了什么?

4

1 回答 1

0

我终于能够弄清楚这一点。问题在于 Java 6 到 7 的升级。

Java 6 和 7 之间的差异,XMLEncoder 表明,在 Java 6 中,XML 编码器直接在构造函数中传递的 ByteArrayOutputStream 上工作,而在 Java 7 中,XMLEncoder 将 StreamEncoder 包装在构造函数中传递的 ByteArrayOutputStream 周围。

(第 289 行)

http://grepcode.com/file_/repository.grepcode.com/java/root/jdk/openjdk/7-b147/java/beans/XMLEncoder.java/?v=diff&id2=6-b14

虽然调用 ByteArrayOutputStream.close()(请参阅 Javadoc)绝对不会执行任何操作,但如果 Stream 已关闭,则 StreamEncoder.close()(请参阅 Javadoc)会引发可恢复的 IOException。

此异常被拾取默认的 ExceptionListener 并记录在日志中。

于 2013-12-19T22:52:22.033 回答