RMI sur IIOP

Qu'est-ce que RMI sur IIOP?

RMI sur IIOP (ci-après RMI-IIOP), développé conjointement par IBM et Sun, est une nouvelle version de RMI (Remote Method Invocation) pour IIOP (Internet Inter-ORB Protocol) qui combine les fonctionnalités de programmation facile de RMI avec l'interopérabilité de CORBA. Cette nouvelle version de RMI a été officiellement publiée en juin et rendue disponible gratuitement sur le site Web de Sun (voir la section Ressources ci-dessous pour savoir où vous pouvez la télécharger). L'implémentation de référence Sun s'exécute sous Windows 9x / NT et Solaris. Il s'agit d'une extension standard qui prend en charge à la fois JDK 1.1.6 et la plate-forme Java 2.

RMI et CORBA se sont développés indépendamment en tant que modèles de programmation d'objets distribués. RMI, une base des technologies EJB et Jini, a été introduit en tant que modèle de programmation basé sur Java et facile à utiliser pour les objets distribués. CORBA (Common Object Request Broker Architecture), défini par l'OMG (Object Management Group), est un modèle de programmation d'objets distribués bien connu qui prend en charge un certain nombre de langages. Le protocole IIOP connecte les produits CORBA de différents fournisseurs, garantissant leur interopérabilité. RMI-IIOP est, en un sens, un mariage entre RMI et CORBA.

Pour les besoins de cet article, nous supposons que vous êtes déjà familiarisé avec les bases de CORBA. Si vous avez besoin d'aide supplémentaire pour vous mettre à niveau, il y a un lien utile dans la section Ressources ci-dessous.

Avant RMI-IIOP

Regardez la figure 1 ci-dessous. L'espace au-dessus de la ligne horizontale centrale représente le domaine d'origine de RMI; la région inférieure représente le monde de CORBA et IIOP. Ces deux mondes séparés, s'étant développés indépendamment, n'ont pas été historiquement capables de communiquer entre eux. Par exemple, le protocole natif de RMI, JRMP (Java Remote Method Protocol), ne peut pas se connecter à d'autres protocoles.

Si le seul langage de programmation dont vous avez besoin dans un nouveau projet est Java, l'utilisation de RMI et JRMP - une combinaison appelée RMI (JRMP) pour le reste de cet article - a toujours été le meilleur choix. Contrairement à CORBA, qui nécessite l'utilisation du langage de définition d'interface (IDL) assez compliqué, RMI (JRMP) offre une programmation facile pour les amateurs de Java. CORBA, d'autre part, permet la programmation d'objets distribués sur différentes plates-formes et différents langages de programmation. Les développeurs ont besoin de la programmation d'objets distribués non seulement pour les nouveaux projets, mais aussi pour utiliser les ressources logicielles héritées. Bien entendu, les anciens logiciels sont dans la plupart des cas programmés dans des langages autres que Java; dans de telles situations, les développeurs ont besoin de CORBA, pas de RMI (JRMP).

Nous avons donc notre dilemme central: RMI (JRMP) a l'avantage d'une programmation facile, tandis que CORBA assure l'interopérabilité entre plusieurs langages de programmation sur différentes plates-formes. Malheureusement, il n’existe pas traditionnellement de moyen d’utiliser ces deux excellentes technologies. Ceci est illustré par le graphique de la figure 2, dans lequel un cercle représente une situation dans laquelle un client peut appeler un serveur, et un X représente un cas dans lequel ce n'est pas possible

Le meilleur des deux mondes

Il était difficile de choisir entre RMI (JRMP) et CORBA lors du démarrage d'un nouveau projet. Si vous avez sélectionné RMI (JRMP), vous avez une programmation facile, mais vous avez perdu l'interopérabilité dans plusieurs langues. Si vous avez sélectionné CORBA, vous bénéficiez de l'interopérabilité, mais vous êtes confronté à une tâche de programmation plus ardue. Les utilisateurs de RMI (JRMP) et de CORBA, fatigués de prendre cette décision, ont dit d'une seule voix: "Veuillez connecter les deux."

Dans la figure 3 ci-dessous, la section supérieure représente le modèle RMI (JRMP), la section médiane le modèle RMI-IIOP et la section inférieure le modèle CORBA. Une flèche représente une situation dans laquelle un client peut appeler un serveur. RMI-IIOP appartient au monde IIOP sous la ligne horizontale. Ce qui peut paraître étrange, ce sont les flèches diagonales qui traversent la frontière entre le monde JRMP et le monde IIOP, ce qui implique qu'un client RMI (JRMP) peut appeler un serveur RMI-IIOP, et vice versa. Il est naturel pour les lecteurs de penser que ces flèches diagonales sont fausses - après tout, différents protocoles ne peuvent jamais se parler, n'est-ce pas? Cependant, ces flèches sont en fait au bon endroit. RMI-IIOP prend en charge les protocoles JRMP et IIOP.

