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