WASM Logo

Eine Einführung in WASM nicht nur für Webentwickler

Bei der Cloud Native Computing Foundation (kurz CNCF) wird in der Projektlandkarte „WASM“ inzwischen als eigener Filter angeboten. Trotzdem ist das Thema bei vielen noch unter dem Radar. Daher möchte ich mit diesem Artikel das Thema Webassembly mit der Beantwortung der zentralen Fragen beleuchten.

Was ist WASM?

WASM ist die Abkürzung für WebAssembly. Dabei handelt es sich um ein vom W3C standardisiertes, binäres und maschinennahes Format, das Instruktionen für eine Stack-basierte virtuelle Maschine (Laufzeitumgebung) bereitstellt. Es legt dabei einen großen Wert auf eine schnelle und effektive Verarbeitung. Bei der Ausführung wird zudem großer Wert auf Speichersicherheit und Isolation gelegt. Das klingt erst einmal alles sehr technisch. Doch dahinter steckt mehr.

Ist „Web“Assembly nur für Webentwickler relevant?

Nein! Das ist leider ein Vorurteil, das sich bei vielen festgesetzt hat.

Das „Web“ in WebAssembly kommt zum einen daher, dass bei der Entwicklung von WASM der Browser eine wichtige Zielplattform war. Dort wollte man abseits von JavaScript auch die Ausführung von anderen Programmiersprachen ermöglichen.

WASMs Ziel ist ähnlich wie damals bei der Java Virtual Machine überall zu laufen. Daher ist WASM für die unterschiedlichsten Plattformen relevant und betrifft die Entwicklung von Software in allen Bereichen:

  • Embedded Software
  • Graphical Programming
  • Multiplattform
  • Cloud Computing
  • IOT / Edge Computing
  • Simulationen
  • Microservices
  • Serverless
  • Plugins
  • AI

Welche Programmiersprachen sind für WASM geeignet?

Hier müssen wir unterscheiden zwischen Host-Sprachen und Source-Sprachen. Host-Sprachen sind Sprachen die WASM Komponenten konsumieren, also aufrufen können. Das setzt voraus, dass es eine Laufzeitumgebung für die Host-Sprache gibt. In der Regel stehen diese als Bibliothek für die entsprechende Sprache zur Verfügung und stellen eine entsprechende API bereit.

Source-Sprachen dagegen sind Sprachen die sich in das WASM-Format kompilieren lassen. Hier ist die Unterstützung der Sprachen recht unterschiedlich. Das hängt mit dem Problem zusammen, dass die Spracheignen Runtimes auf die besonderen Stärken und Eigenschaften ausgelegt sind und WASM dagegen es allen recht machen muss. Aktuelle Herausforderungen sind dabei Themen wie Garbage Collection und Multithreading. Entsprechende Standards dazu sind in der Entwicklung.

Sprachen die sich besonders gut als Source-Sprachen für WASM eigenen:

  • Rust
  • Zig
  • C/C++
  • Go(TinyGo)

Es entwickeln sich auch immer mehr Sprachen die direkt für die Entwicklung von WASM Anwendungen konzipiert sind:

  • Grain
  • MoonBit
  • AssemblyScript

Insgesamt haben aber die allermeisten Sprachen Ambitionen WASM zu unterstützen. Hier gibt es eine Übersicht:

Wie betrifft mich das als Javaentwickler?

Die Beziehung zwischen Java und WASM ist nicht ganz einfach. Mit der GraalVM hat Oracle auch Funktionen entwickelt die ähnliche Ziele verfolgen wie WASM. Z.B. das Trueffle/Sulong Framework, welches es ermöglicht weitere Sprachen auf der JVM zu betreiben.

Auf der JVM zeigt besonders Kotlin Ambitionen WASM als Kompilierungsziel gut zu unterstützen. Der Hintergrund liegt dabei sicher in den Ambitionen der Multiplattformentwicklung von JetBrains, dem Entwickler hinter Kotlin.

Für Java gibt es diverse Lösungen. Zum Beispiel die TeaVM welche Java Bytecode zu WASM kompiliert. Oder auch J2CL, bekannt aus Frameworks wie GWT oder Vaadin, die darauf aufbauen Java zu JavaScript zu kompilieren, experimentiert mit einer WASM Unterstützung. Um ein einfaches Programm zu bauen reicht es dann aus ein Mavenplugin zu konfigurieren.

Ein großes Thema ist der Garbage Collector. Es gibt Bestrebungen auch diesen mit WasmGC zu standardisieren. Dann müssen Lösungen wie TeaVM keine eigenen Implementierungen in das Artefakt hinein kompilieren.

