• Stars
    star
    544
  • Rank 81,699 (Top 2 %)
  • Language
    Java
  • License
    MIT License
  • Created about 5 years ago
  • Updated over 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

☕ WebAssembly runtime for Java

A complete and mature WebAssembly runtime for Java based on Wasmer.

Features:

  • Easy to use: The wasmer API mimics the standard WebAssembly API,
  • Fast: The Wasmer JNI executes the WebAssembly modules as fast as possible, close to native speed,
  • Safe: All calls to WebAssembly will be fast, but more importantly, completely safe and sandboxed.

Install

The Wasmer package is published in Bintray on the wasmer/wasmer-jni repository.

The JAR files are named as follows: wasmer-jni-$(architecture)-$(os)-$(version).jar. Thus, to include Wasmer JNI as a dependency, write for instance:

dependencies {
    implementation "org.wasmer:wasmer-jni-amd64-linux:0.3.0"
}

Note: It is also possible to download the Java JAR file from the Github releases page! If you need to produce a JAR for your own platform and architecture, see the Development Section to learn more.

Example

There is a toy program in java/src/test/resources/simple.rs, written in Rust (or any other language that compiles to WebAssembly):

#[no_mangle]
pub extern fn sum(x: i32, y: i32) -> i32 {
    x + y
}

After compilation to WebAssembly, the tests/resources/simple.wasm binary file is generated. (Download it).

Then, we can execute it in Java:

class Example {
    public static void main(String[] args) {
        // `simple.wasm` is located at `tests/resources/`.
        Path wasmPath = Paths.get(new Example().getClass().getClassLoader().getResource("simple.wasm").getPath());

        // Reads the WebAssembly module as bytes.
        byte[] wasmBytes = Files.readAllBytes(wasmPath);

        // Instantiates the WebAssembly module.
        Instance instance = new Instance(wasmBytes);

        // Calls an exported function, and returns an object array.
        Object[] results = instance.exports.getFunction("sum").apply(5, 37);

        System.out.println((Integer) results[0]); // 42

        // Drops an instance object pointer which is stored in Rust.
        instance.close();
    }
}

There is more examples in the examples/ directory. Run them with the Makefile, such as: make run-example EXAMPLE=Simple to run the SimpleExample example.

API of the wasmer library

The root namespace is org.wasmer.

The Instance class

The Instance constructor compiles and instantiates a WebAssembly module. It is built upon bytes. From here, it is possible to call exported functions, or exported memories. For example:

// Instantiates the WebAssembly module.
Instance instance = new Instance(wasmBytes);

// Calls an exported function.
Object[] results = instance.exports.getFunction("sum").apply(1, 2);

// Casts an object to an integer object because the result is an object array.
int result = (Integer) results[0];

System.out.println(result); // 3

// Drops an instance object pointer manually. Note that the garbage collector
// will call this method before an object is removed from the memory.
instance.close();

Exports

All exports, like functions or memories, are accessible on the Instance.exports field, which is of kind Exports (a read-only wrapper around a map of kind Map<String, exports.Export>). The Exports.get method returns an object of type Export. To downcast it to an exported function or to an exported memory, you can use the respective getFunction or getMemory methods. The following sections describe each exports in details.

Exported functions

An exported function is a native Java closure (represented by the exports.Function class), where all arguments are automatically casted to WebAssembly values if possible, and all results are of type Object, which can be typed to Integer or Float for instance.

Function sum = instance.exports.getFunction("sum");
Object[] results = sum.apply(1, 2);

System.out.println((Integer) results[0]); // 3

Exported memories

An exported memory is a regular Memory class.

Memory memory = instance.exports.getMemory("memory_1");

See the Memory class section for more information.

The Module class

The Module.validate static method checks whether a sequence of bytes represents a valid WebAssembly module:

// Checks that given bytes represent a valid WebAssembly module.
boolean isValid = Module.validate(wasmBytes);

The Module constructor compiles a sequence of bytes into a WebAssembly module. From here, it is possible to instantiate it:

// Compiles the bytes into a WebAssembly module.
Module module = new Module(wasmBytes);

// Instantiates the WebAssembly module.
Instance instance = module.instantiate();

Serialization and deserialization

The Module.serialize method and its complementary Module.deserialize static method help to respectively serialize and deserialize a compiled WebAssembly module, thus saving the compilation time for the next use:

// Compiles the bytes into a WebAssembly module.
Module module1 = new Module(wasmBytes);

// Serializes the module.
byte[] serializedModule = module1.serialize();

// Let's forget about the module for this example.
module1 = null;

// Deserializes the module.
Module module2 = Module.deserialize(serializedModule);

// Instantiates and uses it.
Object[] results = module2.instantiate().exports.getFunction("sum").apply(1, 2);

System.out.println((Integer) results[0]); // 3

The Memory class

A WebAssembly instance has a linear memory, represented by the Memory class. Let's see how to read it. Consider the following Rust program:

#[no_mangle]
pub extern fn return_hello() -> *const u8 {
    b"Hello, World!\0".as_ptr()
}

