Issue
I'm moving a project to Java11
I already changed sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl
with java.lang.reflect.ParameterizedType
(as specified href="https://panlw.github.io/15358753472382.html#fixing-sun-and-com-sun-imports" rel="nofollow noreferrer">here), now is the turn of MalformedByteSequenceException
:
warning: MalformedByteSequenceException is internal proprietary API and may be removed in a future release import com.sun.org.apache.xerces.internal.impl.io.MalformedByteSequenceException;
it's being use in a snippet of code that create objects from XML files. More precisely in a try-catch
.
try {
...
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(stream);
NodeList list = document.getChildNodes();
fillProcessStack(document);
...
list = list.item(0).getChildNodes();
createItems(list, parent);
} catch (MalformedByteSequenceException e) {
//"Any char in your xml file has a wrong format: " + e.getLocalizedMessage()
} catch (SAXParseException sax) {
...
} catch (Exception e) {
...
}
Anyway I cant find anything online regarding this.
The closest I can think of is UnsupportedEncodingException
, but I'm not sure.
Also, it's possible this is a relict of some old code copied from the net, and apparently if I remove it everything looks still fine for the compiler.
So, is there any general/good recommendations about it regarding Java11?
Edit: for the guy seeking to close this question because
Questions seeking debugging help ("why isn't this code working?") must include the desired behavior, a specific problem or error and the shortest code necessary to reproduce it in the question itself. Questions without a clear problem statement are not useful to other readers. See: How to create a Minimal, Reproducible Example.
I'll try to be explain clearer.
There is no debugging help here, in Java11 some packages are not exported to public, like sun.*
and they shouldnt be used normally (unless specific conditions). Code works fine under jdk8, but under ojdk11 it complains, so I could either use some workarounds to make them visible anyway at runtime or make it right and get rid of them. The latter is what I'm trying to do.
Given I couldn't find anything online, I'm asking here.
Solution
MalformedByteSequenceException
extends CharConversionException
, which extends IOException
, which the parse
method forces you to catch anyway. So when catching IOException
or CharConversionException
, you’ll also catch MalformedByteSequenceException
if thrown directly.
However there seems to be a behavioral change of the XML parser in JDK 11. When I try, e.g.
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new ByteArrayInputStream(new byte[] { 1, 2, 3, -5 }));
I get
Exception in thread "main" org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; Invalid byte 1 of 1-byte UTF-8 sequence.
at java.xml/com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:262)
at java.xml/com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:339)
at java.xml/javax.xml.parsers.DocumentBuilder.parse(DocumentBuilder.java:122)
at TestXmlParser.main(TestXmlParser.java:14)
Caused by: com.sun.org.apache.xerces.internal.impl.io.MalformedByteSequenceException: Invalid byte 1 of 1-byte UTF-8 sequence.
at java.xml/com.sun.org.apache.xerces.internal.impl.io.UTF8Reader.invalidByte(UTF8Reader.java:702)
at java.xml/com.sun.org.apache.xerces.internal.impl.io.UTF8Reader.read(UTF8Reader.java:568)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.load(XMLEntityScanner.java:1904)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.arrangeCapacity(XMLEntityScanner.java:1770)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.skipString(XMLEntityScanner.java:1808)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLVersionDetector.determineDocVersion(XMLVersionDetector.java:158)
at java.xml/com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:860)
at java.xml/com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:824)
at java.xml/com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
at java.xml/com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:246)
... 3 more
instead of the
Exception in thread "main" com.sun.org.apache.xerces.internal.impl.io.MalformedByteSequenceException: Invalid byte 1 of 1-byte UTF-8 sequence.
at com.sun.org.apache.xerces.internal.impl.io.UTF8Reader.invalidByte(UTF8Reader.java:684)
at com.sun.org.apache.xerces.internal.impl.io.UTF8Reader.read(UTF8Reader.java:554)
at com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.load(XMLEntityScanner.java:1742)
at com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.arrangeCapacity(XMLEntityScanner.java:1619)
at com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.skipString(XMLEntityScanner.java:1657)
at com.sun.org.apache.xerces.internal.impl.XMLVersionDetector.determineDocVersion(XMLVersionDetector.java:193)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:772)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:737)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:119)
at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:232)
at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:284)
at javax.xml.parsers.DocumentBuilder.parse(DocumentBuilder.java:124)
at TestXmlParser.main(TestXmlParser.java:14)
of previous versions.
In other words, parse
now throws a SAXParseException
with a cause initialized to a MalformedByteSequenceException
. So, to detect that the problem is a malformed byte sequence, resp. text in the wrong encoding, you’d need something like
catch(SAXException ex) {
if(ex.getCause() instanceof CharConversionException) {
System.out.println("maformed bytes or wrong encoding: "+ex.getMessage());
}
}
To handle newer and older versions, you’d need something like
catch(CharConversionException ex) {
System.out.println("malformed bytes or wrong encoding: "+ex.getMessage());
}
catch(SAXException ex) {
if(ex.getCause() instanceof CharConversionException) {
System.out.println("malformed bytes or wrong encoding: "+ex.getMessage());
}
}
resp.
catch(CharConversionException ex) {
handle(ex);
}
catch(SAXException ex) {
if(ex.getCause() instanceof CharConversionException) {
handle((CharConversionException)ex.getCause());
}
}
…
static void handle(CharConversionException ex) {
// just an example
System.out.println("malformed bytes or wrong encoding: "+ex.getMessage());
}
Answered By - Holger
Answer Checked By - Timothy Miller (JavaFixing Admin)