DEV Community

Liam
Liam

Posted on

Running Java 21 and Java 25 in the browser via WebAssembly

CheerpJ 5 adds Java 21 and Java 25, and ships the full JDK, including javac. Here's how to use both.

Running a JAR on Java 25

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <script src="https://cjrtnc.leaningtech.com/5.0/loader.js"></script>
  </head>
  <body>
    <script type="module">
      await cheerpjInit({ version: 25 });
      cheerpjCreateDisplay(800, 600);
      await cheerpjRunJar("/app/my_application.jar");
    </script>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

version defaults to 8. The supported values are 8, 11, 17, 21 and 25. /app/ is your web server's root, so serve the folder over HTTP (npx http-server -p 8080). Opening the file from disk won't work.

To run a main class with dependencies, use cheerpjRunMain, with the class path separated by ::

await cheerpjRunMain("com.example.Main", "/app/app.jar:/app/lib.jar");
Enter fullscreen mode Exit fullscreen mode

Compiling in the browser

CheerpJ's virtual filesystem has three mount points:

  • /app/: your web server, read-only
  • /files/: IndexedDB, read-write from Java
  • /str/: written from JavaScript, read-only from Java

Write the source to /str/, compile it into /files/, then run it:

await cheerpjInit({ version: 25 });

cheerpOSAddStringFile("/str/Hello.java", `
public class Hello {
  sealed interface Shape permits Circle, Square {}
  record Circle(double r) implements Shape {}
  record Square(double side) implements Shape {}

  static double area(Shape s) {
    return switch (s) {
      case Circle c -> Math.PI * c.r() * c.r();
      case Square q -> q.side() * q.side();
    };
  }

  public static void main(String[] args) {
    System.out.println(area(new Circle(1)));
    System.out.println(area(new Square(2)));
  }
}
`);

const rc = await cheerpjRunMain(
  "com.sun.tools.javac.Main", "",
  "-d", "/files/out", "/str/Hello.java"
);

if (rc === 0) {
  await cheerpjRunMain("Hello", "/files/out");
}
Enter fullscreen mode Exit fullscreen mode

cheerpjRunMain resolves with the exit code, so a non-zero rc means compilation failed. Sealed interfaces and pattern matching in switch need Java 21 or later, so this fails on version: 17.

Switching on WasmGC

CheerpJ normally compiles bytecode to JavaScript. CheerpJ 5 has an experimental backend that generates WebAssembly using WasmGC:

await cheerpjInit({ version: 25, wasmGC: true });
Enter fullscreen mode Exit fullscreen mode

It needs Chrome or Edge 137+, Firefox 153+ or Safari 27+. Most applications won't run on it yet.

Docs: cheerpj.com/docs


The javac call isn't covered in the docs, so it needs testing before you post this.

Top comments (0)