Photon – 4.8 (Juin 2018), inclu des fonctionnalités de configuration des projets Java pour prendre en charge la notion de module introduite en Java 9.
1. Un projet de démonstration
Dans eclipse créer un nouveau projet Java: Sélectionner le menu : File / New / Project.Sélectionner Java Project. Ensuite, l’utilisation du bouton Next permet d’accéder à la fenêtre de configuration du projet. Saisir le nom du projet et sélectionner la version 9 de Java au minimum comme cible d’exécution. Utiliser le bouton Finish pour lancer la création du projet. A ce stade, une fenêtre s’affiche pour suggérer la création du fichier descripteur de module module-info.java du projet: Si on aurait choisit Java 1.8 ou inférieur comme version cible d’exécution, cette fenêtre ne s’afficherait pas. Pour le besoin de démonstration, on va décliner cette offre et continuer avec un projet compatible Java 1.8 et inférieur. On clique donc sur Don’t Create et Eclipse génère le projet comme demandé. Sélectionner le nouveau projet dans l’explorateur de package (volet de gauche) et faire un click droit de la souris puis accéder au menu de création d’une nouvelle classe: New / Class. Ce menu mène à la fenêtre de cration d’une nouvelle classe: Eclipse ajoute le fichier de la nouvelle classe qu’il convient de compléter comme suit (ligne à rajouter): A ce statde la création du projet de démonstration est terminée. On peut l’exécuter pour afficher le message de test. On se propose dans la suite de transformer ce projet en module Java.2. Le fichier descripteur de module
Si le projet Eclipse est un module Java, il faudra qu’il inclut le fichier descripteur de module module-info.java dans la racine du projet (voir l’article à ce sujet). Une fonctionnalité Eclipse permet de créer ce fichier. Click droit sur le projet, ensuite Configure / Create module-info.java. L’utilisation de ce menu permet d’accéder à la même fenêtre de création de module rencontrée à la première génération du projet. Dans cette fenêtre saisir net.meddeb.eclipsemoduletuto comme nom de module et valider avec le bouton Create. Eclipse génère, alors, le fichier descripteur de module avec le nom saisi. Ce fichier généré exporte l’unique package de notre projet. On constate que cette transformation en module ne change rien à cette application et elle continue à s’exécutable de la même manière. Pour le besoin de démonstration, on va faire évoluer cette application de manière qu’elle affiche un autre message en passant par l’API de logging de Java. Modifier le fichier de la classe Mainclass pour que son contenu devienne (copier / coller):package net.meddeb.eclipsemoduletuto; import java.util.logging.Logger; public class Mainclass { public static void main(String[] args) { System.out.println("Hello eclipse Java !"); Mainclass m = new Mainclass(); m.afficherMessage(); } public void afficherMessage() { final Logger logger=Logger.getLogger(this.getClass().getPackage().getName()); logger.info("Hello eclipse Java module !"); } }Après cette modification la compilation de l’application échoue. La raison est que le package java.util.logging utilisé par cette modification n’est pas accessible du fait de la modularisation du code. La solution est de déclarer implicitement le besoin de notre application/module à ce package. Pour le faire, modifier le fichier descripteur de module de manière que son contenu devienne:
module net.meddeb.eclipsemoduletuto { exports net.meddeb.eclipsemoduletuto; requires java.logging; }L’explication est que le code supplémentaire utilisé se trouve dans le package java.util.logging, exporté par le module du JRE java.logging. Pour pouvoir l’utiliser il faudra inclure ce module dans une clause requires du fichier descripteur. Une question légitime se pose dans ces conditions: pourquoi l’application se compilait et s’exécutait sans problème avant cette modification, alors qu’aucune clause requires n’a été utilisée ? La réponse à cette question est que le code de définition de la classe et le code de System.out utilisé pour l’affichage du message se trouvent dans le module de base du JRE java.base. C’est l’unique module qui est référencé implicitement et n’a pas besoin de figurer explicitement dans une clause requires du module qui l’utilise. D’un autre côté, pour que la compilation et l’exécution donctionnent, l’emplacement des fichiers des modules utilisés doit figuer dans le chemin de recherche des modules: le Modulepath.