Java IOException при сбросе XMLEncoder

Я недавно обновился до 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-кодировщиком или с этим методом в целом, есть ли что-то, что я могу исправить в коде, или это кажется более нисходящим? Что мне не хватает?

1 ответ

Решение

Я наконец смог понять это. Проблема была из-за Java от 6 до 7 upgarde.

В отличие от 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) абсолютно ничего не делает, StreamEncoder.close() (см. Javadoc) генерирует восстанавливаемое исключение IOException, если поток уже закрыт.

Это исключение выбирается по умолчанию ExceptionListener и регистрируется в журналах.

Другие вопросы по тегам