The return_hello function returns a pointer to a string. This string is stored in the WebAssembly memory. Let's read it.

Instance instance = new Instance(wasmBytes);

// Gets the memory by specifying its exported name.
Memory memory = instance.exports.getMemory("memory");

// Gets the pointer value as an integer.
int pointer = (Integer) instance.exports.getFunction("return_hello").apply()[0];

// Reads the data from the memory.
ByteBuffer memoryBuffer = memory.buffer();
byte[] stringBytes = new byte[13];
memoryBuffer.position(pointer);
memoryBuffer.get(stringBytes);

System.out.println(new String(stringBytes)); // Hello, World!

instance.close();

Memory grow

The Memory.grow methods allows to grow the memory by a number of pages (of 64KiB each).

// Grows the memory by the specified number of pages, and returns the number of old pages.
int oldPageSize = memory.grow(1);

Development

The Wasmer JNI library is based on the Wasmer runtime, which is written in Rust, and is compiled to a shared library. For your convenience, we produce one JAR (Java Archive) per architecture and platform. By now, the following are supported, consistently tested, and pre-packaged:

  • amd64-darwin,
  • amd64-linux,
  • amd64-windows.

More architectures and more platforms will be added in a close future. If you need a specific one, feel free to ask!

If you want to build the extension you will need the following tools:

  • Gradle, a package management tool,
  • Rust, the Rust programming language,
  • Java, because it's a Java project ;-).
$ git clone https://github.com/wasmerio/wasmer-java/
$ cd wasmer-java

To build the entire project, run the following command:

$ make build

To build the JAR package:

$ make package

This will generate the file build/libs/wasmer-jni-$(architecture)-$(os)-0.3.0.jar.

Automatic dependencies per architecture and platform

It is possible to infer the archive appendix automatically, see how.

According the Gradle Jar API, the $(architecture)-$(os) part is called the archive prefix. To infer that appendix automatically to configure your dependencies, you can use the following inferWasmerJarAppendix function:

String inferWasmerJarAppendix() {
    def nativePlatform = new org.gradle.nativeplatform.platform.internal.DefaultNativePlatform("current")
    def arch = nativePlatform.architecture
    def os = nativePlatform.operatingSystem

    def arch_name

    switch (arch.getName()) {
        case ["x86_64", "x64", "x86-64"]:
            arch_name = "amd64"
            break;

        default:
            throw new RuntimeException("`wasmer-jni` has no pre-compiled archive for the architecture " + arch.getName())
    }

    def os_name

    if (os.isMacOsX()) {
        os_name = "darwin"
    } else if (os.isLinux()) {
        os_name = "linux"
    } else if (os.isWindows()) {
        os_name = "windows"
    } else {
        throw new RuntimeException("`wasmer-jni` has no pre-compiled archive for the platform " + os.getName())
    }

    return arch_name + "-" + os_name
}

Finally, you can configure your dependencies such as:

dependencies {
    implementation "org.wasmer:wasmer-jni-" + inferWasmerJarAppendix() + ":0.3.0"
}

Testing

Run the following command:

$ make test

Note: Testing automatically builds the project.

Documentation

Run the following command:

$ make javadoc

Then open build/docs/javadoc/index.html.

What is WebAssembly?

Quoting the WebAssembly site:

WebAssembly (abbreviated Wasm) is a binary instruction format for a stack-based virtual machine. Wasm is designed as a portable target for compilation of high-level languages like C/C++/Rust, enabling deployment on the web for client and server applications.

About speed:

WebAssembly aims to execute at native speed by taking advantage of common hardware capabilities available on a wide range of platforms.

About safety:

WebAssembly describes a memory-safe, sandboxed execution environment […].

License

The entire project is under the MIT License. Please read the LICENSE file.

More Repositories

1

wasmer

🚀 The leading Wasm Runtime supporting WASIX, WASI and Emscripten
Rust
16,915
star
2

wasmer-go

🐹🕸️ WebAssembly runtime for Go
Go
2,679
star
3

wasmer-python

🐍🕸 WebAssembly runtime for Python
Rust
1,999
star
4

wasmer-php

🐘🕸️ WebAssembly runtime for PHP
PHP
964
star
5

winterjs

Winter is coming... ❄️
JavaScript
844
star
6

wasmer-js

Monorepo for Javascript WebAssembly packages by Wasmer
Rust
828
star
7

kernel-wasm

Sandboxed kernel mode WebAssembly runtime.
C
702
star
8

awesome-wasi

😎 Curated list of awesome things regarding WebAssembly WASI ecosystem.
476
star
9

wasmer-ruby

💎🕸 WebAssembly runtime for Ruby
Rust
462
star
10

wasmer-postgres

💽🕸 Postgres library to run WebAssembly binaries.
Rust
392
star
11

wapm-cli

📦 WebAssembly Package Manager (CLI)
Rust
368
star
12

webassembly.sh

Open-source and installable PWA terminal powered by WebAssembly, WAPM, and Wasmer-JS 🖥
JavaScript
269
star
13

wasmer-rust-example

