# WASM in the Enterprise: Secure, Portable, and Ready for Business
About me:
Agenda:
1.
2.
# WebAssembly ##
<3
- **Speed** for image processing - **Secure** execution through sandboxing - **Standard** as part of the W3C Note: - being it named after the "Web" the natural environment for Wasm is the browser - Wasm shines in the browsers and we are using it on a daily basis
# Server Side ##
- **Polyglot** with a lot of programming languages support - **Embeddable** in a lot of host runtimes - **Secure** allows to run untrusted code - **Standard** as part of the W3C Note: - Wasm has properties and charateristics that makes it a perfect execution environment on the server - first off it's Polyglot and we can compile from an increasing number of compatible programming languages, we don't need to decide upfront what language to support - it's built to be embedded in a host runtime, similarly to what happens in the browsers with JavaScript we can rely on standard interaction mechanisms that make it easy to be used in different environments - it's secure and the sandboxing mechanism can be leveraged on the server side to enable untrusted code execution - and again, is a W3C standard, is not going away anytime soon and more is going to be built on it
Note: As we mentioned a lot of programming languages has something to do with Wasm some compile to it and we have Wasm runtimes in available in a number of environments
Note: For today we will concentrate on the challenges and the lessons learned of running WebAssembly in pure Java thanks to the Chicory runtime
[chicory.dev](https://chicory.dev)
Note: Let's take a moment to appreciate the reasons why we embarked the journey of building a Java native WASM runtime, we are not just crazy, I believe! Photo by
Dewang Gupta
on
Unsplash
## The JVM: 30 Years of Value Creation
Note: We know Java is spread everywhere and we love it!
# Loading Native Code in the JVM Has Downsides - **Distribution** : Makes your app platform specific - **Runtime** : Execution leaves safety and observability of the JVM Note: - Distribution: The primary reason people target the JVM is for it's platform dependence. This violates it. - Runtime: Jumping into the native code leaves the safety and observability of the JVM. It also adds complexity and overhead when translating across the boundary.
# Within the JVM Boundaries - Guaranteed Memory Safety - Fault Isolation - Advanced JIT - Self contained programs - WORA: (Write once run anywhere) Platform independent bytecode - ... more! Note: - So lets talk about specifics, what are the benefits of staying within the boundaries of the JVM?
Note: Now that we have the core elements, lets see what happen when the rubber hits the road and we start implementing and scaling real-world case studies of the technology Photo by
Holly Mandarich
on
Unsplash
- Slow
- Fast
case study 1 https://blog.enebo.com/2024/02/23/jruby-prism-parser.html
> JRuby is a high performance, stable, fully threaded Java implementation of the Ruby programming language. Note: From an historical point of view, JRuby has been the first "real world" case study for Chicory. JRuby is a full implementation of Ruby that runs really fast and is used widely. I got contacted regarding a new implementation of the Ruby parser, but let's go step by step.
- **Ruby** UX - **C** foundation Note: Ruby is some kind of an iceberg, C interoperability is a first class building block. Just like Python those days where the language is used for numeric computation as some kind of "DSL" on top of low-level C/C++. Ruby has always been optimized by rewriting fundamental libraries in C. This is already a friction point on JRuby where people need to port the "Ruby bits" of a library to Java and subsequently bind to the underlying C code with all the pain and struggle of using JNI and the risks of running code outside the JVM. Photo by
SIMON LEE
on
Unsplash
[How to parse Ruby](https://programmingisterrible.com/post/42432568185/how-to-parse-ruby) ```ruby (lambda { |x| x.send((x > 0 ? :succ : :pred).to_s.to_sym) }).call((rand(2) == 1 ? -1 : 1) * (1..10).to_a.sample) ``` > slowly lose your sanity, gazing into the abyss that is **parse.y** Note: Ruby syntax is complex, as it tries to feel natural to humans, and, well, humans are complex creatures ... The first step any interpreter/compiler should pass is parsing the syntax and doing something down the line with it. Given the complexity of the task multiple Ruby parsers emerged, and the situation has been a bit chaotic. Photo by
Dmitriy Demidov
on
Unsplash
Note: To sort the situation a new parser have been designed and implemented in pure C: Prism!
+
+
# = # **Portability!** Note: Running Prism with Chicory, with zero native dependencies, has several advantages, it doesn't need a C library to be built for each and every target architecture(like x86, ARM etc.). This is important, for example, to bootstrap on IBM Z, which is the processor of IBM's mainframes where the JVM is available, but, compiling and running an additional library requires significant effort.
+
+
# =
Note: By using Prim with the Chicory interpreter, why, unsuprisingly, found out that it was pretty slow. But this doesn't need to be the case. Photo by
Sebastian Molinares
on
Unsplash
[Throughput :](https://github.com/andreaTP/wasm-bench/tree/bench-prism) | Interpreter | AOT | |---|---| | 1127 ops/s | 35259 ops/s | Note: We found out that WASM binary format and Java bytecode are very, very similar, so we developed an experimental AOT(Ahead Of Time) compiler/translator that takes WASM and emits pure Java bytecode, again, with zero dependencies outside Chicory itself. With it you can get pure Java bytecode out of a WASM module and it will run fast on any, stock, JVM. We have a basic "Hello world" application compiled from Go code, and those are the numbers in operations per second, of comparing the Chicory interpreter with the "AOT compiled" pure Java bytecode.
case study 2 https://trino.io/docs/current/udf/python.html
> Trino, distributed SQL query engine for big data analytics Note: TrinoDB is a distributed SQL database that happens to be built in Java. One of the first contributors to Chicory, David Philips, wanted to run Python UDF functions.
<3
Note: Starting from the recent 3.13 release CPython is a Tier 2 release target. So officially supported and any failure will block the release train. This enable to run the Pyhton interpreter on any WASI/WASM engine. And, of course, it runs on Chicory.
Note: Python is a pure interpreter, and it takes time to, on startup, load the entire standard library. Wasm promises very low latency startup times, so we need to find a way to speedup to make it a viable choiche.
# wasi-vfs https://github.com/kateinoigakukun/wasi-vfs > **Embedded file system**: a read only file system embedded in the .wasm binary. Note: First off we need to have quick access to all the files of the Python standard library. Instead of loading it from the Host, you can pre-load all of them into the wasm module itself. Using Wasi-VFS we don't need to give access to the host File System. This is also very secure.
# Wizer https://github.com/bytecodealliance/wizer > The WebAssembly Pre-Initializer Note: Wizer comes to help, with it you can run your wasm module and record the status in another wasm module. Next time you start the pre-initialized module it will start, super quickly, from where it left.
- **Before**: initialization time **40 seconds** - **After**: initialization time **1 second**
*on my machine
Note: So snapshotting a pre-initialized version of Python after loading the entire standard library makes it fast, reliable, and more secure.
case study 3
https://debezium.io/blog/2025/02/24/go-smt/
Note: Debezium is an engine for Change Data Capture capable of connecting to a variety of different databases.
<3
because:
Note:
# **S**ingle **M**essage **T**ransformation
- filter - routing - ... more! Note: Bheind the scenes, Debezium, is powered by Kafka Connect and is based, obviously, on Kafka. One of the interesting characteristics of Debezium is that it allows for Single Message Transformations. This means that, for each and every event happening on the database, you can inspect the payload of the generated message and take actions, for example filtering only valid messages or routing the content to a different topic.
# Naive approach
Note: We want to use Go for our transformations, but, given that we are going to run it in a Wasm sandbox we'd need a full cycle of serialization/deserialization of the entire message.
```go package main import ( "github.com/debezium/debezium-smt-go-pdk" ) //export process func process(proxyPtr uint32) uint32 { var sourceVersion = debezium.GetString(debezium.Get(proxyPtr, "value.source.version")) return debezium.SetBool(sourceVersion == "1.2.3") } func main() {} ```
https://github.com/debezium/debezium-smt-go-pdk
Note: Instead providing a Go Plugin Development Kit to lazy access the data
case study 4 - optional
> SQLite is the most used database engine in the world Note: SQLite is used everywhere, we want to run it safely in Java applications without FFI
+
# =
Note: So thanks to Chicory we compiled SQLite to WASM, compiled WASM to Java Bytecode to safely run in the pure JVM
+
# =
Note: We figured out that execution of a lot of queries was really slow
# Memory.grow
# Pre-allocation
https://github.com/roastedroot/sqlite4j
```bash mvn test -Dtest=QueryTest ``` Before: > Tests run: 15, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: **52.03 s** -- in io.roastedroot.sqlite4j.QueryTest After: > Tests run: 15, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: **8.035 s** -- in io.roastedroot.sqlite4j.QueryTest
conclusions When you need: - Safety - Portability - Speed - Polyglot Note:
conclusions When you have a constrained problem like: - A stable C/C++/Rust library - A stable ABI (Application Binary Interface) - ...more! Note:
Note: Don't fear the sloth! Even if there are technical challenges you can endure the pain and have pretty fast Wasm modules ready for production
Note:
# Thanks and Q&A
https://github.com/dylibso/chicory
https://github.com/andreaTP/qcon-2025-deck