Insgesamt gibt es zu dem Thema WASM/Java einen sehr empfehlenswerten Artikel der viele Fragen beantwortet: https://www.javaadvent.com/2023/12/a-return-to-webassembly-for-the-java-geek.html

Wie performant ist WASM?

Die Performanz von WASM lässt sich nicht eindeutig bestimmen, da diese von vielen Faktoren abhängt. Sowohl der verwendete Compiler, die Hardware, wie auch die Laufzeitumgebung haben am Ende einen maßgeblichen Einfluss darauf. In der Laufzeitumgebungen können Optimierungen Just in Time (JIT) vorgenommen werden. Die Laufzeitumgebung Wasmtime kann zum Beispiel WASM beim ersten start in nativen Maschinencode kompilieren und so native Performanz erreichen.

Am Ende kommt es darauf an was man als Maßstab für schnell ansetzt. Hier ein Beispiel aus der Kotlin Dokumentation:

Was hat WASM mit Docker zu tun?

Wenn man sich ein wenig umschaut findet man schnell Überschriften wie „WebAssembly: Das neue Docker und noch mehr?“.
Auch die steigende Relevanz von WASM bei der Cloud Native Computing Foundation lässt ein wenig die Frage aufkommen ob WASM das neue Docker ist. Doch was hat WASM wirklich mit Docker zu tun?

a) WASM läuft überall und eignet sich daher Software portabel zu implementieren. Nehmen wir das Beispiel einer Datenbank. Vor Docker war es notwendig diese speziell für das genutzte Betriebssystem zu installieren. Mit Docker konnte man dann dazu auf verschiedenen Systemen den gleichen Befehl verwenden. Genauso ist es mit WASM. Ist eine Software mit WASM gebaut kann sie auf verschiedenen Systemen einfach und einheitlich ausgeführt werden. Da WASM auch im Browser läuft, nutzen das viele moderne Datenbanken um eine Spielwiese anzubieten (Beispiel: CozoDB). Die Datenbank wird dazu dann komplett lokal im Browser ausgeführt. Dadurch fällt auch der Sicherheitsaspekt weg, der bei einer Serverseitig betriebenen Datenbank problematisch werden kann.

b) Bei Docker geht es um die „Containerisierung“ von Anwendungen. Das bedeutet alles notwendige für die Ausführung einer Anwendung in einem Artefakt zu bündeln. Genauso eignet sich WASM für diesen Zweck. Durch WASI werden Abhängigkeiten zum Beispiel zum Filesystem entkoppelt und können von der Laufzeitumgebung virtualisiert werden. Am Ende können WASM Komponenten in einer Registry abgelegt und bei bedarf konsumiert werden.

c) Da WASM auf die Entwicklung von modernen cloudbasierten und verteilten Anwendungen abzielt wird im Tooling die Orchestrierung mitbedacht. Ähnlich wie bei Docker-Compose oder Kubernetes wird bei WASM auf deklarative Deployments gesetzt. Die WASM Plattformen bieten einen ähnlichen Arbeitsablauf wie mit Docker an. Bei Spin verwendet man zum Beispiel vertraute Befehle wie spin build oder spin up oder bei wasmCloud wash up und wash app list. Für Kubernetes gibt es auch direkte Erweiterungen um WASM orchestrieren zu können.

Wie sieht das WASM Ökosystem aus?

Um WASM herum hat sich ein Ökosystem gebildet, das Lösungen für verschiedene Probleme anbietet. Hier die wichtigsten Teile dieses Ökosystems:

  • WASI – Ähnlich wie die Web APIs im Browser, definiert WASI eine Menge an Schnittstellen die dann von WASM Programmen einheitlich genutzt werden können. Die Schnittstelle umfast Funktionen wie Zeit, Zufall, Dateisystem, HTTP und IO. Die Implementierung kann dann von der Laufzeitumgebung entsprechend den Anforderungen zur verfügung gestellt werden. Entsprechend kann eine „Sandbox“ realisiert werden.
  • WIT – Ähnlich wie bei Typescript die Declaration Dateien bietet WASM mit WIT ein Format an, Schnittstellen mit einer Interface Declaration Language (IDL) zu definieren. Das ermöglicht das erstellen eines Schnittstellenvertrages zwischen WASM Komponenten und dient der (unter anderem menschlesbaren) Dokumentation sowie der Toolunterstützung. Ein ähnliches Konzept findet man auch bei gRPC oder OpenAPI Spezifikationen.
  • Component Model – Ein kompiliertes WASM Programm liegt als *.wasm Datei vor. Man spricht von einem einfachen Modul. Damit mit diesem Modul und zwischen anderen Modulen kommuniziert werden kann fehlen aber wichtige Informationen. Zum Beispiel wie sich komplexe Datentypen wie Kollektionen oder Strukturen darstellen. Hierfür sieht das Component Model WIT Deklerationen vor die den Import/Export beschreiben. Mit diesen Informationen spricht man dann von einer Komponente. Des weiteren definiert das Component Model eine ABI, welche zum Beispiel das Format von Strings regelt, da Strings von Programmiersprache zu Programmiersprache unterschiedlich repräsentiert werden können. Eine Komponente ist damit eine Library die mit anderen geteilt werden kann.

Was sind die Vor- und Nachteile von WASM?

Vorteile

  • Kompaktes Format – Im Vergleich zu JavaScript ist ein kompiliertes Programm kompakter. Oder als Alternative zu Docker Container können Anwendungen als Artefakte im Bereich von Kilobytes anstatt Megabytes verteilt werden.
  • Läuft überall – Da die Laufzeitumgebung für WASM relativ einfach zu entwickeln ist, gibt es für die verschiedensten Plattformen eine. Damit fällt die notwendigkeit weg den Code für verschiedene Plattformen zu kompilieren. Die JVM lässt grüßen ;).
  • Sicherheit – Bei der Entwicklung von WASM lag die Ausführung in einer Isolierten Umgebung (Sandbox) im Fokus. Entsprechend ist WASM mit den Sicherheitsanforderungen bei der Codeausführung im Browser kompatibel. Aber auch in der Cloud können WASM Anwendungen virtualisiert ausgeführt werden.
  • Polyglot – Programme können mit verschiedenen Programmiersprachen entwickelt werden. Teile von Programmen können in einer passenden Sprache entwickelt werden. Die Abhängigkeit zu einem spezifischen Ökosystem sinkt.
  • Erweiterbarkeit – Besonders für die Entwicklung eines Pluginsystems ist WASM besonders gut geeignet. Das einbinden einer WASM Runtime in ein Host System ist relativ einfach. Durch die Modularisierung von WASM Anwendungen müssen auch nur die teile neu gebaut werden die sich geändert haben.
  • Ordentliche Performanz und schnelle Startzeiten. Damit ist WASM perfekt für Serverless geeignet. Programme können instant ausgeführt werden und müssen daher nicht als Server laufen.

Nachteile

  • Status – WASM existiert schon seit 2017. Trotzdem sind viele Aspekte noch in der Entwicklung. Jede Sprache wird unterschiedlich gut unterstützt. Besonders das Ökosystem ist nicht einfach zu verstehen. Wie Komponenten und Sprachen zusammenspielen können wird gerade noch definiert. Entsprechend ist auch das Tooling noch stark in der Entwicklung.
  • Angriffsfläche – Wie jede zusätzliche Technologie und Komplexität bringt auch WASM neue Angriffsflächen mit in das Projekt. Da das Programm in einem Binären Format kommuniziert wird, ist es auch entsprechend schwerer Sicherheitsprobleme darin zu erkennen.

Spannende WASM Projekte

Fazit

Rund um WASM ist viel in Bewegung. Es gibt einige spannende Projekte, aber auch einiges an technischer Komplexität, wo derzeit Lösungen entwickelt und etabliert werden. Eine sehr große Stärke von WASM ist, dass es sich um einen offenen Standard handelt, was zum Beispiel auch bei der Entwicklung und Verbreitung des Internets ein wichtiger Faktor war. Ich kann mir vorstellen, dass WASM eine ähnliche Rolle einnimmt wie das Language Server Protocol bei der Unterstützung von Programmiersprachen in IDEs. Das bedeutet ein viel offeneres und breiteres Ökosystem, das davon profitiert, dass nicht jeder selbst das Rad neu erfinden muss. Gerade im Serverless Bereich könnte WASM der Standard für die Laufzeitumgebungen werden. Damit wäre auch die Zeit vorbei in der der Erfolg einer Programmiersprache, maßgeblich an den verfügbaren Frameworks und Libraries bzw. einer Killeranwendung hängt. Selbst Komponenten innerhalb einer Anwendung können mit verschiedenen Programmiersprachen entwickelt und kombiniert werden. Die Karten werden neu gemischt.

Markus Hettich

Über MICH

Alle Beiträge von Markus Hettich

Mehr erfahren

Weitere Infos auf unserer Website und in unserem Newsletter

Pfeil hoch