Java et OpenVMS: Mythes et réalités

Jean-Yves Bourlès et Thierry Uso, le 7 mars 2006.

Cet article a pour objectif de discuter quelques mythes concernant l’utilisation de Java en environnement OpenVMS. Nous avons identifié trois mythes qui bien que contredits par les faits semblent particulièrement tenaces parmi les communautés OpenVMS et Java, à savoir :

:: :: Mythe n° 1: Java est lent

La lenteur d’exécution présumée des programmes en Java est souvent utilisée comme argument pour refuser le déploiement de logiciels Java en environnement OpenVMS.

Java n’est ni un langage compilé ni un langage interprété au sens habituel du terme; Java est un langage à machine virtuelle1. Le principe même de la machine virtuelle implique qu’un programme en Java soit en moyenne2 plus lent qu’un programme en langage compilé (C, Ada…) mais plus rapide qu’un programme en langage interprété (PHP, Perl…). C’est ce que confirment les résultats de microbenchmarks publiés sur le site du Computer Language Shootout Benchmarks [1], par exemple3 :


gcc

php


Ces résultats montrent également que les progrès réalisés dans la conception des machines virtuelles Java grâce à la technologie JIT (Just In Time) ont fortement réduit l’écart entre Java et les langages compilés. Dans la majorité des logiciels, la qualité de la programmation a désormais plus d’impact sur la vitesse d’exécution des programmes que le fait que ceux-ci soient écrits en Java ou en langage compilé.

Refuser le déploiement de logiciels Java en environnement OpenVMS peut se justifier parfois compte-tenu du surcoût en consommation mémoire induit par la machine virtuelle mais de plus en plus rarement à cause de la lenteur du langage lui-même.

:: :: Mythe n° 2: Java est inadapté à OpenVMS

Le démarrage de certaines applications Java est extrèmement lent sous OpenVMS. Par exemple, le démarrage du serveur d’applications Jetty [2,3] (avec le déploiement de l’application web javadoc à partir de son archive javadoc.war) sur un DS20 2×500 MHz 1Go de RAM prend 105 secondes sous OpenVMS 7.3-2 (Fast VM 1.4.2-3) contre 11 secondes sous Tru64 5.1B (Fast VM 1.4.2-4). Java est-il donc inadapté à OpenVMS ?

Afin de répondre à la question de l’inadaptation de Java à OpenVMS et d’identifier la cause de ces lenteurs, nous avons effectué plusieurs benchmarks sur la plateforme décrite ci-dessus.

Le benchmark n°1 repose sur un programme calculant des arbres binaires; ce programme est adapté du programme binarytrees trouvé sur le site du Computer Language Shootout Benchmarks [1]. Pour une profondeur de 18, les résultats sont les suivants :

Système Durée (secondes)
OpenVMS 37.4
Tru64 27.7

Le benchmark n°2 repose sur un programme lisant séquentiellement un fichier octet par octet à l’aide de la fonction InputStream( ). Pour des fichiers de 10, 100 et 1000 Ko, les résultats sont les suivants :

Système Fichier 10K (s) Fichier 100K (s) Fichier 1000K (s)
OpenVMS 5.0 34.1 332.7
Tru64 8.0 79.0 808.4

Le benchmark n°3 repose sur un programme lisant séquentiellement un fichier par bloc d’octets à l’aide de la fonction BufferedInputStream( ). Pour des fichiers de 10, 100 et 1000 Ko, les résultats sont les suivants :

Système Fichier 10K (s) Fichier 100K (s) Fichier 1000K (s)
OpenVMS 3.2 14.3 128.4
Tru64 0.1 0.7 6.9

Seul le benchmark n°3 montre des différences significatives entre OpenVMS et True64. En fait, la très mauvaise performance des entrées/sorties bufferisées sous OpenVMS par rapport à Tru64 s’explique par la lenteur du système de fichiers (RMS+ODS2/ODS5) et non pas par une mauvaise implémentation de la fonction BufferedInputStream( ). En effet, on constate des différences du même ordre avec le programme C unzip.

