Les trois types de portabilité de Java

Java a suscité beaucoup d'enthousiasme dans la communauté de programmation car il promet des applications et des applets portables . En fait, Java offre trois types distincts de portabilité: la portabilité du code source, la portabilité de l'architecture du processeur et la portabilité du système d'exploitation / interface graphique. Le fait qu'il existe trois types distincts de portabilité est essentiel, car un seul de ces types constitue une menace pour Microsoft. On peut s'attendre à ce que Microsoft sape ce type de portabilité tout en adoptant les deux autres - tout en prétendant prendre en charge Java. Comprendre les trois types de portabilité et la manière dont ils fonctionnent ensemble est essentiel pour comprendre la menace pesant sur Microsoft et les réponses possibles de Microsoft.

Avant de passer aux détails de chacun de ces trois types de portabilité, examinons quelques termes fondamentaux.

Définition de certains termes

Les termes suivants sont utilisés dans cet article:

Endianisme
L'endianisme fait référence à l'ordre de stockage des octets dans une quantité multi-octets dans un processeur donné. Par exemple, le court 256 non signé (décimal) nécessite deux octets de stockage: un 0x01 et 0x00. Ces deux octets peuvent être stockés dans l'ordre: 0x01, 0x00ou 0x00, 0x01. L'endianisme détermine l'ordre dans lequel les deux octets sont stockés. Pour des raisons pratiques, l'endianisme n'a généralement d'importance que lorsque des processeurs d'endianisme différent doivent partager des données.
Java
Java regroupe plusieurs technologies différentes: le langage de programmation Java, la machine virtuelle Java (JVM) et les bibliothèques de classes associées au langage. Cet article traite de tous ces aspects.
Machine virtuelle Java (JVM)

La JVM est un processeur imaginaire pour lequel la plupart des compilateurs Java émettent du code. La prise en charge de ce processeur imaginaire est ce qui permet aux programmes Java de s'exécuter sans être recompilés sur différents processeurs. Rien dans le langage de programmation Java n'exige que le code source Java soit compilé en code pour la JVM plutôt qu'en code objet natif.

