Introduction: Why Java in WebAssembly?
WebAssembly (WASM) is a low-level binary instruction format designed for execution in the browser with near-native performance. For a long time, Java remained outside this ecosystem due to its virtual machine (JVM). However, modern tools such as TeaVM and CheerpJ allow compiling Java code into WebAssembly, opening up new possibilities for web development.
In this article, we will analyze how the Java + WebAssembly combination works, look at practical examples, and evaluate performance. You will learn how to port existing Java code to the browser without rewriting it in JavaScript.
Main Approaches to Integrating Java and WebAssembly
There are two main ways to run Java code in WebAssembly:
- Compiling bytecode to WASM — uses TeaVM, which translates Java bytecode into WebAssembly.
- Running the JVM in the browser — CheerpJ emulates the JVM in WebAssembly, allowing unmodified Java applications to run.
The first approach is preferable for new projects, as it results in a smaller bundle size and better performance. The second is suitable for porting legacy applications.
Setting up a Project with TeaVM
To get started with TeaVM, add the dependency to pom.xml (Maven):
<dependency> <groupId>org.teavm</groupId> <artifactId>teavm-classlib</artifactId> <version>0.9.0</version></dependency>Create a simple Java class for compilation:
import org.teavm.jso.JSBody;import org.teavm.jso.JSExport;
public class Calculator { @JSExport public static int add(int a, int b) { return a + b; } @JSExport public static int factorial(int n) { if (n <= 1) return 1; return n * factorial(n - 1); }}The @JSExport annotation makes methods accessible from JavaScript. After compilation, you will get a WASM module and a JavaScript wrapper.
Practical Example: Compilation and Calling from JavaScript
Let's look at the full cycle from compilation to calling in the browser. First, compile the Java code using the TeaVM plugin:
<plugin> <groupId>org.teavm</groupId> <artifactId>teavm-maven-plugin</artifactId> <version>0.9.0</version> <configuration> <targetType>WEBASSEMBLY</targetType> <mainClass>com.example.Calculator</mainClass> </configuration> <executions> <execution> <goals> <goal>compile</goal> </goals> </execution> </executions></plugin>After building (mvn package), the files calculator.wasm and calculator.js will appear in the target folder. Now create an HTML page:
<!DOCTYPE html><html><head> <title>Java + WebAssembly Demo</title></head><body> <h1>Java Calculator in WASM</h1> <p>Result: <span id="result"></span></p> <script src="calculator.js"></script> <script> // Callback function after WASM loads teavmMain().then(function(api) { var sum = api.com.example.Calculator.add(15, 27); var fact = api.com.example.Calculator.factorial(5); document.getElementById('result').innerHTML = '15 + 27 = ' + sum + '<br>' + '5! = ' + fact; }); </script></body></html>Open the page