Dans le cas du démarrage de Jetty sous OpenVMS, le déploiement de l’application web javadoc est l’opération sollicitant le plus le système de fichiers et c’est aussi sans surprise la plus coûteuse. Sur le total de 105 secondes, 96 secondes sont utilisées pour décompresser l’archive javadoc.war en 42 directories et 549 fichiers.

Il existe des solutions pour pallier à la lenteur du système de fichiers d’OpenVMS bien qu’aucune d’elles ne soit applicable à l’ensemble des applications Java. Prenons à nouveau le cas de Jetty. Ce serveur d’applications déploie par défaut les applications web (archives war) dans une directory temporaire et y met également les bytecodes des servlets créés à la volée. La redirection de cette directory temporaire vers un RAMdisk diminue le temps de démarrage de 105 à 18 secondes et améliore notablement le temps de réponse des applications web. Une autre solution permettant également des gains significatifs consiste à n’utiliser que des applications web déployées à la main et avec des JSP “pré-compilées”.

En conclusion, il n’y a pas d’inadaptation de Java à OpenVMS. Simplement, les applications sollicitant fortement le système de fichiers seront toujours nettement plus lentes sous OpenVMS que sous Unix ou Windows, quelles soient développées en Java ou non. Le seul reproche que l’on puisse faire à Java est de créer très souvent un nombre important de fichiers applicatifs (un bytecode par classe Java).

:: :: Mythe n° 3: Java est totalement portable

Les concepteurs de Java ont conçu un environnement (langage à machine virtuelle et libraries standards) avec pour objectif le développement de programmes ayant une portabilité maximale. En effet, c’est en théorie à la machine virtuelle de traiter les spécificités de la plateforme cible (processeur et système d’exploitation) et non plus au développeur.

Est-ce à dire que Java est totalement portable comme le proclame le slogan de Sun Microsystems “Compile once, run everywhere” ?

Les nombreux tests et portages que nous avons réalisés en environnement OpenVMS montrent que les logiciels Java sont nettement plus portables que ceux écrits en langages compilés. Mais nous sommes cependant loin de la portabilité totale annoncée. La raison en est simple: Les concepteurs des librairies standard, les développeurs de machine virtuelle, les développeurs de programmes Java sont majoritairement des unixiens méconnaissant le plus souvent OpenVMS4.

Les problèmes de portabilité peuvent se classer en 2 grandes catégories :

Les problèmes de portabilité les plus fréquemment rencontrés par l’ingénieur système OpenVMS concernent les fichiers et DCL; ils sont décrits en détail dans le User Guide Java for OpenVMS [4] et peuvent se résoudre sans avoir à recompiler l’application.

Java ne prend en considération que les fichiers dont le format d’enregistrement est Stream-LF. Par conséquent, l’ingénieur système se doit de vérifier que l’ensemble des fichiers de l’application Java (bytecode, archive jar, fichier de données…) respecte bien ce format d’enregistrement.

La plupart des applications Java étant issues du monde Unix utilisent des noms de fichiers ne respectant pas la sémantique du système de fichiers ODS2. Dans ces cas, il est indispensable de passer en système de fichiers ODS5 et de paramètrer correctement le process exécutant l’application Java. Par exemple :

$ SET PROCESS/PARSE=EXTENDED
$ DEFINE DECC$EFS_CASE_PRESERVE ENABLE
$ DEFINE JAVA$FILENAME_CONTROLS 540227174

Les deux premières commandes forcent le process à respecter la casse et la dernière indique à la machine virtuelle quelles règles de mapping Unix/OpenVMS appliquer aux noms de fichiers. Le choix de la valeur de JAVA$FILENAME_CONTROLS peut s’avérer assez délicat.

