javajava-11internalssun

Java11, what shall MalformedByteSequenceException be replaced with?


I'm moving a project to Java11

I already changed sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl with java.lang.reflect.ParameterizedType (as specified 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());
    }