From 5203402374aeb1a6450747f7ca01798dd5d4cff8 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Mon, 6 Jun 2022 17:52:16 +0100 Subject: [PATCH] Add j2cl demo --- .docker/Dockerfile | 10 +++ java/browser-hello-world/.gitignore | 1 + java/browser-hello-world/README.md | 9 +++ java/browser-hello-world/WORKSPACE | 27 +++++++ java/browser-hello-world/run.sh | 5 ++ .../java/com/google/j2cl/samples/wasm/BUILD | 70 +++++++++++++++++++ .../google/j2cl/samples/wasm/HelloWorld.java | 25 +++++++ .../com/google/j2cl/samples/wasm/hello.js | 28 ++++++++ 8 files changed, 175 insertions(+) create mode 100644 java/browser-hello-world/.gitignore create mode 100644 java/browser-hello-world/README.md create mode 100644 java/browser-hello-world/WORKSPACE create mode 100755 java/browser-hello-world/run.sh create mode 100644 java/browser-hello-world/src/main/java/com/google/j2cl/samples/wasm/BUILD create mode 100644 java/browser-hello-world/src/main/java/com/google/j2cl/samples/wasm/HelloWorld.java create mode 100644 java/browser-hello-world/src/main/java/com/google/j2cl/samples/wasm/hello.js diff --git a/.docker/Dockerfile b/.docker/Dockerfile index 5b33069..a26c136 100644 --- a/.docker/Dockerfile +++ b/.docker/Dockerfile @@ -7,6 +7,16 @@ RUN npm install jsvu wasm-opt wasm-pack -g \ && dpkg -i tinygo_0.23.0_amd64.deb \ && rm tinygo_0.23.0_amd64.deb +RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ + && curl -fsSL https://storage.googleapis.com/www.bazel.build/bazel-release.pub.gpg | gpg --dearmor > bazel-archive-keyring.gpg \ + && mv bazel-archive-keyring.gpg /usr/share/keyrings/ \ + && echo "deb [arch=amd64 signed-by=/usr/share/keyrings/bazel-archive-keyring.gpg] https://storage.googleapis.com/bazel-apt stable jdk1.8" > /etc/apt/sources.list.d/bazel.list + +RUN apt-get update && apt-get install bazel-5.1.0 && ln -s /usr/bin/bazel-5.1.0 /usr/bin/bazel + +RUN curl -fsSL https://github.com/WebAssembly/binaryen/releases/download/version_108/binaryen-version_108-x86_64-linux.tar.gz | tar -xzf - \ + && (cd binaryen-version_108; cp -rf * /usr) && rm -rf binaryen* + USER gitpod RUN rustup target add wasm32-wasi wasm32-unknown-unknown \ diff --git a/java/browser-hello-world/.gitignore b/java/browser-hello-world/.gitignore new file mode 100644 index 0000000..6d8ad95 --- /dev/null +++ b/java/browser-hello-world/.gitignore @@ -0,0 +1 @@ +bazel-* \ No newline at end of file diff --git a/java/browser-hello-world/README.md b/java/browser-hello-world/README.md new file mode 100644 index 0000000..5c05296 --- /dev/null +++ b/java/browser-hello-world/README.md @@ -0,0 +1,9 @@ +# Java Implementation of WASM using J2CL + +This sample demonstrates how to use [j2cl](https://github.com/google/j2cl) to implement a WASM function in Java and call it from the browser on port 8000. + +To launch the browser (you need Chrome unstable): + +``` +$ google-chrome-unstable --js-flags="--experimental-wasm-typed-funcref --experimental-wasm-gc --experimental-wasm-eh" +``` \ No newline at end of file diff --git a/java/browser-hello-world/WORKSPACE b/java/browser-hello-world/WORKSPACE new file mode 100644 index 0000000..5a0892b --- /dev/null +++ b/java/browser-hello-world/WORKSPACE @@ -0,0 +1,27 @@ +workspace(name = "com_google_j2cl_samples_helloworld") +load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") + +http_archive( + name = "com_google_elemental2", + strip_prefix = "elemental2-1.1.0", + url = "https://github.com/google/elemental2/archive/1.1.0.zip", +) + +load("@com_google_elemental2//build_defs:repository.bzl", "load_elemental2_repo_deps") +load_elemental2_repo_deps() + +load("@com_google_elemental2//build_defs:workspace.bzl", "setup_elemental2_workspace") +setup_elemental2_workspace() + +# Load j2cl repository +http_archive( + name = "com_google_j2cl", + strip_prefix = "j2cl-master", + urls = ["https://github.com/google/j2cl/archive/refs/heads/master.zip"], +) + +load("@com_google_j2cl//build_defs:repository.bzl", "load_j2cl_repo_deps") +load_j2cl_repo_deps() + +load("@com_google_j2cl//build_defs:rules.bzl", "setup_j2cl_workspace") +setup_j2cl_workspace() diff --git a/java/browser-hello-world/run.sh b/java/browser-hello-world/run.sh new file mode 100755 index 0000000..50cd57e --- /dev/null +++ b/java/browser-hello-world/run.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +set -ex + +bazel run src/main/java/com/google/j2cl/samples/wasm:jsapp_dev_server diff --git a/java/browser-hello-world/src/main/java/com/google/j2cl/samples/wasm/BUILD b/java/browser-hello-world/src/main/java/com/google/j2cl/samples/wasm/BUILD new file mode 100644 index 0000000..00aab0d --- /dev/null +++ b/java/browser-hello-world/src/main/java/com/google/j2cl/samples/wasm/BUILD @@ -0,0 +1,70 @@ +# Sample for J2WASM copied from https://github.com/google/j2cl. +# +# Note that J2WASM is experimental and it is NOT production ready. +# +# It is mostly developed to help with the evolution of WASM GC specification and +# what is released externally here is minimal working version to provide .wat files +# for community experimentation and it doesn't reflect final workings of the product +# nor the WASM spec. + +load("@io_bazel_rules_closure//closure:defs.bzl", "closure_js_library") +load( + "@com_google_j2cl//build_defs:rules.bzl", + "j2cl_application", + "j2wasm_application", + "j2wasm_library", +) + +package(licenses = ["notice"]) + +# This is the bazel target that compiles our J2WASM library. +# Since J2WASM currently does global compilation this only serves as a way +# to collect sources and byte code required for j2wasm_application compilation. +j2wasm_library( + name = "helloworld", + srcs = glob(["*.java"]), +) + +# This is the bazel target that compiles and optimizes whole J2WASM app. +# It provides couple of convenient targets: +# :app produces the app.wat and app.wasm that could be used for production. +# :app_dev produces app_dev.wat and app_dev.wasm as development version +# +# e.g.: +# $ (cd j2cl; bazel build src/main/java/com/google/j2cl/samples/wasm:app) +# +# Note that for .wat files (wasm binary output) to be available, you would +# need to have a recent version of binaryen available in your path. +j2wasm_application( + name = "app", + entry_points = [r"com\.google\.j2cl\.samples\.wasm\.HelloWorld\.getHelloWorld"], + deps = [":helloworld"], +) + +# Below is an example of the JS wiring of the wasm app + +closure_js_library( + name = "hellojs", + srcs = glob(["*.js"]), + lenient = True, + deps = ["@com_google_j2cl//:j2wasm_js"], +) + +# This is the bazel target that serves your J2WASM app. +# +# Give it a try: +# $ (cd j2cl; bazel run src/main/java/com/google/j2cl/samples/wasm:jsapp_dev_server) +# +# To launch the browser (use unstable): +# +# $ google-chrome-unstable --js-flags="--experimental-wasm-typed-funcref --experimental-wasm-gc --experimental-wasm-eh" +# +j2cl_application( + name = "jsapp", + entry_points = ["entry"], + extra_dev_resources = [ + ":app.wasm", + ], + deps = [":hellojs"], + dev_server_port = "8000", +) diff --git a/java/browser-hello-world/src/main/java/com/google/j2cl/samples/wasm/HelloWorld.java b/java/browser-hello-world/src/main/java/com/google/j2cl/samples/wasm/HelloWorld.java new file mode 100644 index 0000000..e8bc345 --- /dev/null +++ b/java/browser-hello-world/src/main/java/com/google/j2cl/samples/wasm/HelloWorld.java @@ -0,0 +1,25 @@ +/* + * Copyright 2021 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.google.j2cl.samples.wasm; + +import javaemul.internal.WasmExtern; + +/** A simple hello world example. */ +public class HelloWorld { + public static WasmExtern getHelloWorld() { + return "Hello from Java!".toJsString(); + } +} diff --git a/java/browser-hello-world/src/main/java/com/google/j2cl/samples/wasm/hello.js b/java/browser-hello-world/src/main/java/com/google/j2cl/samples/wasm/hello.js new file mode 100644 index 0000000..494c149 --- /dev/null +++ b/java/browser-hello-world/src/main/java/com/google/j2cl/samples/wasm/hello.js @@ -0,0 +1,28 @@ +/* + * Copyright 2021 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +goog.module('entry'); + +const j2wasm = goog.require('j2wasm'); + +j2wasm.instantiateStreaming('app.wasm').then((instance) => { + document.body.innerText = instance.exports.getHelloWorld(); +}, (err) => { + document.body.style.color = 'red'; + document.body.innerText = `Failed to load wasm: ${err}`; + // rethrow so it also bubbles up to the console. + throw err; +});