Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
275 views
in Technique[技术] by (71.8m points)

java.lang.NoSuchMethodError:java.io.ByteArrayOutputStream.toString

I made a java program with gradle. I have jdk 15 on my computer but in the gradle file I put :

sourceCompatibility = 1.8
targetCompatibility = 1.8

so it can run with java 8.

I send the jar file to someone that uses java 8 and it works perfectly fine. On my computer, it works perfectly fine with java 8 and java 15.

I send the jar file to another person and he gets the following error :

[ERROR)Exceptioninthread'Thread-7"java.lang.NoSuchMethodError:java.io.ByteArrayOutputStream.toString(Ljava/nio/charset/Charset;)Ljava/lang/String;
[ERROR)    at fr.bloomenetwork.fatestaynight.packager.Utils.docxToKsFile(Utils.java:84)
[ERROR)    at fr.bloomenetwork.fatestaynight.packager.FetchingThread.run(FetchingThread.java:197)
[ERROR)    at java.lang.Thread.run(UnknownSource)

I don't undestand why he gets this error if it works fine for me and the other person.

Here is the code that raise the error :

public static void docxToKsFile(InputStream is, String filename) throws IOException {
        ZipInputStream zis = new ZipInputStream(is);
        ByteArrayOutputStream fos = new ByteArrayOutputStream();
        ZipEntry ze = null;
        String xmlContent = null;
        while ((ze = zis.getNextEntry()) != null) {
            if (ze.getName().equals("word/document.xml")) {
                byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
                int len;
                while ((len = zis.read(buffer)) != -1) {
                    fos.write(buffer, 0, len);          
                }
                xmlContent =  new String(fos.toString(StandardCharsets.UTF_8)); //Here is line 84
                fos.close();
                break;
            }
        }
        fos.close();
        String txtContent = xmlContent.replaceAll("</w:p>", "
"); 
        txtContent = txtContent.replaceAll("<[^>]*/?>", "");
        txtContent = txtContent.replaceAll("&amp;", "&");
        txtContent = txtContent.replaceAll("&quot;", """);
        java.nio.file.Files.write(Paths.get(filename), txtContent.getBytes(StandardCharsets.UTF_8));
    }
question from:https://stackoverflow.com/questions/65915184/java-lang-nosuchmethoderrorjava-io-bytearrayoutputstream-tostring

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

As per the javadoc of ByteArrayOutputStream's toString(Charset) method, it was added in Java10, and is thus not available on JDK8.

sourceCompatibility = 1.8
targetCompatibility = 1.8

so it can run with java 8.

That's not what that means. That merely means the source files are compiled using the JDK8 idea of java-the-language, and that the produces class files are in JDK8 format. It does nothing to guarantee that you are only using the JDK8 idea of the core libraries. Those gradle options are the gradle equivalent of javac's --source resp. --target options.

Those are the wrong options.

With javac, there is now a --release option (introduced in.. I think JDK8?) which covers both source and target compatibility, and even warns about trying to use core library calls that weren't in the stated release. Let's try it, with JDK14 which I happen to have installed on my machine (but should work with JDK11 too):

echo "class Test {{ new java.io.ByteArrayOutputStream().toString(java.nio.charset.StandardCharsets.UTF_8); }}" > Test.java
javac -version
> javac 14.0.1
javac --release 8 Test.java
> Test.java:1: error: no suitable method found for toString(Charset)
javac --release 11 Test.java
> [no message; it compiles fine]

As per the current gradle docs, sourceCompatibility and targetCompatibility are deprecated and should no longer be used. Use options.release = 8 instead, which is the gradle variant of the --release option. Yay!

NB: .toString("UTF-8") is ugly, but does work; it was introduced before java8.

NB2:

On my computer, it works perfectly fine with java 8 and java 15.

Nope. You weren't running it on java8 on your machine. If you had, the app would have failed with the same error. Must have accidentally used the wrong one :P


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...