Un binaire de serveur (c'est-à-dire un fichier de classe) créé à l'aide des API RMI-IIOP peut être exporté en tant que JRMP ou IIOP. Vous n'avez pas besoin de réécrire son code source Java, ou de le recompiler lors du passage de JRMP à IIOP, ou vice versa. Il vous suffit de modifier les paramètres tels que les propriétés du système Java lors de son exécution. Vous pouvez également déterminer le protocole utilisé en le spécifiant dans le code source Java. La même flexibilité s'applique au code client RMI-IIOP.

Double exportation

Il y a un autre fait important à garder à l'esprit lors du choix entre les protocoles JRMP et IIOP. Lorsque vous exportez un objet RMI-IIOP sur votre serveur, vous n'avez pas forcément à choisir entre JRMP et IIOP. Si vous avez besoin d'un seul objet serveur pour prendre en charge les clients JRMP et IIOP, vous pouvez exporter votre objet RMI-IIOP vers JRMP et IIOP simultanément. Dans la terminologie RMI-IIOP, cela s'appelle double exportation.

Les flèches diagonales de la figure 3 sont possibles car les API RMI-IIOP prennent en charge les protocoles JRMP et IIOP. Cela signifie que, sans réécrire le code source d'un objet RMI (JRMP), il peut être appelé par un nouveau client RMI-IIOP. De même, sans réécrire le code source d'un client RMI (JRMP), vous pouvez remplacer un objet serveur RMI (JRMP) par un nouvel objet RMI-IIOP qu'un client CORBA peut également appeler. Ainsi, RMI-IIOP préserve l'investissement existant dans les binaires RMI (JRMP), car RMI-IIOP peut communiquer avec eux sans aucune modification du code source ni recompilation.

Cette interopérabilité avec RMI (JRMP) était l'un des principes de conception de RMI-IIOP. Les concepteurs de RMI-IIOP ont évité la tentation de remplacer CORBA et RMI par un troisième modèle de programmation, car cela n'aurait fait que confondre les programmeurs d'objets distribués et rendu la migration depuis RMI (JRMP) d'autant plus difficile.

Interopérabilité avec CORBA

Regardez à nouveau la figure 3. La section sous la ligne horizontale est le monde IIOP, où un client RMI-IIOP appelle un serveur CORBA et un client CORBA appelle un serveur RMI-IIOP. Par client RMI-IIOP, nous entendons un programme client qui a été écrit par un programmeur RMI qui ne sait rien de CORBA ou IDL. De même, un client CORBAest un programme client qui a été écrit par un programmeur CORBA ignorant RMI. La séparation de l'interface et de la mise en œuvre est une technique bien établie pour permettre aux programmeurs d'accéder à différentes ressources sans avoir besoin de savoir comment ces ressources sont mises en œuvre; si cette technique est suivie, les utilisateurs de RMI-IIOP et de CORBA peuvent utiliser les services de l'autre protocole, s'ils peuvent accéder à son interface. Un fichier d'interface Java RMI est l'interface avec les utilisateurs RMI-IIOP, tandis que IDL est l'interface avec les utilisateurs CORBA; l'interopérabilité entre RMI-IIOP et CORBA dans la figure 3 est obtenue en fournissant à chaque utilisateur son interface attendue, tout en gardant la mise en œuvre réelle cachée.

Le dernier détail à expliquer sur la figure 3 est la flèche en pointillé indiquant un client RMI-IIOP appelant un serveur CORBA. Pourquoi seulement cette flèche est-elle pointillée? Un client RMI-IIOP ne peut pas nécessairement accéder à tous les objets CORBA existants. La sémantique des objets CORBA définis en IDL est un sur-ensemble de celle des objets RMI-IIOP, c'est pourquoi l'IDL d'un objet CORBA existant ne peut pas toujours être mappé dans une interface Java RMI-IIOP. Ce n'est que lorsque la sémantique d'un objet CORBA spécifique correspond à celle de RMI-IIOP qu'un client RMI-IIOP peut appeler un objet CORBA. La flèche en pointillé indique une connexion qui est parfois - mais pas toujours - possible.

Cependant, l'incompatibilité ici ne doit pas être surestimée. Les restrictions indiquées par la flèche en pointillé s'appliquent uniquement lors du traitement d'objets CORBA existants. Supposons que vous conceviez un tout nouvel objet distribué avec une interface Java RMI-IIOP. Dans ce cas, vous pouvez générer automatiquement son IDL correspondant avec lermicoutil. À partir de ce fichier IDL, vous pouvez l'implémenter en tant qu'objet CORBA - en C ++, par exemple. Cet objet C ++ est un objet CORBA pur qui peut être appelé par un client CORBA et peut également être appelé par un client RMI-IIOP sans aucune limitation. Pour le client RMI-IIOP, cet objet CORBA C ++ apparaît comme un objet RMI-IIOP pur car il est défini par une interface Java RMI-IIOP. En bref, la différence entre un objet CORBA et un objet RMI-IIOP n'est qu'une question d'implémentation. De même, si un objet est implémenté dans RMI-IIOP, l'objet apparaît comme un objet CORBA pour un client CORBA car un client CORBA y accède via son IDL.

La figure 4 ci-dessous montre la matrice qui résume les flèches de la figure 3. Le cercle en pointillé signifie la même chose que la flèche en pointillé de la figure 3. La figure 4 montre que, si vous implémentez votre serveur dans RMI-IIOP, vous avez le choix le plus large de clients. De même, si vous implémentez votre client dans RMI-IIOP, vous pouvez parler à la plus grande gamme de serveurs, bien qu'il existe certaines restrictions dans le cas des objets CORBA existants, comme indiqué par le cercle en pointillé.

Politique de conception RMI-IIOP

Il y avait deux conditions préalables majeures qui ont façonné la conception du protocole RMI-IIOP: la sémantique RMI devait être laissée aussi intacte que possible, et CORBA devait être amélioré afin que la sémantique RMI puisse être implémentée à l'aide de l'infrastructure CORBA. C'était plus facile à dire qu'à faire. Si un troisième modèle de programmation était introduit, cela ne ferait que dérouter les programmeurs. Pour produire un mariage heureux entre RMI et CORBA, il était nécessaire de parvenir à un compromis entre les différents antécédents de ces partenaires de mariage - si les deux partenaires rejetaient tout compromis, le mariage n'aboutirait à rien. Heureusement, la communauté CORBA l'a reconnu et a accepté certains changements pour que le RMI-IIOP devienne une réalité.

Les deux modifications majeures acceptées par CORBA étaient les objets par valeur et les spécifications de mappage Java vers IDL . La première, déjà disponible pour les utilisateurs RMI sous la forme de sérialisation d'objets Java, est une spécification CORBA destinée à faire en sorte que d'autres langages implémentent une capacité similaire. Ce dernier est le mappage utilisé pour convertir les interfaces RMI Java en définitions CORBA IDL, et ne doit pas être confondu avec le mappage IDL-Java déjà défini dans CORBA 2.2. (Voir Ressources pour des liens vers ces deux nouvelles spécifications CORBA.)

OMG a déjà officiellement accepté les deux spécifications pour CORBA 2.3, mais les implémentations de CORBA devront rattraper cette nouvelle version avant que le nouveau mariage de CORBA et RMI décrit ici ne devienne une réalité généralisée. Par exemple, un compilateur IDL vers Java conforme à CORBA 2.3 est disponible auprès de Sun pour être utilisé en conjonction avec RMI-IIOP ORB (Object Request Broker), mais il s'agit actuellement d'une version à accès anticipé adaptée uniquement pour explorer l'interopérabilité de CORBA et RMI-IIOP, et non pour une utilisation en production. De plus, le compilateur IDL vers Java distribué par Sun pour une utilisation avec l'ORB IDL Java dans Java 1.2 n'est pas conforme à CORBA 2.3, il ne peut donc pas être utilisé pour tester l'interopérabilité avec RMI-IIOP. Cette situation sera résolue au cours des prochains mois à mesure que les fournisseurs de CORBA introduiront de nouvelles versions de leurs produits prenant en charge CORBA 2.3.Par exemple, la prochaine version de la plate-forme Java 2, Standard Edition comprendra à la fois RMI-IIOP et un compilateur IDL vers Java de qualité production prenant en charge CORBA 2.3.

Procédure de développement

La figure 5 ci-dessous montre les procédures de développement pour les serveurs et les clients RMI-IIOP. Vous remarquerez qu'ils sont quasiment les mêmes que ceux du RMI (JRMP). Tout comme dans RMI (JRMP), la définition d'un objet distribué est son interface Java RMI ( MyObject.javafigure 5). Une différence est le -iiopparamètre du rmiccompilateur. Cette option permet de rmicgénérer les stubs et les liens qui supportent le protocole IIOP. Sans cette -iiopoption, rmicgénère un stub et un squelette pour le protocole JRMP. Bien que la procédure de développement de RMI-IIOP soit proche de celle de RMI (JRMP), l'environnement d'exécution est différent en ce que la communication se fait via un ORB conforme CORBA 2.3, en utilisant IIOP pour la communication entre les serveurs et les clients.

Si vous envisagez de convertir du code RMI (JRMP) en RMI-IIOP, sachez qu'il existe des différences d'implémentation lors de l'exécution sur IIOP. Le garbage collection distribué n'est pas pris en charge par CORBA, qui utilise la destruction explicite et les références d'objet persistantes avec passivation et activation transparentes. Le registre RMI est remplacé par JNDI par le CosNamingfournisseur de services ou LDAP, et l'activation RMI est remplacée par l'adaptateur d'objet portable. Les références d'objets distants doivent être abaissées à l'aide d'une narrow()méthode de programmation au lieu d'une conversion directe en langage Java. D'autres sémantiques RMI, telles que la sérialisation d'objets, sont entièrement prises en charge sur IIOP.

Procédure d'interopérabilité CORBA

La figure 6 montre comment réaliser l'interopérabilité entre RMI-IIOP et CORBA. Pour simplifier notre discussion, considérons deux aspects d'une telle interopérabilité: un client CORBA utilisant un objet RMI-IIOP, représenté dans la section la plus à gauche de la figure 6, et un client RMI-IIOP utilisant un objet CORBA, représenté dans la section la plus à droite. Au centre de la figure se trouvent les processus partagés qui permettent aux deux formes d'interopérabilité de fonctionner.