Saltar al contenido

WebImage: de la JVM a WebAssembly

Compile Java o Kotlin en un módulo WebAssembly y un cargador JavaScript con el artefacto WebImage de Elide: requisitos previos, backends, hosts y opciones del compilador.

En esta página

Un artefacto WebImage compila bytecode de la JVM en un cargador JavaScript más un módulo WASM. Para ejecutar un binario WASM o WASI existente, consulte WebAssembly.

Requisitos previos

  • Binaryen 119 o posterior, con wasm-as en el PATH durante la compilación.
  • Código que cumpla los requisitos de Native Image: metadatos de alcanzabilidad para reflexión, recursos y proxies; sin dependencias nativas.
  • Un host con manejo de excepciones de WASM (y WASM GC para wasm-gc): Node.js 25+ o un navegador actual.

El paquete desplegado no necesita ni Elide ni Binaryen.

Compilar un proyecto completo

hello-wasm/
  elide.pkl
  src/main/java/Hello.java
public class Hello {
  public static void main(String[] args) {
    System.out.println("Hello from WebImage");
  }
}
amends "elide:project.pkl"
import "elide:Jvm.pkl" as jvm
import "elide:NativeImage.pkl" as nativeImage

name = "hello-wasm"

artifacts {
  ["app-jar"] = new jvm.Jar {
    sources { "main" }
  }
  ["web"] = new nativeImage.WebImage {
    from { "app-jar" }
    name = "hello"
    entrypoint = "Hello"
    backend = "wasm-gc"
    runtime = "generic"
    autoRun = true
    sourceMap = false
    options {
      optimization = "b"
    }
  }
}
elide build

Elide genera app-jar y después lo compila en web. name es el nombre base sin .js ni .wasm; optimization = "b" es el modo de compilación rápida. La salida va a .dev/artifacts/native-image/:

ArchivoPropósito
hello.jsCargador JavaScript y punto de entrada.
hello.js.wasmMódulo WASM, cargado por hello.js.
hello.js.watForma de texto de WASM, para inspección.
hello.js.mapMapa de código fuente del cargador, con sourceMap = true.

Despliegue hello.js y hello.js.wasm juntos. Kotlin y otros lenguajes de la JVM funcionan igual una vez empaquetados en un JAR. Un acierto de caché restaura el paquete completo; desactivar sourceMap elimina el .js.map anterior.

Elegir backend y host

PropiedadValorSignificado
backend"wasm-gc" (predeterminado)Usa el recolector de basura de WASM del host.
backend"wasm-lm"Usa un recolector de basura en memoria lineal; sigue necesitando el cargador, no es un binario WASI.
runtime"generic" (predeterminado)El cargador admite navegadores y Node.
runtime"browser"Cargador especializado para navegadores.
runtime"node"Cargador especializado para API compatibles con Node.
autoRuntrue (predeterminado)Inicia el programa al cargarse el cargador; false deja el inicio a la página que lo incrusta.
sourceMapfalse (predeterminado)true genera hello.js.map.

El punto de entrada es obligatorio incluso con autoRun = false. Ningún runtime está destinado a Cloudflare Workers, Fastly Compute ni WASI. Los campos compartidos (from, entrypoint, moduleName, options) se describen en Native Image. Un WebImage no puede ser la entrada de un artefacto de contenedor.

Guías por destino: Browser WASM y Edge WASM.

Ejecutar en un host de backend

Con runtime = "generic" o "node":

node .dev/artifacts/native-image/hello.js
Hello from WebImage

Ejecutar en un navegador

Con runtime = "browser" o "generic" y autoRun = true, coloque este index.html en .dev/artifacts/native-image/:

<!doctype html>
<html lang="en">
  <meta charset="utf-8" />
  <title>Hello WebImage</title>
  <body>
    <p>Open the browser console to see the application output.</p>
    <script src="./hello.js"></script>
  </body>
</html>
elide dev --no-tui --port 8000 .dev/artifacts/native-image

Abra http://localhost:8000/; la salida aparece en la consola del navegador. Las URL file:// no funcionan.

Opciones del compilador

El bloque options del artefacto admite las opciones del compilador de Native Image; cuáles se aplican depende del backend. Dos casos propios de WebImage:

  • options.driverMode = "external" usa native-image de GRAALVM_HOME o JAVA_HOME; esa instalación debe admitir los backends de WebAssembly.
  • -H:EntryPointsConfig=config/entrypoints.json en options.flags define los puntos de entrada; la ruta es relativa a la raíz del proyecto, y modificar el archivo provoca una nueva compilación.

Compilar sin manifiesto de proyecto

elide javac -- -d classes src/main/java/Hello.java
elide native-image -- --tool:wasm-gc -Ob -cp classes -o hello Hello
elide native-image -- --tool:wasm-lm -Ob -cp classes -o hello-lm Hello

Los paquetes se escriben en el directorio actual. Un artefacto NativeImage con --tool:wasm-gc o --tool:wasm-lm en options.flags sigue compilándose. Para migrarlo, cambie la clase a WebImage, quite la opción y cualquier type, y establezca backend.

Solución de problemas

SíntomaSolución
No se encuentra wasm-asInstale Binaryen y añádalo al PATH de la compilación.
El controlador externo rechaza el backend de WebAssemblyHaga que GRAALVM_HOME o JAVA_HOME apunte a una instalación cuyo native-image lo admita, o use driverMode = "embedded".
Opciones sin procesar en conflictoQuite las opciones de backend, entorno de ejecución, inicio y mapa de código fuente; use las propiedades tipadas. No sobrescriba Backend ni la propiedad del lanzador.
El host rechaza instrucciones WASMUse un host con manejo de excepciones y, para wasm-gc, WASM GC.
El navegador no puede cargar el móduloSirva el cargador y el módulo juntos por HTTP; compruebe la URL solicitada.
elide run hello.js.wasm informa de importaciones ausentesEjecute hello.js en su lugar; el módulo necesita su cargador.

¿Te resultó útil esta página?