---
title: Notes on Calling WebAssembly from Java with GraalWasm
tags: ["Java", "WebAssembly", "GraalWasm"]
categories: ["Programming", "WebAssembly", "Java", "GraalWasm", "GraalVM"]
date: 2024-07-01T15:08:11Z
updated: 2024-07-01T15:09:10Z
---

> ⚠️ This article was automatically translated by OpenAI (gpt-4o).
> It may be edited eventually, but please be aware that it may contain incorrect information at this time.

In the [previous article](/entries/806), we executed wasm on Java using [Chicory](https://github.com/dylibso/chicory). The same can be done with GraalVM ([GraalWasm](https://www.graalvm.org/latest/reference-manual/wasm/)).

Let's redo the content of the previous article using GraalWasm.

By adding the following dependency libraries, you can load and execute wasm on a Java application.

```xml
	<dependency>
		<groupId>org.graalvm.polyglot</groupId>
		<artifactId>polyglot</artifactId>
		<version>24.0.1</version>
	</dependency>
	<dependency>
		<groupId>org.graalvm.polyglot</groupId>
		<artifactId>wasm-community</artifactId>
		<version>24.0.1</version>
		<type>pom</type>
	</dependency>
```

Let's create a sample wasm file from a WAT file. Create the following file `SumSquared.wat`.

It takes two i32 parameters, adds them, and returns the squared value.

```lisp
(module
  (func (export "SumSquared")
    (param $value_1 i32) (param $value_2 i32)
    (result i32)
    (local $sum i32)

    (i32.add (local.get $value_1) (local.get $value_2))
    local.set $sum
    (i32.mul (local.get $sum) (local.get $sum))
  )
)
```

> [!TIP]
> I used the sample code from [Introduction to WebAssembly](https://www.amazon.co.jp/%E5%85%A5%E9%96%80WebAssembly-Rick-Battagline-ebook/dp/B09MQ6CSBG?crid=2F88E3ZRLB9ML&keywords=webassembly&qid=1688271177&sprefix=WebAssembly%2Caps%2C260&sr=8-6&linkCode=li2&tag=ikam-22&linkId=9a9576034b15b62f172d59f69c3f1784&language=ja_JP&ref_=as_li_ss_il).
> 
> [![Introduction to WebAssembly](https://github.com/making/blog.ik.am/assets/106908/0825cd6a-05f9-4d3a-9e7e-8c3be783709c)](https://www.amazon.co.jp/%E5%85%A5%E9%96%80WebAssembly-Rick-Battagline-ebook/dp/B09MQ6CSBG?crid=2F88E3ZRLB9ML&keywords=webassembly&qid=1688271177&sprefix=WebAssembly%2Caps%2C260&sr=8-6&linkCode=li2&tag=ikam-22&linkId=9a9576034b15b62f172d59f69c3f1784&language=ja_JP&ref_=as_li_ss_il)

Convert it to wasm using `wat2wasm`.

```
wat2wasm SumSquared.wat 
```

`SumSquared.wasm` will be generated. Load and execute this wasm in Java.

```java
package org.example;

import java.io.IOException;
import java.net.URL;
import java.util.Objects;

import org.graalvm.polyglot.Context;
import org.graalvm.polyglot.Source;
import org.graalvm.polyglot.Value;

public class Main {
	public static void main(String[] args) throws IOException {
		try (Context context = Context.newBuilder().allowAllAccess(true).build()) {
			context.initialize("wasm");
			URL resource = Main.class.getClassLoader().getResource("SumSquared.wasm");
			Source source = Source.newBuilder("wasm", Objects.requireNonNull(resource)).name("main").build();
			context.eval(source);
			Value sumSquared = context.getBindings("wasm").getMember("main").getMember("SumSquared");
			Value result = sumSquared.execute(2, 3);
			System.out.println("Result: " + result.asInt()); // should print "Result: 25" (= (2 + 3)^2)
		}
	}
}
```

Run the Java application.

```
$ mvn -q compile exec:java -Dexec.mainClass=org.example.Main
Result: 25
```

This application will work even if the runtime is not GraalVM. For differences in optimization, refer to [this document](https://www.graalvm.org/latest/reference-manual/embed-languages/#runtime-optimization-support).

If the runtime is not GraalVM, the following WARN log will be output.

```
[To redirect Truffle log output to a file use one of the following options:
* '--log.file=<path>' if the option is passed using a guest language launcher.
* '-Dpolyglot.log.file=<path>' if the option is passed using the host Java launcher.
* Configure logging using the polyglot embedding API.]
[engine] WARNING: The polyglot engine uses a fallback runtime that does not support runtime compilation to native code.
Execution without runtime compilation will negatively impact the guest application performance.
The following cause was found: JVMCI is not enabled for this JVM. Enable JVMCI using -XX:+EnableJVMCI.
For more information see: https://www.graalvm.org/latest/reference-manual/embed-languages/#runtime-optimization-support.
To disable this warning use the '--engine.WarnInterpreterOnly=false' option or the '-Dpolyglot.engine.WarnInterpreterOnly=false' system property.
```

You can suppress the log by adding the following JVM options.

```
MAVEN_OPTS="-XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -Dpolyglot.engine.WarnInterpreterOnly=false" mvn -q compile exec:java -Dexec.mainClass=org.example.Main
```

The full source code is [here](https://github.com/making/hello-graalwasm).

I would like to compare the performance of Chicory, GraalWasm, and wasmtime-java.
