Idea
Suggested by Denis Pavlyuchenko, @pavlyuchenko_denis on Telegram, in a comment: the project already builds a GraalVM native image, so the same build could target WebAssembly, and https://openjavaformat.dev could get a playground that formats code in the browser. Nothing would be sent anywhere, which is the point, and the site stays on GitHub Pages with no server.
Why it looks realistic
GraalVM's Web Image backend, native-image --tool:svm-wasm, compiles a JVM application into a Wasm module plus a JavaScript wrapper. The GraalVM team's own demo compiles all of javac that way and runs it in the browser:
Tried in Chrome 152: compiling the sample class took about 69 ms. The formatter needs only javac's parser, which is less than that demo uses.
What is different from today's native build
- GraalVM distribution. Web Image is experimental and ships in Oracle GraalVM 25.1 or later only. CI builds the native images with
distribution: 'graalvm-community', and GraalVM CE 25.0.2 has no svm-wasm tool. The Wasm artifact would need its own job with distribution: 'graalvm', which graalvm/setup-graalvm already supports, plus Binaryen 119 or later on the PATH.
- Entry point.
com.palantir.javaformat.java.Main works on files. The browser needs a small class that uses org.graalvm.webimage.api (@JS, JSObject, JSString) to read the text from the page, call the formatter with the OJF style and write the result back. The demo's WebMain is a template for it.
- Stability. The backend's APIs and tooling may change between releases, so the GraalVM version has to be pinned.
To decide
- Oracle GraalVM is free under the GFTC and the Web Image sources are GPLv2 in
oracle/graal, but it is not the community build. Is that acceptable for this one artifact, given manifesto principle 3 about artifacts built in public?
- Where the Wasm module is published: as a release asset that the site's build downloads, or built in the site's repository.
Size, for scale
|
Size |
| Wasm module of the javac demo |
27.4 MB |
| The same over the wire with gzip |
9.8 MB |
| Our native binary |
about 60 MB |
The module would load on the playground page only. Browsers need WebAssembly GC and exception handling, which current Chrome, Firefox and Safari have.
Not verified yet
Whether the formatter and its dependencies build under svm-wasm unchanged, and whether the existing reachability metadata carries over. Only a trial build can tell.
Suggested first step
A time-boxed spike of about a day: build open-java-format with --tool:svm-wasm on Oracle GraalVM, call the formatter from a static test page, and record what had to change, the module size and the time one format takes. Decide after that whether it becomes a CI job and a page on the site.
Alternatives looked at
- CheerpJ runs an unmodified jar in a browser JVM, but it supports Java 8, 11 and 17 while the formatter needs 21, and its runtime is proprietary and served from the vendor's CDN.
- A server-side formatter contradicts both the no-server setup of the site and the reason for a playground.
Idea
Suggested by Denis Pavlyuchenko, @pavlyuchenko_denis on Telegram, in a comment: the project already builds a GraalVM native image, so the same build could target WebAssembly, and https://openjavaformat.dev could get a playground that formats code in the browser. Nothing would be sent anywhere, which is the point, and the site stays on GitHub Pages with no server.
Why it looks realistic
GraalVM's Web Image backend,
native-image --tool:svm-wasm, compiles a JVM application into a Wasm module plus a JavaScript wrapper. The GraalVM team's own demo compiles all ofjavacthat way and runs it in the browser:Tried in Chrome 152: compiling the sample class took about 69 ms. The formatter needs only javac's parser, which is less than that demo uses.
What is different from today's native build
distribution: 'graalvm-community', and GraalVM CE 25.0.2 has nosvm-wasmtool. The Wasm artifact would need its own job withdistribution: 'graalvm', whichgraalvm/setup-graalvmalready supports, plus Binaryen 119 or later on thePATH.com.palantir.javaformat.java.Mainworks on files. The browser needs a small class that usesorg.graalvm.webimage.api(@JS,JSObject,JSString) to read the text from the page, call the formatter with the OJF style and write the result back. The demo'sWebMainis a template for it.To decide
oracle/graal, but it is not the community build. Is that acceptable for this one artifact, given manifesto principle 3 about artifacts built in public?Size, for scale
The module would load on the playground page only. Browsers need WebAssembly GC and exception handling, which current Chrome, Firefox and Safari have.
Not verified yet
Whether the formatter and its dependencies build under
svm-wasmunchanged, and whether the existing reachability metadata carries over. Only a trial build can tell.Suggested first step
A time-boxed spike of about a day: build
open-java-formatwith--tool:svm-wasmon Oracle GraalVM, call the formatter from a static test page, and record what had to change, the module size and the time one format takes. Decide after that whether it becomes a CI job and a page on the site.Alternatives looked at