En fait, Asymetrix et Microsoft ont annoncé des compilateurs Java qui émettent des applications Microsoft Windows natives. (Consultez la section Ressources de cet article pour plus d'informations.)

Code J
J-code est la sortie émise par la plupart des compilateurs Java dans les fichiers de classe. Le code J peut être considéré comme un code objet pour la machine virtuelle Java.
Portabilité
La portabilité fait référence à la possibilité d'exécuter un programme sur différentes machines. L'exécution d'un programme donné sur différentes machines peut nécessiter différentes quantités de travail (par exemple, aucun travail du tout, recompilation ou apporter de petites modifications au code source). Lorsque les gens se réfèrent aux applications et applets Java comme portables, cela signifie généralement que les applications et les applets s'exécutent sur différents types de machines sans changement (comme une recompilation ou des ajustements au code source).

Maintenant que nous avons couvert certains termes essentiels, nous allons expliquer chacun des trois types de portabilité Java.

Java en tant que langage: portabilité du code source

En tant que langage de programmation, Java fournit la forme la plus simple et la plus familière de portabilité: la portabilité du code source. Un programme Java donné doitproduisent des résultats identiques quel que soit le processeur sous-jacent, le système d'exploitation ou le compilateur Java. Cette idée n'est pas nouvelle; des langages tels que C et C ++ ont fourni la possibilité d'atteindre ce niveau de portabilité depuis de nombreuses années. Cependant, C et C ++ offrent également de nombreuses possibilités de créer du code non portable. À moins que les programmes écrits en C et C ++ ne soient conçus pour être portables dès le début, la possibilité de passer à des machines différentes est plus théorique que pratique. C et C ++ laissent des détails non définis tels que la taille et l'endianisme des types de données atomiques, le comportement des mathématiques à virgule flottante, la valeur des variables non initialisées et le comportement lors de l'accès à la mémoire libérée.

En bref, bien que la syntaxe de C et C ++ soit bien définie, la sémantique ne le est pas. Ce flou sémantique permet à un seul bloc de code source C ou C ++ de se compiler en programmes qui donnent des résultats différents lorsqu'ils sont exécutés sur différents processeurs, systèmes d'exploitation, compilateurs, et même sur une seule combinaison compilateur / processeur / système d'exploitation, en fonction de divers paramètres du compilateur. (Voir la barre latérale Syntaxe versus sémantique pour une discussion des différences entre la sémantique et la syntaxe.)

Java est différent. Java fournit une sémantique beaucoup plus rigoureuse et laisse moins de soin à l'implémenteur. Contrairement à C et C ++, Java a défini des tailles et un endianisme pour les types atomiques, ainsi qu'un comportement en virgule flottante défini.

De plus, Java définit plus de comportement que C et C ++. En Java, la mémoire n'est pas libérée tant qu'elle n'est plus accessible, et le langage ne contient aucune variable non initialisée. Toutes ces fonctionnalités permettent de réduire la variation du comportement d'un programme Java d'une plateforme à l'autre et de l'implémentation à l'implémentation. Même sans JVM, les programmes écrits en langage Java peuvent être portés (après recompilation) sur différents processeurs et systèmes d'exploitation bien mieux que les programmes C ou C ++ équivalents.

Malheureusement, les fonctionnalités qui rendent Java si portable ont un inconvénient. Java suppose une machine 32 bits avec 8 octets et des calculs à virgule flottante IEEE754. Les machines qui ne correspondent pas à ce modèle, y compris les microcontrôleurs 8 bits et les supercalculateurs Cray, ne peuvent pas exécuter Java efficacement. Pour cette raison, nous devrions nous attendre à ce que C et C ++ soient utilisés sur plus de plates-formes que le langage Java. Nous devrions également nous attendre à ce que les programmes Java soient portés plus facilement que C ou C ++ entre les plates-formes qui prennent en charge les deux.

Java en tant que machine virtuelle: portabilité du processeur

La plupart des compilateurs produisent du code objet qui s'exécute sur une famille de processeurs (par exemple, la famille Intel x86). Même les compilateurs qui produisent du code objet pour plusieurs familles de CPU différentes (par exemple, x86, MIPS et SPARC) ne produisent du code objet que pour un type de CPU à la fois; si vous avez besoin de code objet pour trois familles différentes de CPU, vous devez compiler votre code source trois fois.

Les compilateurs Java actuels sont différents. Au lieu de produire une sortie pour chaque famille de CPU différente sur laquelle le programme Java est destiné à s'exécuter, les compilateurs Java actuels produisent du code objet (appelé code J) pour un CPU qui n'existe pas encore.

(Sun a annoncé un processeur qui exécutera directement le code J, mais indique que les premiers échantillons de puces Java n'apparaîtront pas avant le second semestre de cette année; la production complète de ces puces commencera l'année prochaine. Technologie de base picoJavaI de Sun Microelectronics sera au cœur de la gamme de processeurs microJava de Sun, qui ciblera les ordinateurs du réseau. Les titulaires de licence tels que LG Semicon, Toshiba Corp. et Rockwell Collins Inc. prévoient également de produire des puces Java basées sur le cœur picoJavaI.)

Pour chaque CPU réel sur lequel les programmes Java sont destinés à s'exécuter, un interpréteur Java, ou machine virtuelle, "exécute" le J-code. Ce processeur inexistant permet au même code objet de s'exécuter sur n'importe quel processeur pour lequel un interpréteur Java existe.

Produire une sortie pour un processeur imaginaire n'est pas nouveau avec Java: les compilateurs Pascal UCSD (Université de Californie à San Diego) ont produit du code P il y a des années; Limbo, un nouveau langage de programmation en cours de développement chez Lucent Technologies, produit du code objet pour un processeur imaginaire; et Perl crée une représentation de programme intermédiaire et exécute cette représentation intermédiaire au lieu de créer du code exécutable natif. La JVM Internet-savvy se distingue de ces autres implémentations de CPU virtuels en étant intentionnellement conçue pour permettre la génération de code sans virus et dont la sécurité est prouvée. Avant Internet, il n'était pas nécessaire de disposer de machines virtuelles pour prouver que les programmes étaient sûrs et exempts de virus. Cette fonction de sécurité, combinée à une bien meilleure compréhension de la manière d'exécuter rapidement des programmes pour des processeurs imaginaires, a conduit à desacceptation généralisée de la JVM. Aujourd'hui, la plupart des principaux systèmes d'exploitation, notamment OS / 2, MacOS, Windows 95 / NT et Novell Netware, ont, ou devraient avoir, une prise en charge intégrée des programmes J-code.

La JVM, étant essentiellement un processeur imaginaire, est indépendante du langage de code source. Le langage Java peut produire du J-code. Mais Ada95 aussi. En fait, les interpréteurs hébergés en J-code ont été écrits pour plusieurs langages, notamment BASIC, Forth, Lisp et Scheme, et il est presque certain que les implémentations d'autres langages émettront du J-code à l'avenir. Une fois que le code source a été converti en code J, l'interpréteur Java ne peut pas dire quel langage de programmation a créé le code J qu'il exécute. Le résultat: la portabilité entre les différents processeurs.

L'avantage de compiler des programmes (dans n'importe quel langage) en J-code est que le même code s'exécute sur différentes familles de processeurs. L'inconvénient est que le code J ne fonctionne pas aussi vite que le code natif. Pour la plupart des applications, cela n'aura pas d'importance, mais pour le plus haut des programmes haut de gamme - ceux qui ont besoin du dernier pour cent du processeur - le coût de performance du code J ne sera pas acceptable.

Java en tant qu'OS virtuel et interface graphique: portabilité du système d'exploitation

