Archive for octobre, 2005

RMI et les ports

Classiquement, pour développer un serveur RMI, nous devons :

  • Définir une interface avec l’ensemble des méthodes « remotes » (cette interface étendra java.rmi.Remote).
  • Implémenter cette interface dans une class étendant java.rmi.server.UnicastRemoteObject.
  • Enregistrer le serveur auprès d’un registre RMI (il convient d’avoir précédemment lancé la commande rmiregistry).

Au niveau du code côté client, nous devons récupérer une référence de cet objet (son stub) à l’aide de la méthode Naming.lookup(name) qui interroge le service rmiregistry.

Dans le contexte d’un réseau local, cela fonctionne sans que l’on ait vraiment besoin de se préoccuper des ports de communication. Maintenant, si l’on souhaite offrir l’accès à notre serveur aux utilisateurs se trouvant en dehors du LAN, nous devons maîtriser les ports TCP/IP ouverts par notre application pour configurer notre pare-feux et les redirections NAT.

Grâce à la commande netstat nous constatons que rmiregistry écoute le port 1099 et que notre processus java un autre port qui varie à chaque lancement. Le port 1099 est le port par défaut du registre RMI. Il est toutefois possible d’en spécifier un autre en paramètre de la commande rmiregistry. Le second port correspond au port de notre propre service. Toujours grâce à la commande netstat nous remarquons que notre client se connecte une première fois au rmiregistry (sur le port 1099) puis ne dialogue plus qu’à notre application au travers du second port.

Tout ceci ne nous arrange pas, comment définir des règles sur le « router/firewall » si le second port change à chaque redémarrage ?
Un petit tour dans la javadoc nous apprend que le constructeur de la class UnicastRemoteObject admet pour paramètre le port d’écoute. Parfait, nous ajoutons donc super(port) dans le constructeur de notre serveur.

Cependant, nous ne pouvons choisir 1099 car ce port est déjà utilisé par le processus rmiregistry. Heureusement, il y a une solution, nous n’exécuterons plus la commande rmiregistry ; nous créerons directement le registre RMI dans la JVM de notre serveur au moyen de l’instruction LocateRegistry.createRegistry(pPort).

Ainsi nous arrivons à nos fins, notre application ne monopolise qu’un unique port connu et paramétrable.