2

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>", "\n"); 
        txtContent = txtContent.replaceAll("<[^>]*/?>", "");
        txtContent = txtContent.replaceAll("&amp;", "&");
        txtContent = txtContent.replaceAll("&quot;", "\"");
        java.nio.file.Files.write(Paths.get(filename), txtContent.getBytes(StandardCharsets.UTF_8));
    }
6
  • 1
    May be stupid question. Did this another person checked whether he is also using java 8 or higher version ? Commented Jan 27, 2021 at 8:18
  • 1
    Make sure that all of you are actually running it on Java 8. According to javadocs ByteArrayOutputStream#toString(java.nio.charset.Charset) method was introduced in Java 10. Commented Jan 27, 2021 at 8:18
  • He is running java 15. That's what is strange. Commented Jan 27, 2021 at 8:30
  • Your comment makes your question unclear. Did you try to run it on java 15, java 8 or both? Does your friend run it on Java 8 or Java 15? Commented Jan 27, 2021 at 8:35
  • I tried running it on both and it doesn't work with java 8. My friend runs java 15 and it doesn't work. Commented Jan 27, 2021 at 8:51

2 Answers 2

3

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

Sign up to request clarification or add additional context in comments.

2 Comments

You are right. I didn't see that this method was only available with jdk 10. But what is strange here is that the person who is able to run the jar file is using java 8 and the person who is not able to is running java 15.
Finally you were perfectly right. He was using java 8 without knowing it because he has both versions. Thanks for the advice in gradle.
2

Did you try this?

xmlContent =  new String(fos.toByteArray(), "UTF-8");

1 Comment

Thank you it works with both jdk 8 and 15.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.