Chicory seems like it'll be pretty useful. Java doesn't have easy access to the platform-specific security mechanisms (seccomp, etc) that are used by native tools to sandbox their plugins, so it's nice to have WebAssembly's well-designed security model in a pure-JVM library.
I've used it to experiment with using WebAssembly to extend the Bazel build system (which is written in Java). Currently there are several Bazel rulesets that need platform-specific helper binaries for things like parsing lock files or Cargo configs, and that's exactly the kind of logic that could happily move into a WebAssembly blob.
https://github.com/jmillikin/upstream__bazel/commits/repo-ru...
I don't understand logic and layers of abstraction here.
Chicory runs on JVM. Bazel runs on JVM. How inserting WebAssembly layer will help to eliminate platform-specific helper binaries? These binaries compiled to WebAssembly will be run, effectively, on JVM (through one additional layer of APIs provided by Chicory), right? Why you cannot write these helpers directly in JVM language, Java, Kotlin, Clojure, anything? Why do you need additional layer of Chicory?
You don't, just, easily rewrite everything. Being able to just re-use is the trick!
Exactly.
Why would you rewrite (parts of) Cargo from Rust to something that runs on the JVM, when you can use Wasm as basically an intermediate target to compile the Rust down to JVM bytecode?
Or how about running something like Shellcheck (written in Haskell) on the JVM as part of a build process?
You can see the same idea for the Go ecosystem (taking advantage of the Go build system) on the many repos of this org: https://github.com/wasilibs
I really don't want to sound flamewar-y, but how is WebAssmebly's security model well-designed compared to a pure Java implementation of a brainfuck interpreter? Similarly, java byte code is 100% safe if you just don't plug in filesystem/OS capabilities.
It's trivial to be secure when you are completely sealed off from everything. The "art of the deal" is making it safe while having many capabilities. If you add WASI to the picture it doesn't look all that safe, but I might just not be too knowledgeable about it.
It's really difficult to compare the JVM and wasm because they are such different beasts with such different use cases.
What wasm brings to the table is that the core tech focuses on one problem: abstract sandboxed computation. The main advantage it brings is that it _doesn't_ carry all the baggage of a full fledged runtime environment with lots of implicit plumbing that touches the system.
This makes it flexible and applicable to situations where java never could be - incorporating pluggable bits of logic into high-frequency glue code.
Wasm + some DB API is a pure stored procedure compute abstraction that's client-specifiable and safe.
Wasm + a simple file API that assumes a single underlying file + a stream API that assumes a single outgoing stream, that's a beautiful piece of plumbing for an S3 like service that lets you dynamically process files on the server before downloading the post-processed data.
There are a ton of use cases where "X + pluggable sandboxed compute" is power-multiplier for the underlying X.
I don't think the future of wasm is going to be in the use case where we plumb a very classical system API onto it (although that use case will exist). The real applicability and reach of wasm is the fact that entire software architectures can be built around the notion of mobile code where the signature (i.e. external API that it requires to run) of the mobile code can be allowed to vary on a use-case basis.
> What wasm brings to the table is that the core tech focuses on one problem: abstract sandboxed computation. The main advantage it brings is that it _doesn't_ carry all the baggage of a full fledged runtime environment with lots of implicit plumbing that touches the system.
Originally, but that's rapidly changing as people demand more performant host application interfacing. Sophisticated interfacing + GC + multithreading means WASM could (likely will) fall into the same trap as the JVM. For those too young to remember, Java Applet security failed not because the model was broken, but because the rich semantics and host interfacing opened the door to a parade of implementation bugs. "Memory safe" languages like Rust can't really help here, certainly not once you add JIT into the equation. There are ways to build JIT'd VMs that are amenable to correctness proofs, but it would require quite alot of effort and the most popular and performant VMs just aren't written with that architectural model in mind. The original premise behind WASM was to define VM semantics simple enough that that approach wouldn't be necessary to achieve correctness and security in practice; in particular, while leveraging existing JavaScript VM engines.
The bespoke capability model in Java has always been so fiddly it has made me question the concept of capability models. There’s was for a long time a constant stream of new privilege escalations mostly caused by new functions being added that didn’t necessarily break the model themselves, but they returned objects that contained references to objects that contained references to data that the code shouldn’t have been able to see. Nobody to my recollection ever made an obvious back door but nonobvious ones were fairly common.
I don’t know where things are today because I don’t use Java anymore, but if you want to give some code access to a single file then you’re in good hands. If you want to keep them from exfiltrating data you might find yourself in an Eternal Vigilance situation, in which case you’ll have to keep on top of security fixes.
We did a whole RBAC system as a thin layer on top of JAAS. Once I figured out a better way to organize the config it wasn’t half bad. I still got too many questions about it, which is usually a sign of ergonomic problems that people aren’t knowledgeable enough to call you out on. But it was a shorter conversation with fewer frowns than the PoC my coworker left for me to productize.
WASI does open up some holes you should be considerate of. But it's still much safer than other implementations. We don't allow you direct access to the FS we use jimfs: https://github.com/google/jimfs
I typically recommend people don't allow wasm plugins to talk to the filesystem though, unless they really need to read some things from disk like a python interpreter. You don't usually need to.
Pssst, it is the usual WebAssembly sales pitch.
Linear memory accesses aren't bound checked inside the linear memory segment, thus data can still be corrupted, even if it doesn't leave the sandbox.
Also just like many other bytecode based implementations, it is as safe as the implementations, that can be equally attacked.
https://webassembly.org/docs/security/
https://www.usenix.org/conference/usenixsecurity20/presentat...
https://www.usenix.org/conference/usenixsecurity21/presentat...
https://www.usenix.org/conference/usenixsecurity22/presentat...
WebAssembly being described as a sandbox is perfectly valid. Applications with embedded sandboxes for plugins use the sandbox to protect the application from the plugin, not to protect the plugin from itself. The plugin author can protect the plugin from itself by using a memory-safe language that compiles to WebAssembly; that's on them and not on the embedding application.
Looking forward to seeing more Chicory in Bazel, is a great use-case! Thanks for spearheading it!
A few cool things based on Chicory:
OPA: https://github.com/StyraInc/opa-java-wasm
Integration with Debezium has been launched today too: https://debezium.io/blog/2025/02/24/go-smt/
And SQLite will come next: https://github.com/roastedroot/sqlite4j
Some more interesting use cases in production:
Running python UDFs in Trino: https://trino.io/docs/current/udf/python.html
Running the Ruby parser in Jruby: https://blog.enebo.com/2024/02/23/jruby-prism-parser.html
Looking forward to this reviving NestedVM's pure Java SQLite. It's only been (checks notes…) 20 years.
https://benad.me/blog/2008/1/22/nestedvm-compile-almost-anyt...
To be clear: I'm fully supportive of this effort. NestedVM's SQLite is 100% my inspiration for my Wasm based Go SQLite driver.
also the chicory Extism SDK https://github.com/extism/chicory-sdk and the mcpx4j library used for mcp.run Java integration, see e.g. https://docs.mcp.run/tutorials/mcpx-spring-ai-java
...and Chicory works on Android too https://docs.mcp.run/tutorials/mcpx-gemini-android
I'd like to take a moment to appreciate how cute the name is.
Love stuff like that.
Came here to say the same thing, excellent name.
For people who aren't aware, Chicory has long been used (e.g. in Europe during WW2) as a coffee substitute, and Java is another name for coffee, thus Chicory is a substitute for Java.
Edit: I originally thought Chicory was a JVM replacement using WebAssembly (e.g. to run Java applets in modern browsers, using WebAssembly). It appears that it's actually a WebAssembly runtime, to run WebAssembly code on the JVM. So the name is a lot less cool than I thought it was.
it really is a perfect name. credit to u/bhelx!
How does it compare to graal wasm? https://github.com/oracle/graal/blob/master/wasm/README.md/
take a look at this blog post, these are early results but we collaborated with the Graal team for a fair comparison https://chicory.dev/blog/chicory-1.0.0#the-race-day
Wizard's slow interpreter also runs on the JVM, albeit it very, very slowly. Have you done any benchmarking against Wizard?
we should!
Also note, we have the AOT compiler which can target the JVM bytecode directly as well as Dalvik/Android which is experimental but nearly spec complete :)
It'd be interesting to see a benchmark for what the total overhead is for Rust->WASM->Chicory AoT->native-image versus native Rust; I've been pleasantly surprised by the JVM in the past, so I'd hope it'd be a relatively small hit.
Even in interpreter mode, rust wasm programs seem very fast for me on Chicory. I'm not sure if we have any specific benchmarks but the graal team did some and i think it's based on a rust guest program https://chicory.dev/blog/chicory-1.0.0/#the-race-day
ahaha, that's intriguing! I think there are still some gaps but we are comparing results(with GraalWasm) on Photon here: https://github.com/shaunsmith/wasm-bench Should be easy to build a native image and compare!
How far is this from the hypothetical (I think, for now) scenario of including a WASM build as a fallback "platform" in jars that include some native code for a number of platforms? A number of platforms that will never be complete, not when you include the future?
I would say pretty close, check this for example: https://github.com/roastedroot/sqlite4j
For some reason, I think that instead a Java runtime written in WebAssembly would be more useful.
There are a few, and they are really interesting! The reason we wrote Chicory though is we're interested in extending the capabilities of existing Java applications through plugins. The intro of this talk explains some of this reasoning: https://www.youtube.com/watch?v=00LYdZS0YlI
Then you'll be run Java in the browser! Wait, isn't that applets?
Not sure why you're being downvoted. One of the best tools Microsoft made regarding WebAssembly and C# is Blazor. Developers can focus on building web applications and use C# on both the front-end and back-end and drive the UI either server side or WASM without missing a beat. Essentially bypassing the need for JavaScript.
I can only imagine such a capability for Java or other languages would be infinitely useful.
Google web toolkit was released 18 yers ago that essentially allowed you to create early web2.0 apps (like Gmail) in Java. AJAX and a lot of web2.0 innovations were essentially originated from GWT
Arguably, GWT was too ambitious. That made it somewhat of a PITA to work with.
J2CL is a much better approach (IMO) but is somewhat too little too late.
The best analogy to what GWT was is ASP.NET Webforms but ran on the client. That extra baggage (along with an antiquated build system and setup) made it really hard to keep GWT up to date.
I'm excited to see Java bytecode->WASM though. Now that WASM ships with a GC we should see some really neat stuff in terms of the size of the runtime needed for an AOT bytecode->wasm.
I would even argue that large scale JS web apps were plain impossible without Google Closure (the compiler they used to compile both Java and JS to JS, and to add types to JS) at the time.
TeaVM https://www.teavm.org/
Related. Others?
Chicory 1.0.0-M1: First Milestone Release - https://news.ycombinator.com/item?id=42086590 - Nov 2024 (3 comments)
A Zero-Dependency WebAssembly Runtime for the JVM - https://news.ycombinator.com/item?id=38759030 - Dec 2023 (1 comment)
Chicory is how we're able to run newly popular MCP servers on Android!
https://docs.mcp.run/blog/2024/12/27/running-tools-on-androi...
Would Scala be able to run on this?
Yes i think so. it's just a jar
Scala needs the Garbage Collection and Exception Handling proposals(afaik). They are planned but not implemented yet in Chicory.
wait, was the question running scala in wasm or running chicory in scala?
To wasm or not to wasm.
Well, running Chicory in Scala is seamless, I thought this comment was targeting the effort to compile Scala to Wasm in the Scala.js project.
Can we use any JVM language, like Clojure?
I think it's the other direction isn't it? As in, it's a runtime written in Java that runs WebAssembly, not a JVM that runs on WebAssembly.
I could be wrong but that's the impression I got.
that is correct
This is distributed as just a jar, should you can invoke it from Clojure, if that is what you mean.
This looks very cool - I'm going to read into the implementation, there's something about producing JVM bytecode from WASM instructions and then having the JVM JIT compile it into native instructions that amuses me.
It's very amusing to me as well. The first thing i did was run and SNES emulator and definitely made me chuckle https://x.com/bhelx/status/1809235314839281900
I want to do the opposite I want to run jvm languages on wasm
There are a few efforts in this direction, TeaVM but also Graal, I think you just need to stay tuned
I feel like a WASM-native JVM runtime would make more sense these days
There is TeaVM for whatever it’s worth.
JavaScript and WASM really seem more portable. They have now approximated what Java web applets tried to achieve. And now WASM can be run in Mainframe IBM JVMs. Nashorn or Rhino seems like it runs JavaScript there.
JavaScript and WASM are now getting close to COBOL's importance. That’s no mean feat.
There are a few! But also there is lots of Java software out there and Wasm is a great way to extend it and bring new functionality.