Du nouveau pour le projet Code Recommenders

Un petit peu de promotion pour le projet sur lequel je travaille quelque peu aux cotés de Marcel Bruch. Sur le blog officiel sont présentées les nouveautés : refactoring de l'ordonnancement des méthodes et auto-completion "intelligente" (fonctionnalité à laquelle j'ai contribué).

N'hésitez pas à commenter, apporter des idées, dénigrer, louer... Enfin donner votre avis!


Fichier(s) joint(s) :

Intégrer Mantis à Eclipse grâce à Mylyn

Eclipse devient un environnement de développement -de plus en plus- intégré. Il est clair que depuis longtemps maintenant, le but de la fondation est de créer un outil capable d'être utilisé dans toutes les étapes de l'ALM (Application Lifecycle Management). Exemples :

  • Modeling : UML avec Papyrus
  • Configuration Management : SVN avec Subclipse
  • Build management : Maven avec m2eclipse
  • Software Testing : Test unitaires avec le support de JUnit et fonctionnels avec Jubula/SWTBot
  • Release Management : Maven avec m2eclipse
  • Workflow : implémentations avec MWE

Mais cette liste peut encore être complétée par la prise en compte de "Change Management" et "Issue Management" grâce à Mylyn. En effet, ce projet a pour but d'ajouter à Eclipse la capacité de gérer de manière plus approfondie les changements réalisés sur un projet, en s'interfaçant avec les outils les plus courants dans ce domaine : Jira, Mantis... Il est intégré de base dans la majorité des distributions.

Cet article a donc pour but de présenter Mylyn et tente de montrer comment être plus efficace avec sa nouvelle manière de gérer les tickets Mantis.

Tout d'abord, à quoi sert Mylyn? Sa vocation principale est d'apporter une nouvelle façon de traiter les modifications : au sein de l'IDE, un ticket est représenté sous la forme d'une tâche, planifiable dans le temps (l'avancement du travail effectué est donc matérialisé) mais aussi contextualisable (il est possible de lier directement des modifications de code à un ticket). L'IDE est en lien direct et permanent avec le serveur Mantis afin de récupérer toutes les anomalies saisies et de les mettre à jour sans avoir à ouvrir un navigateur. La présentation complète des fonctionnalités est disponible sur cette page.

Voyons donc, avec un exemple, comment traiter un ticket uniquement depuis Eclipse.

Tout commence par la configuration de l'accès au serveur. Dans la vue "Task Repositories", il faut créer un nouveau serveur :

Mantis fournit par défaut un webservice SOAP utilisable pour interagir avec ses données, généralement à l'adresse "http:///api/soap/mantisconnect.php". Il faut donc indiquer à Mylyn l'adresse de ce webservice pour se connecter :

Le serveur apparaît alors dans la vue. Pendant la configuration, Mylyn a récupéré la liste des projets et des utilisateurs créés dans Mantis. Il est donc possible de récupérer les tickets en indiquant la requête à utiliser, autrement dit le filtre enregistré sur le serveur. Par exemple, j'ai créé un filtre dans Mantis pour ne voir que les tickets qui me sont affectés, appelé "All Mine" :

Dans Eclipse, il faut indiquer la requête à utiliser pour télécharger les tickets, avec la fonction "New Query" :

Après avoir sélectionné le projet, il est possible de choisir le filtre "All Mine" :

Pour finaliser la récupération des tâches, il faut se rendre dans la vue "Task List" et synchroniser avec le serveur :

On peut donc voir les tickets rapatriés sous forme de tâches, comprenant l'ensemble des informations saisie sous Mantis. A partir de ce moment, la tâche est consultable hors-ligne et modifiable à volonté. Il est par la suite possible de mettre à jour Mantis avec le bouton "Submit" dans l'éditeur :

Voyons donc comment traiter le bug illustré ici et contextualiser dans Mantis la tâche avec le code mis en jeu au moment du commit. Tout d'abord, il possible de planifier la réalisation dans le temps afin de connaitre le travail effectué dans la journée. Pour ceci, il est possible de définir la date attendue et le temps nécessaire estimé pour la réalisation :

La progression sera ainsi visible en survolant la catégorie regroupant les tâches :

Afin de lier le contexte à la tâche, il faut d'abord l'activer, autrement dit indiquer qu'elle est la tâche courante (point gris à gauche de la tâche sur l'image plus haut). Dès lors, de nouvelles actions sont disponibles comme l'accès direct au code depuis la description de la tâche, grâce à la trace de l'exception :

Ensuite, une fois la correction effectuée, c'est lors de la synchronisation avec le serveur SVN (avant le commit) que l'on indique le contexte (série de modifications) de la tâche courante :

Ainsi, dans l'éditeur de la tâche, sous l'onglet "Context", apparaissent désormais les classes mises en jeu :

Revenons maintenant au commit. Mylyn ajoute par défaut dans le commentaire la référence au Mantis de la tâche. Il est vivement conseillé de conserver au moins ces informations dans le commentaire, nous verrons par la suite pourquoi :

Il faut maintenant mettre à jour le ticket Mantis pour indiquer sa résolution. Pour cela, il suffit de modifier les champs de la section "Action" dans l'éditeur de la tâche et soumettre au serveur :

La mise à jour terminée, la progression du travail est actualisée et le bug est maintenant clos dans Mantis :

Un fichier ZIP a été lié, contenant les informations nécessaires à Mylyn pour récupérer le contexte de la tâche dans l'IDE si nécessaire. A propos de contexte, qu'est devenu le commentaire si important lors du commit? Pour le savoir, il faut éditer la classe qui a été modifiée puis afficher les annotations serveur grâce à "Team"->"Show annotation" :

