konsoletyper / teavm

Compiles Java bytecode to JavaScript, WebAssembly and C
https://teavm.org
Apache License 2.0
2.55k stars 261 forks source link

Reading a text file #840

Open aghasemi opened 8 months ago

aghasemi commented 8 months ago

Hi,

I'm trying to read a text file as a String inside the TeaVM app. Consider a data JSON for example. It sees neither IOUtils.toString not XMLHttpRequest work, although they do fetch from remote hots. May I ask if there is a special location where the file should be? Currently, it is in the same path as index.html. Best

konsoletyper commented 8 months ago

I'm not sure which IOUtils.toString you mean, but XMLHttpRequest actually works. There's not such thing like "something not working", there's something actually that actually happens. Please, describe in detail what is the problem with XHR on your side.

aghasemi commented 8 months ago

Thanks. I managed to get it working with XMLHttpRequest (Isn't fetch supported by the way?). However, here is an interesting phenomenon regarding IOUtils, maybe for future reference:

The following code works as expected:

var txt =  org.apache.commons.io.IOUtils.toString(new URI("https://api.github.com/octocat"), "UTF-8");

, while the following fails:

var txt =  org.teavm.apachecommons.io.IOUtils.toString(new URI("https://api.github.com/octocat"), "UTF-8");
[ERROR] Method java.lang.ThreadLocal.withInitial(Ljava/util/function/Supplier;)Ljava/lang/ThreadLocal; was not found
    at org.teavm.apachecommons.io.IOUtils.<clinit>(IOUtils.java:183)
    at io.aghasemi.Client.main(Client.java:41)
[ERROR] Method java.util.Collections.unmodifiableSortedMap(Ljava/util/SortedMap;)Ljava/util/SortedMap; was not found
    at org.teavm.apachecommons.io.Charsets.<clinit>(Charsets.java:73)
    at org.teavm.apachecommons.io.IOUtils.toString(IOUtils.java:2926)
    at io.aghasemi.Client.main(Client.java:41)

And both fails if the URI is local, such as ./test.txt. This one is only handled by XMLHttpRequest.

TeaVM 0.9.0, Java 21.

konsoletyper commented 8 months ago

In case of Apache commons, TeaVM clearly provides you with explanations: some of the methods required by this library, aren't supported. TeaVM only emulates subset of Java class library, see table here: https://teavm.org/jcl-report/recent/jcl.html

as a workarond, you can write your own function that takes InputStream from URL, reads all bytes from it and constructs a string base on these bytes.

Isn't fetch supported by the way?

Fetch is supported. There's no such thing as "supported" in case of interaction with JavaScript. You can call any JavaScript API you like, see https://teavm.org/docs/runtime/jso.html. TeaVM also comes with some ready-to-use JavaScript definitions. These include XMLHttpRequest, but not fetch.

And both fails if the URI is local, such as ./test.txt

What do you mean by "failing"? Do they report any exceptions or print anything to browser console?

aghasemi commented 8 months ago

What do you mean by "failing"? Do they report any exceptions or print anything to browser console?

Maven passes, but this is printed in browser console:

Uncaught Error: null
    at $rt_exception (classes.js:15:159)
    at $rt_throw (classes.js:14:218)
    at I$ (TURI.java:1397:1)
    at TeaVMThread.runner (classes.js:31:202)
    at TeaVMThread.run (classes.js:692:227)
    at TeaVMThread.start (classes.js:691:480)
    at $rt_startThread (classes.js:693:488)
    at classes.js:31:173
    at onload (3000/:8:25)
konsoletyper commented 8 months ago

The next time you send any stack trace from browser, please, make sure you compiled you application with disabled minification. In this case I suppose the problem is that ./test.txt is not a valid URL.

aghasemi commented 8 months ago

The next time you send any stack trace from browser, please, make sure you compiled you application with disabled minification. In this case I suppose the problem is that ./test.txt is not a valid URL.

I tried file:///test.txt, then got "unrecognised protocol" at build time.

aghasemi commented 8 months ago

The next time you send any stack trace from browser, please, make sure you compiled you application with disabled minification. In this case I suppose the problem is that ./test.txt is not a valid URL.

I tried file:///test.txt, then got "unrecognised protocol" at build time.

But anyways, yes it is a MalformedURL issue and providing the full path via Window.getLocation() solves the issue.