Java ignore la notion de version de fichiers. Par conséquent, une bonne pratique consiste à passer l’ensemble des fichiers de l’application Java en VERSION_LIMIT=1. Il suffit pour cela d’appliquer la commande suivante sur le répertoire racine de l’application :

$ SET DIRECTORY/VERSION_LIMIT=1 disk:[app…]

Une fois réglé le problème des fichiers reste à traduire le(s) script(s) de démarrage de l’application en procédure(s) DCL.

Le lancement de l’application Java s’effectue à l’aide de la foreign command JAVA et peut prendre deux formes :

$ JAVA bytecode
$ JAVA -jar archive-jar

Le nom du bytecode correspond au nom de la classe Java dans le code source. Or, Java est sensible à la casse à la différence du DCL. Le nom du bytecode doit donc être mis entre guillemets pour prendre en compte cette différence de comportement, par exemple :

$ JAVA “MaClasse”

La commande JAVA accepte plusieurs paramètres optionnels dont le classpath qui indique la localisation des bytecodes. Ces paramètres peuvent parfois contribuer à ce que la commande finale ait une taille supérieure au maximum autorisé pour une commande DCL dans une procédure (8192 octets depuis OpenVMS 7.3-2). La commande JAVA doit alors être modifiée pour entrer sous ce maximum à l’aide des différents workarounds proposés sous OpenVMS (fichier d’options, fichier de classpath, noms logiques JAVA$ENABLE_ENVIRONMENT_EXPANSION et JAVA$CLASSPATH…).

Les problèmes de portabilité les plus fréquemment rencontrés par le développeur Java concernent la gestion des processes et ne peuvent se résoudre qu’après modification des sources et recompilation de l’application. Nous allons les illustrer à travers le cas de iReport [5], outil de reporting inspiré d’Access et de
Crystal Report.

iReport fait appel à un programme externe pour afficher le rapport au format PDF ou HTML. Ce programme (par exemple, XPDF ou Mozilla) s’exécute dans un process détaché. Sous OpenVMS, l’affichage du rapport fonctionne correctement en local mais échoue en déporté. La raison en est simple : Les paramètres X11 (display node, display transport) sont des noms logiques qui ne sont pas hérités du process père (iReport) par le process fils (affichage). Nous avons donc dû modifier le fichier source IReportCompiler.java de manière à ce que le process iReport communique les paramètres X11 au process chargé de l’affichage (pour plus de détails, voir [6]).

L’utilisation du nom logique JAVA$EXEC_TRACE est souvent d’une grande aide pour diagnostiquer les problèmes de portabilité liés à la gestion des processes. Lorsque ce nom logique est défini à la valeur “true” dans la table LNM$JOB, la machine virtuelle trace l’appel posix execv() ainsi que sa liste d’arguments.

Notes

1 la compilation du code source conduit à un bytecode par classe Java; les bytecodes sont indépendant de la plateforme (processeur et système d’exploitation); la machine virtuelle interprète les bytecodes en les traduisant à la volée en instructions machine

2 toutes choses étant égales par ailleurs (qualité des compilateurs, machines virtuelles, interpréteurs et qualité de programmation des benchmarks)

3 AMD Sempron, Debian unstable Kernel 2.6.8-1-k7, Java Hotspot 1.4.2_05-b04, C gcc 4.0.3, PHP 5.1.2-1

4 les machines virtuelles FastVM (Alpha) et Hotspot (Itanium) utilisées sous OpenVMS sont des portages issus respectivement de Tru64 et HP-UX; La plupart des applications Java sont d’abord développées sur et pour une plateforme Unix

Références

[1] http://shootout.alioth.debian.org/
[2] http://jetty.mortbay.org/jetty/index.html
[3] http://vmsfree.ouvaton.org/free/index.php?s=jetty
[4] http://h18012.www1.hp.com/java/documentation/
[5] http://ireport.sourceforge.net/
[6] http://www.bourles.fr/Portage.html

aleft Quel CMS choisir en environnement OpenVMS ? A propos des Technical Update Days 2006 aright