Exécuter Java VM avec Web Assembly

Parlons de Web Assembly, qui s'améliore récemment. Je voudrais créer un environnement où Java peut être exécuté en tant que sujet. Oui, c'est un interpréteur Java (Java VM) qui s'exécute dans un navigateur, comme une applet Java.

Tout d'abord, je voudrais refuser. Bien qu'il s'agisse d'un interpréteur Java qui interprète le bytecode Java, il implémente un bytecode minimal. De plus, comme il n'implémente que quelques classes sous java / lang, il est pratiquement inutile. Personnellement, je l'ai fait pour étudier l'interpréteur Java. Je suis désolé pour ceux qui s'y attendaient.

Nous allons procéder comme suit.

J'ai appelé "waba" le code source du langage C de l'interpréteur Java. J'ai beaucoup appris. Merci beaucoup.

wabasoft  http://wabasoft.com/

J'ai utilisé "emscripten" pour le compilateur WebAssembly.  https://emscripten.org/index.html

Ce qui suit est la suite. Exécution de Java VM avec Web Assembly: Supplement

Installez emscripten

Je l'ai installé dans l'environnement WSL de Windows 10. J'utilise donc Python 2.7, mais il était déjà installé.

> python --version
Python 2.7.15rc1
> git clone https://github.com/juj/emsdk.git
> cd emsdk
> ./emsdk install latest
> ./emsdk activate latest

Vous avez maintenant installé le compilateur WebAssembly "emcc". Lorsque vous l'utilisez, vous devez le transmettre, procédez comme suit:

> source ./emsdk_env.sh --build=Release

Créer un dossier de projet

Créez un dossier approprié et travaillez.

Placez un ensemble de fichiers source en langage C dans le même dossier.

Je l'ai posté sur le GitHub suivant.

https://github.com/poruruba/javaemu

> git clone https://github.com/poruruba/javaemu.git
> cd javaemu

Compiler le code source Java à intégrer dans WebAssembly

Compilez le code source Java. Le code source Java est divisé en deux types et la méthode de placement est modifiée. Le premier est la source Java intégrée à WebAssembly et l'autre est la source Java qui n'est pas intégrée à WebAssembly. Ce dernier est un code source Java standard écrit par l'utilisateur. D'autre part, java / lang etc. sont utilisés par des utilisateurs ordinaires, et la source Java du système qui ne change pas est la première. Le premier est également une classe Java qui a des fonctions natives qui ne peuvent être traitées qu'en langage C et qui fonctionne avec des interprètes.

On suppose que le code source sera créé dans le dossier java_src. Créez un dossier pour placer les fichiers de classe compilés. Disons pré_classes.

> mkdir pre_classes

La compilation est la suivante.

>javac -encoding UTF8 -d pre_classes -sourcepath java_src java_src/base/framework/*.java java_src/java/lang/*.java java_src/test/*.java

Les fichiers source Java sous base / framework et java / lang sont les sources Java du système. java_src / test / *. java sera utilisé pour les tests plus tard, veuillez donc le supprimer après le test. Vous avez maintenant un fichier de classe Java dans le dossier pre_classes.

J'ai utilisé le JDK Oracle sous Windows. Dans le cas d'OpenJDK, j'ai rencontré un fichier de classe sur l'environnement d'exécution et je ne savais pas comment l'exclure. .. ..

Compiler le code source du langage C

Compilons

> emcc *.c -s WASM=1 -o javaemu.js -s "EXTRA_EXPORTED_RUNTIME_METHODS=['ccall', 'UTF8ArrayToString', 'stringToUTF8Array']" --preload-file pre_classes

(Référence) Options de compilation  https://emscripten.org/docs/tools_reference/emcc.html#emccdoc

-s WASM = 1 est un sort qui indique qu'un fichier WASM sera généré.

-o javaemu.js sert à générer un fichier (javaemu.data) qui combine un fichier WASM (javaemu.wasm), un utilitaire Javascript (javaemu.js) et un fichier de classe Java à incorporer dans WebAssembly. Le nom javaemu est approprié. Veuillez utiliser le nom de votre choix.

-s EXTRA_EXPORTED_RUNTIME_METHODS est le nom de la fonction fournie par javaemu.js qui peut être appelée à partir du Javascript de la page HTML placée sur le Web. ccall est requis, mais les deux autres sont utiles, je les ai donc définis.

--preload-file spécifie le nom du dossier dans lequel se trouvent les fichiers à incorporer dans WebAssembly. Les fichiers sous le nom de dossier spécifié sont regroupés dans un fichier appelé javaemu.data.

Parmi les fichiers terminés, ceux à placer sur le Web sont "javaemu.wasm", "javaemu.js" et "javaemu.data". javaemu.wasm est juste un fichier WebAssembly qui compile le langage C.

Les fonctions appelées depuis Javascript sur les pages Web sont définies dans main.c.

main.c


int EMSCRIPTEN_KEEPALIVE setInoutBuffer(const unsigned char *buffer, long bufferSize );
int EMSCRIPTEN_KEEPALIVE setRomImage(unsigned char *romImage, long romSize );
int EMSCRIPTEN_KEEPALIVE callStaticMain(char *className, char *param );

Vérifiez le fonctionnement du code d'octet Java placé sur le Web et intégré dans l'assembly Web.

Téléchargez le html des fichiers déposés de GitHub sur le serveur Web. Nous avons également préparé une page pour vérifier le fonctionnement. Placez également les trois fichiers que vous venez de générer dans le dossier html.

> cp javaemu.wasm javaemu.js javaemu.data html/

Ou

> cd html
> ln -s ../javaemu.wasm ../javaemu.js ../javaemu.data .
> cd ..

(Veuillez le mettre dans le dossier racine de HTML, sinon javaemu.js ne lira pas bien les fichiers wasm et données)

Heureusement, emscripten a une fonction de serveur Web simple, donc je vais l'utiliser. Le numéro de port est 8080.

emrun --serve_root html --no_browser --port 8080 .

Maintenant, accédons-y depuis le navigateur. En tant que navigateur, j'ai essayé de l'exécuter sur Chrome sous Windows.

http://localhost:8080

image.png

Pour plus de clarté, j'appuie sur F12 pour faire apparaître la console développeur.

Entrez le nom de la classe Java intégrée pour tester le nom de la classe. C'est "test / TestFunc".

Le code source d'origine ressemble à ce qui suit.

TestFunc.java


package test;

import base.framework.System;
import base.framework.Convert;
import base.framework.Util;

public class TestFunc{
  public static void main( String[] args ){
  	try
  	{
  		System.println("Hello test/TestFunc");

  		if( args.length >= 1 )
  			System.println("args[0]=" + args[0]);
  		
  		String[] input = System.getInput(-1);
  		for( int i = 0 ; i < input.length ; i++ )
	  		System.println("params[" + i + "]=" + input[i]);

  		System.setOutput(new String[]{ "World", "Bonsoir" });
  	}catch( Exception ex )
  	{
		System.print( ex.toString() );
  		ex.printStackTrace();
  	}
  }
}

Entrez une chaîne de caractères appropriée dans Input Arg et Input Params. Appuyez immédiatement sur le bouton «start was m».

Appelez la fonction implémentée en langage C avec le sentiment suivant. Le chargement et l'exécution du fichier WebAssembly demandent beaucoup de travail, mais javaemu.js le fait bien.

start.js


            this.output_return = Module.ccall('callStaticMain', // name of C function 
                                    "number", // return type
                                    ["string", "string"], // argument types
                                    [this.class_name, this.input_arg]); // arguments

image.png

Ensuite, alors que les caractères de débogage désordonnés étaient affichés dans la console du navigateur, je pense que la chaîne de caractères suivante était affichée. L'exécution du fichier de classe Java par l'interpréteur Java est terminée.

Hello test/TestFunc args[0]=ABCD params [] = Aiueo params [1] = Kakikukeko

En outre, vous devriez voir ce qui suit sur la page.

Output Return 0 Paramètres de sortie ["Monde", "Bonsoir"]

Compilez le code source Java qui n'était pas incorporé dans WebAssembly.

Créons et exécutons maintenant diverses sources Java.

Je vais le créer sous java_src. Cette fois, nous allons le créer dans le dossier test2.

La compilation est la suivante.

> mkdir classes
> javac -encoding UTF8 -d classes -sourcepath java_src -classpath pre_classes java_src/test2/*.java

Je crée un dossier classes pour stocker les fichiers de classe. Puisque pre_classes est supposé être incorporé dans le fichier WebAssembly, il est supposé qu'il s'agit d'un fichier de classe existant et compilé.

Ensuite, transformez le fichier de classe créé en fichier Jar.

> jar cvf classes.jar -C classes .

Les fichiers sous le dossier classes sont désormais regroupés dans le fichier classes.jar. Des fichiers autres que le fichier de classe test2 ont également été créés, mais ils sont inoffensifs et peuvent être ignorés ou exclus de la cible du fichier Jar.

Cliquez sur le bouton "Sélectionner un fichier" et spécifiez le "classes.jar" créé précédemment. En dessous, une liste des fichiers de classe inclus dans le fichier Jar sera affichée.

J'ai utilisé unzip.min.js de zlib.js pour extraire le fichier Jar, c'est-à-dire le fichier ZIP.

zlib.js  https://github.com/imaya/zlib.js

Maintenant, exécutez-le à nouveau depuis le navigateur.

image.png

Spécifiez test2 / TestFunc inclus dans le fichier Jar pour le nom de la classe et cliquez sur le bouton "start was m" pour exécuter.

Avez-vous vu ce qui suit sur la console? Il devient test2 / TestFunc et vous pouvez voir que la source correspondante est en cours d'exécution.

Hello test2/TestFunc args[0]=ABCD [] = Aiueo [1] = Kakikukeko

Supplément

L'interpréteur Java a été fortement personnalisé à partir de waba et est plein de bugs, donc j'aimerais beaucoup le refuser. .. ..

L'explication sera dans le prochain article. D'abord ici.

Ce qui suit est la suite. Exécution de Java VM avec Web Assembly: Supplement

c'est tout.

Recommended Posts

Exécuter Java VM avec Web Assembly
Exécution de JavaVM avec WebAssembly: supplément
Exécuter un lot avec docker-compose avec Java batch
Exécuter des applications écrites en Java8 en Java6
Profilage avec Java Visual VM ~ Utilisation de base ~
Développement Java avec Codenvy: Hello World! Run
Exécuter Rust depuis Java avec JNA (Java Native Access)
En utilisant Gradle avec VSCode, compilez Java → exécutez
S'entendre avec les conteneurs Java dans Cloud Run
Installez java avec Homebrew
Changer de siège avec Java
Installez Java avec Ansible
Exécutez PostgreSQL sur Java
Téléchargement confortable avec JAVA
Changer java avec direnv
Exécutez Payara avec Docker
Téléchargement Java avec Ansible
Raclons avec Java! !!
Construire Java avec Wercker
Conversion Endian avec JAVA
[Tutoriel] Télécharger Eclipse → Lancer l'application avec Java (Pléiades)
[Tutoriel] Télécharger Eclipse → Lancer l'application Web avec Java (Pléiades)
Java EE sans serveur à partir de Quarkus et Cloud Run
(Java) BDD facile avec Spectrum?
Utiliser des couches Lambda avec Java
Créer un multi-projet Java avec Gradle
Premiers pas avec Java Collection
Configuration Java avec Spring MVC
Authentification de base avec Java 11 HttpClient
Expérimentons l'expansion en ligne Java
[Template] Connexion MySQL avec Java
Réécrire Java try-catch avec facultatif
[Java] Communication JSON avec jackson
Exécutez TAO Core avec Docker
Java pour jouer avec Function
Essayez la connexion DB avec Java
Activer Java EE avec NetBeans 9
[Java] JavaConfig avec classe interne statique
Essayez gRPC avec Java, Maven
Exploitons Excel avec Java! !!
Gestion des versions Java avec SDKMAN
Exécutez LIFF avec Spring Boot
Cryptage / décryptage RSA avec Java 8
Pagination de PDF avec Java + PDFBox.jar
Trier les chaînes comme une fonction caractéristique avec Java
Orienté objet avec Strike Gundam (java)
Exécuter des rails à chaque fois dans le docker
[Java] Acquisition de contenu avec HttpCliient
Gestion des versions Java avec jenv
Dépannage avec Java Flight Recorder
Rationalisez les tests Java avec Spock
Exécutez l'applet java sur ubuntu
Connectez-vous à MySQL 8 avec Java
Erreur lors de la lecture avec java
Utilisation de Mapper avec Java (Spring)
Mémo d'étude Java 2 avec Progate
Premiers pas avec les bases de Java
Affichage saisonnier avec commutateur Java
Utiliser SpatiaLite avec Java / JDBC
Étudier Java avec Progate Note 1