Affichées en mod "diff", il est possible de voir le commentaire spécifié lors du commit qui a modifié la ligne en question, et donc de retrouver directement le lien vers le ticket Mantis traité :

Comme on peut le voir, le traitement des bugs devient donc bien plus pratique et pragmatique avec Mylyn : le déroulement des corrections se fait entièrement depuis l'IDE, sans avoir à manipuler un navigateur externe (il est même possible de pousser le vice l'outil jusqu'à ouvrir les tickets Mantis correspondants aux tâches dans le navigateur intégré d'Eclipse...).

Il existe encore bien d'autres possibilités d'utilisation, mais j'espère que cette présentation aura éveillé les curiosités!

Sources :


Fichier(s) joint(s) :



Précisions sur le support de Java 7 sous Eclipse

Voici quelques nouvelles pistes pour les plus pressés de découvrir et tester les nouveautés du langage :

La dernière version de l'IDE, Indigo (3.7), ne gérant pas encore le compileur de Java 7, il faudra attendre le mois de septembre et les builds d'intégration de la version 3.7.1 pour trouver les premiers supports, officiellement intégrés dans la version suivante 3.8M1 (nommée Juno, téléchargeable ici).

Il est d'ores et déjà possible d'avoir un aperçu de l'intégration du nouveau compileur, grâce à quelques images dévoilées pour la version 3.8 de JDT et à cette vidéo de démonstration "live".

On your marks... ready... compile!


Fichier(s) joint(s) :



Configuration en temps réel grâce à Java NIO

Oracle ayant récemment publié la version 7 du JRE, j'ai décidé de commencer à tester quelque peu les nouveautés disponibles.

Dans cet article, je vais présenter les possibilités offertes par la nouvelle gestion du système de fichiers, avec java.nio.file.WatchService, qui permet de mettre en place un outil de "surveillance" des ressources.

Imaginons donc une fonctionnalité de mise à jour en temps réel de la configuration d'une application lors de la modification d'un fichier properties.

Voici le code mis en place :

package com.developpef;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardWatchEventKinds;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.List;
import java.util.Properties;

public class PropertiesSpreader {

	private static final String basePath = "C:\\java\\ides\\eclipse-jee-helios-SR2\\workspace\\Test\\resources";
	private static Path propDir;

	public static void main(String[] args) {
		try {
			loadProperties();

			FileSystem fs = FileSystems.getDefault();
			final WatchService watcher = fs.newWatchService();
			propDir = fs.getPath(basePath);
			propDir.register(watcher, StandardWatchEventKinds.ENTRY_MODIFY);

			Thread t = new Thread(new Runnable() {
				@Override
				public void run() {
					watch(watcher);
				}
			});
			t.start();

			System.out.println("Le watcher a été démarré...");
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private static void watch(WatchService watcher) {
		WatchKey key = null;
		do {
			try {
				key = watcher.take();
				List<WatchEvent<?>> events = key.pollEvents();
				for (WatchEvent<?> event : events) {
					if (event.kind() == StandardWatchEventKinds.ENTRY_MODIFY) {
						Path propFile = (Path) event.context();
						if (propFile.endsWith("test.properties")) {

							BasicFileAttributes bfa = Files.readAttributes(
									propDir.resolve(propFile),
									BasicFileAttributes.class);
							System.out
									.println("\n** Fichier propriétés modifié! Rechargement... (modifications du "
											+ bfa.lastModifiedTime() + ")**");
							loadProperties();
						}
					}
				}
			} catch (InterruptedException|IOException e) {
				e.printStackTrace();
			}
		} while (key.reset());
	}

	private static void loadProperties() throws IOException {
		InputStream stream = new FileInputStream(new File(basePath
				+ "\\test.properties"));
		Properties props = new Properties();
		props.load(stream);
		stream.close();
		System.out.println("Titre de l'application : "
				+ props.getProperty("App.title"));
	}

}

L'intérêt de cette implémentation est de gérer la configuration dans un thread autonome (comme un daemon) qui actualisera les propriétés de l'application.

La gestion du système de fichiers a été "allégée", notamment grâce à un nouveau "super objet" java.nio.file.FileSystem qui facilite la manipulation des ressources de manière logique. Ainsi, par exemple, plus besoin d'instancier des java.io.File à tour de bras : la méthode java.nio.file.FileSystem.getPath("Path") permet de récupérer n'importe quel type de chemin, qu'il s'agisse d'un fichier ou d'un dossier, sous la forme d'un java.nio.file.Path.

Ensuite, l'essentiel de la fonction de mise à jour réside dans la méthode watch qui relance le chargement du fichier de configuration dès que celui-ci est modifié. Exemple de trace lors de l'utilisation :

Titre de l'application : Java 7 Watch Service
Le watcher a été démarré...

** Fichier propriétés modifié! Rechargement... (modifications du 2011-08-10T09:22:37.183499Z)**
Titre de l'application : Java 7 Watch Service rocks!!

Pour les plus observateurs, vous aurez également pu remarquer une nouvelle syntaxe de catch multiple : catch (InterruptedException|IOException e) apportée par le projet Coin dont j'ai parlé dans cet article.

Note :

Ce code fonctionne correctement lors de la modification du fichier avec Notepad (de Windows). Mais dès que l'on essaie de modifier le fichier avec un autre éditeur (Notepad++ ou Eclipse), le WatchService réagit à deux évènements de modification. Je n'ai pas encore d'explication quant à ce comportement (comme expliqué ici), mais si quelqu'un a déjà pu approfondir les tests et trouvé une solution, tout commentaire est le bienvenu!


Fichier(s) joint(s) :