{"id":16909461,"url":"https://github.com/bluejekyll/wasmtime-java","last_synced_at":"2025-03-22T10:31:41.843Z","repository":{"id":37177521,"uuid":"298454229","full_name":"bluejekyll/wasmtime-java","owner":"bluejekyll","description":"Wasmtime bindings for Java","archived":false,"fork":false,"pushed_at":"2023-07-24T04:45:07.000Z","size":325,"stargazers_count":38,"open_issues_count":15,"forks_count":6,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-03-18T10:37:56.570Z","etag":null,"topics":["java","wasm","wasmtime"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bluejekyll.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-09-25T03:07:34.000Z","updated_at":"2025-01-20T11:16:21.000Z","dependencies_parsed_at":"2024-10-28T13:15:36.520Z","dependency_job_id":"1557b31d-cf7d-4eaa-9722-e87245311ca5","html_url":"https://github.com/bluejekyll/wasmtime-java","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bluejekyll%2Fwasmtime-java","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bluejekyll%2Fwasmtime-java/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bluejekyll%2Fwasmtime-java/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bluejekyll%2Fwasmtime-java/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bluejekyll","download_url":"https://codeload.github.com/bluejekyll/wasmtime-java/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244943877,"owners_count":20536290,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["java","wasm","wasmtime"],"created_at":"2024-10-13T18:55:52.070Z","updated_at":"2025-03-22T10:31:41.442Z","avatar_url":"https://github.com/bluejekyll.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![test](https://github.com/bluejekyll/wasmtime-java/workflows/test/badge.svg?branch=main)](https://github.com/bluejekyll/wasmtime-java/actions?query=workflow%3Atest)\n\n# Java bindings to the Wasmtime runtime engine\n\nWASM, web-assembly, is a low-level stack execution engine. This library gives a JNI based binding to the Wasmtime WASM runtime.\n\nFor more information, please see [github.com/bytecodealliance/wasmtime](https://github.com/bytecodealliance/wasmtime).\n\nThis is very early stages. All interfaces are subject to change. Supported platforms, x86_64 for Linux and macOS. Windows should also be supported, but currently not due to lack of resources.\n\n## Building\n\nUse the provided Makefile. You need Java 11 (not 17), Maven and Rustup (the error messages will prompt you to install that if you don't have it).\n\nEnsure tools are installed:\n\n```shell\n\u003e make init\n```\n\nRun tests:\n\n```shell\n\u003e make test\n```\n\nInstall the maven packages locally:\n\n```shell\n\u003e make install\n```\n\n## Using in Java\n\nMaven co-ordinates for the installed artifacts: `net.bluejekyll:wasmtime-java:1.0-SNAPSHOT`.\n\n### Initializing the Wasmtime runtime\n\nInitialize the WASM runtime. Much of this is not threadsafe, so be aware...\n\n```java\n// Initiale the Wasmtime JNI bindings (this will happen once per ClassLoader)\nWasmtime wasmtime = new Wasmtime();\n// Get a new Engine (one per thread)\nWasmEngine engine = wasmtime.newWasmEngine();\n// Compile The module, this can be reused, i.e. is cacheable for multiple executions\nWasmModule module = engine.newModule(${PATH_TO_MODULE});\n```\n\nOnce the runtime is initialized, create a new instance. This requires a linker, and exported functions if the module has imports that need to be met.\n\n```java\n// create a new store and linker\nWasmStore store = engine.newStore();\nWasmLinker linker = store.newLinker();\n\n// This will link in exports from Java to the WASM module, if that module has imports, see below\nlinker.defineFunctions(this.store, new TestExport());\n```\n\n### Exporting functions to Webassembly\n\nTo export functions into WASM, that are bound to the WASM module's imports, a class must implement the `WasmExportable` interface. Each method to export and be bound to functions the corresponding function in WASM must be annotated with `WasmExport`.\n\nSee [`TestExport`](https://github.com/bluejekyll/wasmtime-java/blob/fd075fe88ba106409d10a1c985f8573f2d7936e2/src/test/java/net/bluejekyll/wasmtime/proxy/TestExport.java) for example:\n\n```java\n// Specify the module name that we need to export functions into (imports in the WASM)\n@WasmModule(name = \"test\")\npublic class TestExport implements WasmExportable {\n\n    // Export the function to WASM and give the name that corresponds to the import in WASM\n    @WasmExport(name = \"reverse_bytes_java\")\n    public final byte[] reverseBytesJava(ByteBuffer buffer) {\n        ByteBuffer toReverse = buffer.duplicate();\n        byte[] bytes = new byte[toReverse.remaining()];\n\n        for (int i = bytes.length - 1; i \u003e= 0; i--) {\n            bytes[i] = toReverse.get();\n        }\n\n        return bytes;\n    }\n\n}\n```\n\nAfter Wasmtime is initiated and the module compiled, then it can be linked and an instance created:\n\n```java\nlinker.defineFunctions(this.store, new TestExport());\nWasmInstance instance = linker.instantiate(module);\n```\n\n### Importing functions implemented in Webassembly\n\n`WasmImportProxy` To work with the Proxy builder, an `interface` must extend the `WasmImportable` interface. It should be annotated to specify the WASM module being bound to.\n\nSee [`TestImportProxy`](https://github.com/bluejekyll/wasmtime-java/blob/fd075fe88ba106409d10a1c985f8573f2d7936e2/src/test/java/net/bluejekyll/wasmtime/proxy/TestImportProxy.java) for example:\n\n\n```java\n// This annotation allows for the WASM module name to be specified\n@WasmModule(name = \"test\")\npublic interface TestImportProxy extends WasmImportable {\n    // This annotation allows for the function name to be set as it is defined in WASM\n    @WasmImport(name = \"add_i32\")\n    int addInteger(int a, int b);\n}\n```\n\nThis can now be used with `WasmImportProxy` to create a proxy that will call into the specified functions in WASM, see [`ImportTests`](https://github.com/bluejekyll/wasmtime-java/blob/fd075fe88ba106409d10a1c985f8573f2d7936e2/src/test/java/net/bluejekyll/wasmtime/proxy/ImportTests.java):\n\n```java\nWasmInstance instance = linker.instantiate(this.module);\nWasmImportProxy importProxy = new WasmImportProxy(instance);\nTestImportProxy proxy = importProxy.newWasmProxy(TestImportProxy.class);\n\nint ret = proxy.addInteger(3, 2);\n```\n\n## Structure\n\nThe Java is meant to be as minimal as possible. All Wasmtime object references are stored in Java objects as opaque pointers (longs). The safety in this area has not yet been proven. Thread safety in particular is non-existent. The WasmEngine should be safe to share across threads, though we should most likely introduce a custom clone method for this purpose.\n\n### Adding new native methods\n\nThe Java compiler will automatically output the headers for the JNI bindings based on the native methods defined in the various classes. While the headers generated by the Java compiler aren't directly used during the Rust JNI compilation, they are useful for seeing the C signature that the Rust needs to export. The files can be found in `target/generated-sources/*.h`.\n\n## Debugging\n\nThe tests should all run regardless of platform. Windows hasn't been fully tested due to lack of resources. If tests fail to run, there are a few different environments at play which will make discovering which component failed and why difficult. At the moment, all output from Java is captured in `txt` files at in the `target/surfire-reports/{CLASS_NAME}-output.txt`. All output from the JNI bindings is currently captured in `target/wasm-logs/java_{DATE}.log`, this may be combined into the same place in the future. In the `pom.xml` Maven project file, the `surfire` test configuration has `RUST_LOG` set to `debug` by default. This can be set to any other value to increase or decrease logging output.\n\n## libc like support with WASI\n\n[WASI](https://wasi.dev/) is supported for things like printing to stdout. This is supplied during linking in the Java bindings. It is not required, in Rust this can be targeted with `cargo build --target wasm32-wasi`, that target must be installed with `rustup` before hand.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbluejekyll%2Fwasmtime-java","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbluejekyll%2Fwasmtime-java","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbluejekyll%2Fwasmtime-java/lists"}