-
Bug
-
Resolution: Not an Issue
-
P3
-
9
FULL PRODUCT VERSION :
java version "9"
Java(TM) SE Runtime Environment (build 9+181)
Java HotSpot(TM) 64-Bit Server VM (build 9+181, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Darwin Kernel Version 14.3.0: Mon Mar 23 11:59:05 PDT 2015; root:xnu-2782.20.48~5/RELEASE_X86_64 x86_64
A DESCRIPTION OF THE PROBLEM :
The new introduced com.sun.xml.internal.bind.v2.runtime.output.XMLStreamWriterOutput$NewLineEscapeHandler can't call into XMLStreamWriter if text length is 0.
Previousely(at least in jdk-9-ea+174), the com.sun.xml.internal.bind.v2.runtime.output.XMLStreamWriterOutput.text(String value, boolean needsSeparatingWhitespace) method is like
public void text(String value, boolean needsSeparatingWhitespace) throws IOException, SAXException, XMLStreamException {
if(needsSeparatingWhitespace)
out.writeCharacters(" ");
out.writeCharacters(value);
}
So even the String value length is 0, out.writeCharacters(value) is still invoked, so that the underlying XMLStreamWriter get chance to handle this case, like put specify text meaningful in the output payload.
But in JDK9 GA it becomes
public void text(String value, boolean needsSeparatingWhitespace) throws IOException, SAXException, XMLStreamException {
if(needsSeparatingWhitespace)
out.writeCharacters(" ");
escapeHandler.escape(value.toCharArray(), 0, value.length(), false, writerWrapper);
}
And this new introduced XMLStreamWriterOutput$NewLineEscapeHandler is
public void escape(char[] ch, int start, int length, boolean isAttVal, Writer out) throws IOException {
int limit = start+length;
int lastEscaped = start;
for (int i = start; i < limit; i++) {
char c = ch[i];
if (c == '\r' || c == '\n') {
if (i != lastEscaped) {
out.write(ch, lastEscaped, i - lastEscaped);
}
lastEscaped = i + 1;
if (out instanceof XmlStreamOutWriterAdapter) {
try {
((XmlStreamOutWriterAdapter)out).writeEntityRef("#x" + Integer.toHexString(c));
} catch (XMLStreamException e) {
throw new IOException("Error writing xml stream", e);
}
} else {
out.write("&#x");
out.write(Integer.toHexString(c));
out.write(';');
}
}
}
if (lastEscaped != limit) { //here if char[] ch lenght is 0, then there's no way to run into the out.write
out.write(ch, lastEscaped, length - lastEscaped);
}
}
So if the String value length is 0, it would skip the out.write(...) so that the XMLStreamWriter never get called.
This different behavior cause that the underlying XMLStreamWriter lost chance to put any meaningful text into the output payload when the String value is empty.
For example, with previous expected behavior, we can get a payload like
{"Book":{"id":123,"name":"MyName","state":"state length is actually 0"}}
if state is an empty string actually as we can override the XMLStreamWriter.writeCharacters(text) method and detect if the text is empty and output anything meaningful for us.
However, with the JDK9 GA the output payload is
{"Book":{"id":123,"name":"MyName","state":""}}
as underlying XMLStreamWriter lost chance to handle when text is empty
REGRESSION. Last worked in version 8u144
ADDITIONAL REGRESSION INFORMATION:
It worked in
jdk-9-ea+174
REPRODUCIBILITY :
This bug can be reproduced always.
java version "9"
Java(TM) SE Runtime Environment (build 9+181)
Java HotSpot(TM) 64-Bit Server VM (build 9+181, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Darwin Kernel Version 14.3.0: Mon Mar 23 11:59:05 PDT 2015; root:xnu-2782.20.48~5/RELEASE_X86_64 x86_64
A DESCRIPTION OF THE PROBLEM :
The new introduced com.sun.xml.internal.bind.v2.runtime.output.XMLStreamWriterOutput$NewLineEscapeHandler can't call into XMLStreamWriter if text length is 0.
Previousely(at least in jdk-9-ea+174), the com.sun.xml.internal.bind.v2.runtime.output.XMLStreamWriterOutput.text(String value, boolean needsSeparatingWhitespace) method is like
public void text(String value, boolean needsSeparatingWhitespace) throws IOException, SAXException, XMLStreamException {
if(needsSeparatingWhitespace)
out.writeCharacters(" ");
out.writeCharacters(value);
}
So even the String value length is 0, out.writeCharacters(value) is still invoked, so that the underlying XMLStreamWriter get chance to handle this case, like put specify text meaningful in the output payload.
But in JDK9 GA it becomes
public void text(String value, boolean needsSeparatingWhitespace) throws IOException, SAXException, XMLStreamException {
if(needsSeparatingWhitespace)
out.writeCharacters(" ");
escapeHandler.escape(value.toCharArray(), 0, value.length(), false, writerWrapper);
}
And this new introduced XMLStreamWriterOutput$NewLineEscapeHandler is
public void escape(char[] ch, int start, int length, boolean isAttVal, Writer out) throws IOException {
int limit = start+length;
int lastEscaped = start;
for (int i = start; i < limit; i++) {
char c = ch[i];
if (c == '\r' || c == '\n') {
if (i != lastEscaped) {
out.write(ch, lastEscaped, i - lastEscaped);
}
lastEscaped = i + 1;
if (out instanceof XmlStreamOutWriterAdapter) {
try {
((XmlStreamOutWriterAdapter)out).writeEntityRef("#x" + Integer.toHexString(c));
} catch (XMLStreamException e) {
throw new IOException("Error writing xml stream", e);
}
} else {
out.write("&#x");
out.write(Integer.toHexString(c));
out.write(';');
}
}
}
if (lastEscaped != limit) { //here if char[] ch lenght is 0, then there's no way to run into the out.write
out.write(ch, lastEscaped, length - lastEscaped);
}
}
So if the String value length is 0, it would skip the out.write(...) so that the XMLStreamWriter never get called.
This different behavior cause that the underlying XMLStreamWriter lost chance to put any meaningful text into the output payload when the String value is empty.
For example, with previous expected behavior, we can get a payload like
{"Book":{"id":123,"name":"MyName","state":"state length is actually 0"}}
if state is an empty string actually as we can override the XMLStreamWriter.writeCharacters(text) method and detect if the text is empty and output anything meaningful for us.
However, with the JDK9 GA the output payload is
{"Book":{"id":123,"name":"MyName","state":""}}
as underlying XMLStreamWriter lost chance to handle when text is empty
REGRESSION. Last worked in version 8u144
ADDITIONAL REGRESSION INFORMATION:
It worked in
jdk-9-ea+174
REPRODUCIBILITY :
This bug can be reproduced always.