Example of WebAssembly embedding in Rust using Wasmer
Rust
163
star
14

ate

Distributed immutable data store with strong encryption and authentication
Rust
129
star
15

vscode-wasm

WebAssembly extension for VSCode
Rust
122
star
16

wai

A language binding generator for `wai` (a precursor to WebAssembly interface types)
Rust
110
star
17

rusty_jsc

Rust bindings for the JavaScriptCore engine.
Rust
86
star
18

wasmer-c-api

Example of the C API to embed the Wasmer runtime
C
76
star
19

io-devices-lib

Library for interacting with the Wasmer Experimental IO Devices
WebAssembly
51
star
20

wasmer-pack

Rust
49
star
21

sonde-rs

A library to compile USDT probes into a Rust library
Rust
44
star
22

old-docs.wasmer.io

Wasmer Documentation (for standalone and embedded use cases)
WebAssembly
41
star
23

wasmer-install

Wasmer Binary Installer https://wasmer.io/
Shell
39
star
24

loupe

Profiling tool for Rust code.
Rust
35
star
25

c-wasm-simd128-example

Example C++ repo emitting Wasm SIMD 128 instructions
C++
30
star
26

wasmer-nginx-example

This is a simple example of Nginx running with wasmer
HTML
29
star
27

wasmer-ocaml

OCaml bindings for Wasmer
OCaml
28
star
28

cargo-wasmer

A cargo sub-command for publishing Rust crates to the WebAssembly Package Manager.
Rust
24
star
29

wasm-fuzz

Fuzzer for Wasm and Wasmer
JavaScript
22
star
30

wasmer.io

The Wasmer.io website
JavaScript
21
star
31

wasmer-bench

This is a repo for benchmarking Wasmer (compilation & runtime)
Rust
20
star
32

wcgi-wordpress-demo

PHP
15
star
33

wcgi-php-template

PHP
14
star
34

docs.wasmer.io

The Wasmer Docs Website (website deployed using Wasmer Edge)
MDX
14
star
35

setup-wasmer

GitHub action for setting up Wasmer
TypeScript
14
star
36

c-http-server

A very simple http server in c
JavaScript
13
star
37

rust-wasm-simd128-example

Example Rust repo emitting Wasm SIMD 128 instructions
Rust
10
star
38

wasm-debug

A runtime-independent crate for transforming Wasm-DWARF
Rust
9
star
39

wasmer-terminal-js

The WebAssembly terminal, revamped!
Rust
7
star
40

rust-cli-app-example

Example CLI app written in rust for Wasmer
Rust
7
star
41

wapm-publish

GitHub action for publishing to WAPM
TypeScript
7
star
42

wasmer-rust-customabi-example

An example repo to demonstrate how to create a module with a custom ABI to then use it from an embedder
Rust
6
star
43

wasm-interface-cli

A binary for verifying Wasm interfaces
Rust
6
star
44

interface-types

The `wasmer-interface-types` crate
Rust
5
star
45

ewasm-workshop

Ewasm workshow with Wasmer Metering
Rust
5
star
46

sgp4

Rust
5
star
47

llvm-custom-builds

Sandbox to produce custom LLVM builds for various platforms
Shell
5
star
48

sha2

A WebAssembly interface to Rust's sha2 crate
Rust
5
star
49

wasm-python-api

WebAssembly Python standard API prototype
Python
4
star
50

python-flask-example

Sample Python Flask server for Wasmer Edge
Python
4
star
51

shared-buffer

An abstraction over buffers backed by memory-mapped files or bytes in memory
Rust
3
star
52

wcgi-rust-template

Rust
3
star
53

wasmer-toml

Split out the wapm.toml parsing from wasmerio/wapm-cli
Rust
3
star
54

wasmer-nightly

Nightly releases of Wasmer
3
star
55

llvm-build

LLVM Distribution for being used with Wasmer
3
star
56

js-service-worker-example

Sample for a js service worker running on Wasmer Edge.
JavaScript
3
star
57

wasi-tests

Integration tests for WASI
Rust
2
star
58

.github

Github profile
2
star
59

wasmer-js-example

Wasmer-JS example
2
star
60

edge-react-starter

Wasmer Edge + Vite + React + TS starter template. Deploy it like it's hot 🚀
CSS
1
star
61

rustfft

Rustfft for WASM, published on WAPM
Rust
1
star
62

inline-c

Rust
1
star
63

speed.wasmer.io

Speed tracker of Wasmer
CSS
1
star
64

windows-llvm-build

Build of LLVM in Windows
1
star
65

wasmer-edge-support

1
star
66

zig2wapm

CI script to clone zig/zig to wapm.io
Shell
1
star
67

wasm4-on-wapm

This is a demo repo to showcase how to upload your WASM-4 games to WAPM
1
star
68

wai-hashids

Hashids demonstration with WAI
Rust
1
star
69

astro-starter-a1d

Astro
1
star
70

flask-starter-324

Python
1
star
71

wasmerio-flask-template

Python
1
star
72

wasmer-integration-tests

Integration tests between Edge and the backend
Rust
1
star