konsoletyper / teavm

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

Run WebAssembly in the browser #953

Closed jsfan3 closed 1 month ago

jsfan3 commented 1 month ago

Given this code:

package ...;

import org.teavm.jso.dom.html.*;

public class Calculator {

    public static void main(String[] args) {
        HTMLDocument document = HTMLDocument.current();
        HTMLElement container = document.getElementById("calculator-container");

        // Create input fields
        HTMLInputElement input1 = (HTMLInputElement) document.createElement("input");
        input1.setType("number");
        container.appendChild(input1);

        HTMLInputElement input2 = (HTMLInputElement) document.createElement("input");
        input2.setType("number");
        container.appendChild(input2);

        // Create a button
        HTMLButtonElement button = (HTMLButtonElement) document.createElement("button");
        button.appendChild(document.createTextNode("Calculate Sum"));
        container.appendChild(button);

        // Create a div to display the result
        HTMLElement resultDiv = document.createElement("div");
        container.appendChild(resultDiv);

        // Add click event listener to the button
        button.addEventListener("click", (evt) -> {
            try {
                double num1 = Double.parseDouble(input1.getValue());
                double num2 = Double.parseDouble(input2.getValue());
                double sum = num1 + num2;
                resultDiv.setTextContent("Result: " + sum);
            } catch (NumberFormatException e) {
                resultDiv.setTextContent("Please enter valid numbers.");
            }
        });
    }
}

I can easily run its JavaScript version produced by TeaVM in the browser:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>TeaVM Examples</title>
    <script type="text/javascript" src="calculator.js"></script>
    <script type="text/javascript">
        document.addEventListener('DOMContentLoaded', function() {
            main();
        });
    </script>
</head>
<body>
<div id="calculator-container"></div>
</body>
</html>

But producing the WebAssemby files calculator.wasm and calculator.wasm-runtime.js, I didn't get how to use them in the browser.

I tried:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>TeaVM Examples</title>
    <script type="text/javascript" src="calculator.wasm-runtime.js"></script>
</head>
<body>
<div id="calculator-container"></div>
    <script>
        (async () => {
            try {
                const teavmWasm = await TeaVM.wasm.load("calculator.wasm");
                teavmWasm.main();

            } catch (error) {
                console.error('Error:', error);
            }
        })();
    </script>
</body>
</html>

This produces the error:

Error: TypeError: import object field '' is not an Object
konsoletyper commented 1 month ago

I don't know why your project successfully compiled. It should have reported thousands errors, since JSO is not supported in WebAssembly. There's not much documentation on WebAssembly though, so you need to look into examples.

jsfan3 commented 1 month ago

TeaVM also compiles with unsupported classes like Swing. I noticed this and was confused at first.

Also in the javadocs, no class or method has a description or example of use. I had a hard time figuring out how to use TeaVM, although I got the hang of it later.

konsoletyper commented 1 month ago

@jsfan3 TeaVM should not compile unsupported classes. Can you please describe exactly what you doing?

Also in the javadocs, no class or method has a description or example of use.

Which ones do you mean? For which classes or methods you need description?

I had a hard time figuring out how to use TeaVM, although I got the hang of it later.

With what do you have hard time?

konsoletyper commented 1 month ago

@jsfan3 in case you are going to write article about using TeaVM to compile Java to WebAssembly, please, notice that currently I'm working on new WebAssembly backend that utilizes WebAssembly GC proposal. One of the advantages of this approach is the ability to pass objects between JavaScript and WebAssembly (previously, it was only possible to pass numbers). That allows to support JSO there, so JavaScript targeted apps can be ported to WebAssembly (almost) without any rewriting.

jsfan3 commented 1 month ago

@konsoletyper Thanks for the clarification. I have a good opinion of TeaVM and my focus is on the use of Javascript. I am also glad that you respond promptly, which is a rather rare virtue.