La plupart des programmes Microsoft Windows écrits en C ou C ++ ne se portent pas facilement vers les environnements Macintosh ou Unix, même après recompilation. Même si les programmeurs prennent des précautions supplémentaires pour traiter les faiblesses sémantiques en C ou C ++, le portage est difficile. Cette difficulté se produit même lorsque le port vers le système d'exploitation non Windows a lieu sans changer de CPU. Pourquoi la difficulté?

Après avoir éliminé les problèmes sémantiques en C et C ++ et les problèmes de portage du processeur, les programmeurs doivent encore gérer les différents systèmes d'exploitation et les différents appels d'API GUI.

Les programmes Windows effectuent des appels au système d'exploitation très différents des programmes Macintosh et Unix. Ces appels sont essentiels pour écrire des programmes non triviaux, donc tant que ce problème de portabilité n'est pas résolu, le portage restera difficile.

Java résout ce problème en fournissant un ensemble de fonctions de la bibliothèque (contenues dans les bibliothèques Java fournis tels que awt, utilet lang) qui parlent à un OS imaginaire et GUI imaginaire. Tout comme la JVM présente un CPU virtuel, les bibliothèques Java présentent un OS / GUI virtuel. Chaque implémentation Java fournit des bibliothèques implémentant cet OS / GUI virtuel. Les programmes Java qui utilisent ces bibliothèques pour fournir assez facilement le port des fonctionnalités du système d'exploitation et de l'interface graphique.

Utiliser une bibliothèque de portabilité au lieu d'appels natifs du système d'exploitation / interface graphique n'est pas une nouvelle idée. Des produits tels que Galaxy de Visix Software et Zinc de Protools Software offrent cette capacité pour C et C ++. Une autre approche, non suivie par Java, consiste à choisir un seul OS / GUI comme maître et à fournir des bibliothèques de wrapper prenant en charge ce SE / GUI maître sur toutes les machines sur lesquelles vous souhaitez porter. Le problème avec l'approche OS / GUI principale est que les applications portées semblent souvent étrangères sur les autres machines. Les utilisateurs de Macintosh, par exemple, se sont plaints d'une version récente de Microsoft Word pour Macintosh parce qu'elle ressemblait et se comportait comme un programme Windows, et non comme un programme Macintosh. Malheureusement, l'approche adoptée par Java pose également des problèmes.

Java a fourni une fonctionnalité de moindre dénominateur commun dans ses bibliothèques OS / GUI. Les fonctionnalités disponibles sur un seul système d'exploitation / interface graphique, telles que les boîtes de dialogue à onglets, ont été omises. L'avantage de cette approche est que le mappage de la fonctionnalité commune au système d'exploitation / interface graphique natif est assez facile et, avec précaution, peut fournir des applications qui fonctionnent comme prévu sur la plupart des systèmes d'exploitation / interfaces graphiques. L'inconvénient est qu'il y aura des fonctionnalités disponibles pour les applications en mode natif qui ne sont pas disponibles pour les applications Java. Parfois, les développeurs pourront contourner ce problème en étendant l'AWT; d'autres fois, ils ne le feront pas. Dans les cas où les fonctionnalités souhaitées sont inaccessibles avec des solutions de contournement, les développeurs choisiront probablement d'écrire du code non portable.

Qui se soucie de la portabilité?

Trois principaux groupes se soucient de la portabilité: les développeurs, les utilisateurs finaux et les services SIG.

Développeurs: les opportunités et les menaces occupent une place importante

Les développeurs ont tout intérêt à créer des logiciels portables. En revanche, les logiciels portables leur permettent de prendre en charge plus de plates-formes, ce qui conduit à une plus grande base de clients potentiels. Cependant, la même portabilité qui permet aux développeurs de cibler de nouveaux marchés permet également aux concurrents de cibler leur marché.

En un mot, la portabilité Java éloigne le marché des logiciels d'application des marchés séparés basés sur les différents systèmes d'exploitation et interfaces graphiques et vers un seul grand marché. Sur le marché actuel des logiciels, par exemple, Microsoft est une force avec laquelle il faut compter sur les marchés des logiciels d'application Windows et Macintosh, mais n'a pratiquement aucune présence sur les marchés OS / 2 et Unix. Ce partitionnement permet aux entreprises des marchés OS / 2 et Unix de ne pas considérer Microsoft comme un concurrent. Java facilite la concurrence pour ces entreprises sur le marché Windows, mais permet également à Microsoft d'entrer plus facilement sur les marchés OS / 2 et Unix.

Utilisateurs: les bénéficiaires indirects de la portabilité

Les utilisateurs ne se soucient pas de la portabilité en soi. Si la portabilité rend leur vie plus facile et plus agréable, alors ils sont tous pour; sinon, ils ne le sont pas. La portabilité a des effets positifs pour les utilisateurs, mais ceux-ci sont quelque peu indirects. Les effets positifs: