IKVM.NET est à la base une implémentation de la machine virtuelle java pour le framework .NET.
Le but de cet outil est de permettre l'exécution de modules ou applications développés en JAVA dans un environnement .NET et d'utiliser vos librairies de composants Java préférées "directement" dans vos applications .NET. Et inversement, il offre aussi la possibilité d'attaquer l'API .NET depuis une application JAVA.
Créé par Jeroen Frijters, IKVM.NET a rapidement été porté vers Mono, une implémentation open source du framework .NET pouvant être installée sur différents systèmes dont Windows, Linux et Mac OS X.
Pour fonctionner, IKVM.NET a donc besoin de Microsoft .NET Framework (1.1+) ou Mono (1.2+)
Deux modes d'utilisation possibles
Mode dynamique
Dans ce mode, on utilise le programme ikvm.exe pour lancer une application Java compilée. Plus précisément, ikvm.exe va fonctionner comme la machine virtuelle de Sun mais en effectuant une double traduction : du bytecode Java vers du bytecode .NET (CIL, Common Intermediate Language) puis, du bytecode .NET en code machine via le CLR (Common Language Runtime). De ce fait, l'application prendra un certain temps à démarrer.
Mode statique
Le mode statique consiste à compiler les classes Java et les archives jars en librairies .NET (DLL) à l'aide de ikvmc.exe pour qu'elles soient directement utilisables par une application .NET.
Par ailleurs, le programme ikvmstub.exe sera utilisé pour générer des stubs java (classes) à partir des librairies .NET et ainsi permettre la compilation d'un programme Java appelant une API .NET.
Et cela fonctionne ...
Voyons un peu si les promesses sont tenues. Pour cela, j'ai créé une simple application Java 6 utilisant quelques composants standards :
- Spring 2.0.2 avec un peu d'injection
- Hibernate 3 avec annotations JPA et lazy loading
- une base HSQL 2.0.1 embarquée.
En mode console, le programme liste simplement les entités des tables « Project » et « Resource » ; un projet étant relié à une ou plusieurs ressources par la table d'association « Project_resource ».
Vous trouverez les sources de cet exemple dans l'archive ikvm-smile-test.zip.
L' environnement d'exécution sur lequel nous allons faire le test est le suivant :
- MS Windows XP SP3
- MS .NET Framework 4
- IKVM 0.44.0.5
IKVM.NET ne fournit pas de compilateur Java car ce n'est pas sa vocation. Il faut donc compiler l'application avec votre compilateur habituel. Par exemple, celui du JDK Sun ou via l'IDE Eclipse.
Exécution dynamique du programme sur IKVM.NET
ikvm.exe -cp %CLASSPATH% fr.smile.ikvm.apptest.Application
L'application est alors exécutée comme si elle était lancée avec le JRE Sun :
Exécution statique par conversion en bytecode .NET
Tout d'abord, il faut convertir les archives Java en librairies .NET afin d'exposer les API java utilisées. Pour y parvenir, il faut gérer soit même les dépendances des librairies java, cette gestion pouvant s'avérer fastidieuse pour certains composants. Les dépendances non résolues sont signalées par des warnings.
Certaines d'entre-elles concernent des librairies du JDK qui seront liées à l'exécution via les DLL livrées avec IKVM.NET.
A noter : le compilateur peut convertir toutes les archives en une unique DLL ou créer une DLL par archive.
ikvmc.exe -target:library -out:bin\javalib.dll %JARS_LIST%
La DLL générée (javalib.dll) peut ensuite être utilisée dans une application .NET ou pour générer un exécutable en référençant les classes et les autres DLL nécessaires (notamment celles fournies par IKVM.NET).
Pour notre test, je rassemble donc les DLL indispensables dans un même répertoire pour ensuite créer le programme apptest.exe:
ikvmc.exe -reference:bin\*.dll -recurse:classes\*.* -out:bin\apptest.exe -main:fr.smile.ikvm.apptest.Application
Le programme est alors exécutable sur une machine virtuelle .NET. Sous Windows, il suffit de lancer l'exécutable directement en ligne de commande pour obtenir un rendu identique à celui d'un JRE Sun.
Utilisation des librairies de classes .NET dans une application Java
Pour rendre disponible les librairies .NET a un programme JAVA, il faut utiliser ikvmstub.exe. Cet utilitaire génère une archive JAVA (jar) pour chaque librairie .NET spécifiée.
L'archive résultante contient les interfaces et les types nécessaires au développement et à la compilation en environnement Java. Les classes et interfaces seront accessibles en Java dans le package cli.* en ayant préalablement ajouté l'archive jar au classpath du projet Java,
ikvmstub.exe \mono\lib\mscorlib.dll
Attention, l'application Java utilisant ces stubs doit être exécutée avec IKVM.NET. Elle ne peut pas fonctionner avec un JRE classique.
Premiers tests de performance
Pour se faire une première idée des performances de la machine virtuelle IKVM par rapport à celle de Sun (JRE 1,6.0_23), nous avons ajouté une boucle de trois itérations sur l'exemple utilisé jusqu'ici et tracé le temps d'exécution de chaque appel :
|
| Mode dynamique
| Mode statique
| JRE Sun
|
| Itération 1
| 2904 ms
| 571 ms
| 461 ms
|
| Itération 2
| 20 ms
| 20 ms
| 20 ms
|
| Itération 3
| 20 ms
| 20 ms
| 20 ms
|
Premier constat, le lancement en mode dynamique a pour effet de bord de ralentir gracieusement le lancement de la première itération. Ce délai peut sans aucun doute être imputé à la traduction du bytecode Java en CIL.
Cependant, en mode statique, IKVM se rapproche du JRE Sun mais, à priori, le chargement des classes (1er itération) demeure un peu plus performant avec le JRE standard.
Enfin, on s'aperçoit que les itérations suivantes restent constantes en temps et sont similaires au JRE Sun.
Sans être concluant, ce test montre que dans un contexte « basique » IKVM.NET tient la route.
Conclusion
Je n'ai pas rencontré de difficultés particulières pour faire ce test. En effet, IKVM.NET est très simple à mettre en place.
Même si l'outil est déjà opérationnel, notamment au sein du framework Mono, il y a encore du travail pour fournir une compatibilité totale avec les librairies standards (l'outil se base sur les projets OpenJDK et GNU Classpath). La liste des packages non implémentés du JDK et la liste "officielle" des librairies compatibles peuvent être consultées sur le site d'IKVM.NET. On apprend par exemple que l'IDE Eclipse, le serveur Jetty ou encore Apache FOP ont pu être lancés sur IKVM.NET et que des efforts importants ont été accomplis pour la compatibilité avec AWT et Swing !
Cependant, la version 0.44.0.5 publiée en septembre 2010 souffre encore de certaines incompatibilités à la lecture de la release notes, notamment en ce qui concerne les API graphiques et multimédias.
Dans un prochain billet, nous lancerons des tests plus poussés pour savoir si l'outil est assez stable et performant pour des applications en production.
Pour plus d'informations :
Commentaires