As for what I wrote to you yesterday in the previous comment, take it as constructive criticism. My invitation is to fill the javadocs for all classes and all methods with descriptions and examples, as it is a good pratice and a great help for developers. The documentation on your official site is poor, there are no manuals or complete step-by-step guides for beginners. In addition, those approaching TeaVM may know little or nothing about Javascript, which is exactly why they want to use Java. Setting up a Maven project with Eclipse is not trivial either, and there are different ways to do it, either by putting everything in the pom.xml or by using the TeaVMTool class. This should also be explained. The examples on the official site are outdated and contain code that is no longer valid, such as the suggestion to use Java 8.

I repeat: I like TeaVM, it is a great project, but the documentation on both the official site and other sites is very poor.

konsoletyper commented 1 month ago

As for what I wrote to you yesterday in the previous comment, take it as constructive criticism

Sure, but when you criticizing, please, realize that I work on TeaVM alone, on my free time (which means few hours a week). There are occasional contributions, but they are mostly to the code, almost nobody ever contributed documentation. Also please note that writing good documentation take immense amount of time, especially for those with non-native English skills and who isn't a professional technical writer.

That's why I can't just "make everything good", it's impossible. When you criticize documentation, please criticize very specific things, so that I could identify pain points and prioritize only those. For example "I wanted to do A and B, but had troubles because could not find information on C".

My invitation is to fill the javadocs for all classes and all methods with descriptions and examples

Sorry, it's not possible for all classes. And not reasonable for all classes. Some of them are compiler internals, some are just emulation of Java class library, which is already documented, some just wrappers around JavaScript APIs which are already documented.

there are no manuals or complete step-by-step guides for beginners

Here's step-by-step guide for beginners: https://teavm.org/docs/intro/getting-started.html

Or you meant something else? What exactly?

In addition, those approaching TeaVM may know little or nothing about Javascript, which is exactly why they want to use Java

Sorry, it's the greatest misunderstanding from your part. TeaVM was never addressed to developers who don't want to learn JavaScript. If someone simply does not want to learn JavaScript, my solution is: do. Anyway, there is a huge army of front-end JavaScript developers, business can hire anyone.

The primary purpose of TeaVM is to share code between platforms. For example, at my current company we have huge Java code base, which works on Android, iOS (using GraalVM), and web. It's simply impossible to take 3 different teams and to ask each team to write same functionality on JavaScript/TypeScript and on Swift. Especially, when it's some hardcore functionality like physics engine or OT.

Some other potential use cases: you have distinct teams to write UI using platform-specific tools, but use some shared non-trivial library written in Java, like OT/CRDT implementation (I heard Google does something similar).

Setting up a Maven project with Eclipse is not trivial either

Sorry, what's non-trivial here? Quote the documentation

The easiest way to create a new TeaVM project is to type in this command:

mvn -DarchetypeCatalog=local \
  -DarchetypeGroupId=org.teavm \
  -DarchetypeArtifactId=teavm-maven-webapp \
  -DarchetypeVersion=${teavm_version} archetype:generate

Now you can execute mvn clean package and get the generated war file. Deploy this war in Tomcat or another container, or simply unzip it and open the index.html page.

or by using the TeaVMTool class

I can't advice to use TeaVMTool directly except for rare cases (for example, a person is using SBT, for which there's no official implementation, but sure exist some 3rd party plugins). I can't track and document all the rare cases, so if a developer really needs it, they may just ask or learn the code.

I repeat: I like TeaVM, it is a great project, but the documentation on both the official site and other sites is very poor.

I understand the problem with the documentation, but my answer: in general, I'm not gonna do anything with it. Hope for your understanding.

jsfan3 commented 1 month ago

I understand you. And I am grateful to you for creating TeaVM.

konsoletyper commented 1 month ago

TeaVM also compiles with unsupported classes like Swing. I noticed this and was confused at first.

Ah, I just realized what's going on. Instead of using Maven plugin, you rely on your own TeaVMTool, which you use incorrectly. When it's used properly OR when standard tool is used, TeaVM reports unsupported classes.