12 juillet 2012

GWT 2.5 : Premiers pas avec le «Super Dev Mode»

Parmi les nouveautés majeures de la version 2.5 de GWT figure le «Super Dev Mode». Le Super Dev Mode est en effet qualifié de majeur, car il a pour but d'améliorer la productivité des développeurs en offrant une alternative au «Dev Mode classique» qui, avouons-le, est contraignant (installation obligatoire de plug-in dans le navigateur), lent et consommateur en mémoire lorsque le code de l'application atteint une taille importante.

Contrairement à ce que l'on pourrait penser, le Super Dev Mode n'est pas un Dev Mode amélioré. En effet :

  • Dans le Dev Mode l'exécution de l'IHM est distribuée entre la JVM (qui exécute le code Java) et le navigateur (qui exécute le code JavaScript présent dans les méthodes JSNI). La communication entre le code Java et le code JavaScript se fait à l'aide d'un protocole basé sur les messages utilisant une connexion TCP sur le port 9997. Cela génère beaucoup d'aller-retour entre la JVM et le navigateur.
  • Dans le Super Dev Mode l'IHM ne tourne pas dans une JVM, elle est compilée en mode «Super Draft» sans aucune optimisation. C'est du JavaScript pure. Cela veut dire qu'il n'y plus d'échange verbeux entre la JVM et le navigateur. En revanche, il n'est plus possible de déboguer dans votre IDE préféré, vous le ferez cette fois-ci dans votre navigateur préféré et toujours en Java !

Pour plus de détails sur les différences, je vous invite à consulter l'article de Google Introducing Super Dev Mode.

En résumé, le Super Dev Mode vous permet de compiler et de tester rapidement votre code. Il vous permet, comme dit plus haut, de déboguer et d'inspecter votre code Java directement dans le navigateur si vous utilisez Chrome (Chrome utilise une technique magique appelée Source Maps. Chez Mozilla on est à pied d’œuvre  pour l'implémenter dans Firefox).

Nous allons donc vous présenter le Super Dev Mode à l'aide d'un exemple simple. Le tutoriel sera divisé en deux parties : la première concerne le lancement et l'utilisation du Super Dev Mode. La seconde concerne quant à elle le débogage du code Java directement dans le navigateur.

Avertissement:

  • Ce tutoriel a été réalisé avec la version RC1, il est possible de constater des différences avec la version finale. Il sera éventuellement mis à jour à la sortie de la version finale.
  • Nous n'expliquerons pas le fonctionnement interne du Super Dev Mode. Un article complet sur le sujet a déjà été publié par Thomas Broyer (contributeur et membre du comité de pilotage du projet open source GWT).
  • Étant un utilisateur d'Eclipse, j'ai réalisé ce tutoriel avec cet outil. Les principes expliqués dans cet article devraient s'appliquer à n'importe quelle autre IDE.

Partie 1 : Lancement du Super Dev Mode

Avant de commencer, assurez-vous de disposer d'un environnement de développement composé de :

Pour illustrer le Super Dev Mode, nous allons nous servir de l'application exemple fournie par GPE (Google Plugin for Eclipse). Préparons d'abord l'environnement de développement :

1 Installez le SDK 2.5 :

  1. Récupérez le version 2.5-rc1 du SDK à cette adresse : http://google-web-toolkit.googlecode.com/files/gwt-2.5.0.rc1.zip
  2. Lancez Eclipse, ouvrez les préférences puis allez dans rubrique « Google > Webtoolkit » pour ajoutez le nouveau SDK.

2 Créez une nouvelle application GWT

  1. Créez une nouvelle application GWT, nommez-la Hello et choisissez comme nom de package hello.
  2. Assurez-vous d'avoir sélectionné le SDK 2.5.0
  3. Décochez "Use Google App Engine"
(cliquez sur l'image pour l'agrandir)

3 Lancez l'application avec le Dev Mode «classique»  ou avec n'importe quel Servlet Container

Exécutez l'application avec le Dev Mode « Run As -> Web Application ».  Nous utiliserons plus tard l'URL qui est affichée : http://127.0.0.1:8888/Hello.html?gwt.codesvr=127.0.0.1:9997.

Le Dev Mode n'est pas obligatoire nous l'employons juste pour exécuter la partie serveur de l'application. Cela veut dire que vous pouvez utiliser votre serveur habituel, par exemple Tomcat ou Jetty.

4 Préparez le module GWT

Comme vous allez le voir plus loin, le Super Dev Mode est un petit programme serveur qui écoute les demandes de compilation et envoie le résultat sur le port 9876. Ainsi, dans ce mode les ressources statiques sont servies par un serveur autre que le serveur hébergeant les services RPC et la Host Page. Ce scénario est prévu par GWT, mais demande l'utilisation d'un linker spécial nommé xsiframe.

Ceci n'est pas suffisant, il faut que le bootstrap (hello.nocache.js) appel l'autre bootstrap se trouvant sur le serveur du Super Dev Mode c'est-à-dire http://localhost:9876/hello/hello.nocache.js. Ceci est possible en activant la propriété devModeRedirectEnabled.

En résumé, ajoutez au fichier de configuration du module (Hello.gwt.xml) les deux lignes suivantes :

<add-linker name="xsiframe"/>
<set-configuration-property name="devModeRedirectEnabled" value="true"/>

5 Lancez le Super Dev Mode

Pour l'instant GPE ne supporte pas le Super Dev Mode, nous allons donc le lancer manuellement en créant un Launcher Eclipse :

  1. Lancez «Run Configurations», sélectionnez le type «Java Application».
  2. Donnez lui le nom «Hello SuperDevMode» et renseignez les paramètres suivants avec les valeurs correspondantes :
    • Projet : Hello
    • Main class : com.google.gwt.dev.codeserver.CodeServer (c'est la classe du serveur qui va écouter sur le port 9786)
  3. Nous devons spécifier à la classe CodeServer le répertoire source ainsi que le nom du module. Dans l'onglet «Arguments» ajoutez au champ «Program Arguments» ce qui suit :  -src src/ -workDir workdir/ hello.Hello
  4. Dans l'onglet Classpath ajouter le jar externe gwt-codeserver.jar (il se trouve à la racine du répertoire d'installation du SDK).
  5. Vous pouvez lancer maintenant le Super Dev Mode

Voici une capture d'écran de la sortie du CodeServer. Remarquez le message encadré :

Allez à l'adresse indiquée et suivez la procédure décrite dans la page affichée.

(cliquez sur l'image pour l'agrandir)

1 . Ajouter les deux bookmarklets à votre barre de favoris (Dans la plupart des navigateurs la barre n'est pas affichée, affichez là et glissez-déposez les deux liens dans la barre)


2 -  Attention, le message "Visit a web page that use one of these modules : hello" est un peu trompeur, car il nous incite à cliquer sur le nom du module (hello). Ce n'est pas ce lien qu'il faut ouvrir mais plutôt  l'URL fournie par le DevMode classique (sans le suffixe) ou par votre servlet container : http://127.0.0.1:8888/Hello.html

Le lien sur le nom du module vous permet de voir ce qui a été généré ainsi que les messages du compilateur.

(cliquez sur l'image pour l'agrandir)

Cliquez sur maintenant sur la bookmarklet Dev Mode On. Une boite de dialogue s'affiche vous invitant à compiler le module «hello». Vous pouvez à n'importe quel moment désactiver le Super Dev Mode en cliquant sur la bookmarklet Dev Mode Off.

(cliquez sur l'image pour l'agrandir)

Partie 2 : Déboguez le code source Java directement dans Chrome :

Pour cette partie vous êtes obligés d'utiliser Chrome, car il est pour l'instant le seul à supporter le Source Maps.

Qu'est-ce le Source Maps

En production, le code JavaScript est souvent obfusqué et compressé. Ce code est quasiment impossible à déboguer. Le Source Maps est une technique qui permet de rendre cela possible en déboguant directement le code d'origine (grâce à des mappings de source), ce code d'origine peut être du JavaScript, du CoffeScript, du Java (notre cas) ou tout autre langage. Le Souce Maps ne concerne pas uniquement le débogage, il conccerne aussi les messages d'erreurs CSS et JavaScript, les logs, la StackTrace, etc.

1 - Ouvrez Chrome et activez le source maps : Affichez les «Outils de développement» en utilisant le combinaison de touches Ctrl+Shift+I. Affichez ensuite les paramètres en cliquant sur l’icône située en bas à droite de la fenêtre :

(cliquez sur l'image pour l'agrandir)

Allez maintenant dans l'onglet Scripts, dans l'explorateur de scripts (à gauche) vous devriez voir tous les sources utilisées par votre IHM (y compris ceux générées). Vous pouvez maintenant poser des points d'arrêt, inspecter la valeur de variables, voir la stack d'exécution, etc.

Happy Debugging !


Liens et références utilisées dans cet article

GWT 2.5 RC1 : Release notes, release notes détaillée et liste de bugs fixes.

How does GWT's Super Dev Mode work ? par Thomas Broyer

Introducing Super Dev Mode par Google

Introduction to JavaScript Source Maps par Ryan Seddon.

Programmation GWT 2 : Sous le capot de GWT par Sami Jaber

Conception du DevMode : Out of Process Hosted Mode par Google

19 avril 2010

Comment obtenir un accès root en exploitant une faille XSS, le cas Apache

Contexte : L'infrastructure technique de la fondation Apache a été victime d'une attaque XSS suivie d'une intrusion dans les systèmes. Les administrateurs ont reporté cet incident en détail et avec transparence.

Ils ont fait état des erreurs qu’ils ont commises et ont établi des recommandations afin d'améliorer la sécurisation des infrastructures. Ce billet tente d'expliquer la partie XSS de l'attaque et d'offrir une analyse du point de vue du développeur, il livre enfin des recommandations pour vous aider à renforcer la sécurité de vos applications Web.

Tout a commencé par une simple déclaration d'anomalie (issue INFRA-2591) dans le JIRA de la fondation Apache, un message aussi bref qu'énigmatique contenant un lien masqué par Tinyurl :

«ive got this error while browsing some projects in jira http://tinyurl.com/XXXXXXXXX» (le Tinyurl a été brouillé intentionnellement).

Le lien recelait des intentions peu amicales : l'URL d'une page contenant une faille XSS complétée par un code JavaScript hostile. Le code JavaScript sous forme de paramètres HTTP fait deux choses : voler le cookie de session des administrateurs en l'envoyant à un serveur externe, puis, pour ne pas éveiller les soupçons, affiche une une stack trace Java dans pastie.org (site communautaire d'échange et de partage de texte) faisant croire qu'il y a eu vraiment un problème.

Ce lien a été créé sur mesure pour une JSP contenant une faille XSS. Cette JSP quelconque ne contient pas de code spécialement sensible, elle affiche seulement une boite de dialogue pour choisir des couleurs (colorPicker.jsp) :



Dans cette page, on récupère deux paramètres : element et defaultColor, ces deux paramètres sont directement recopiés dans la page sans aucun contrôle d'assainissement !



Pour exploiter cette faille, des valeurs pour element et defaultColor ont été judicieusement choisies, de façon à ce que le code ait un comportement spéciale. Si l'on observe bien les valeurs dans l'URL, elles sont presque inintelligibles, mais dès qu'on les injecte dans le code, celui-là change bizarrement de structure, on se rend compte rapidement de la supercherie : à la ligne 26 lorsque le moteur JavaScript exécute opener.document.jiraform.name, cela génère une erreur, le flux d'exécution entre dans le bloc catch dans lequel le navigateur envoie innocemment le cookie de l'utilisateur à un serveur, outrepassant carrément le
principe du Same Origin policy (SOP).

Le serveur en question n'est qu'un site Web hébergé gratuitement sur une banale plateforme d'hébergement : PHP, Mysql, etc. Aucun risque pour le pirate.




L'attaque ne s'arrête pas là, puisque le pirate a attaqué la mire de connexion par « recherche exhaustive » (brute force attack). Cette attaque n'a pas été détectée faute de présence d'outil adéquat (sa présence aurait aidé à détecter rapidement l'attaque).

Une fois introduit dans le système, le pirate a remplacé l’écran d’authentification par un autre lui permettant de collecter des mots de passe grâce à une archive JAR injectée, cela m’a tout de suite rappelé l'excellente étude de Philippe PRADOS qui démontre avec force détails la façon avec laquelle il est possible de compromettre une application Web en posant juste un fichier JAR. Les techniques sont nombreuses : injection d'une valve Tomcat, utilisation de l'AOP, de filtres J2EE, corruption de la configuration Spring ou la surcharge des parseurs XML du JDK (Un projet Google code consacré à cette étude http://code.google.com/p/macaron/ a été mis en place, on y trouve notamment un PDF d'une soixantaine de pages, rédigé en français : surprenant, didactique et très riche en informations).

Comment prévenir ce genre d'attaques ?

En tant que développeurs

Heureusement, il est possible de se prémunir contre ce genre d'attaque et de manière efficace. Il suffit d'observer quelques règles de programmation simples à mettre en œuvre :


Utilisez un filtre J2EE contre le XSS : il s'agit d'un filtre, qui se base sur des expressions rationnelles, et qui va analyser la requête afin d'y déceler des combinaisons de caractères non autorisées dans le corps de la requête (par exemple ?clientId=<script>...) et de prendre les mesures adéquates : traçage de la requête, envoi d'un mail à l'administrateur, assainissement des valeurs (déspécialisation des caractères spéciaux, etc.).

Validez votre filtre, en écrivant des tests unitaires basés sur les préventions XSS et sur les patterns XSS qu'il est facile de trouver sur la Toile.

Utilisez le flag httpOnly : httpOnly est un flag qui indique qu'un cookie ne peut être utilisé que pour les échanges HTTP. Aucun script ne pourra y accéder, même en présence de faille XSS, il sera impossible de subtiliser le cookie. Le flag httpOnly fonctionne sur tous les navigateurs récents (y compris la famille IE puisqu'il a été inventé en 2002 par Microsoft).

Le flag est concaténé à l'entête HTTP Set-Cookie de la façon suivante :

Set-Cookie: SESSIONID=XXXXX; path=/;HttpOnly

Pour activer ce flag dans Tomcat, il suffit d'ajouter useHttpOnly=True dans l'élément <Context> du fichier context.xml de l'application Web.

<Context useHttpOnly="true" docBase="...">

...

</Context>

Utilisez un Firewall applicatif ou WAF (Web Application Firewall) : bien que cela intéresse surtout les opérateurs de production. Il est important de connaitre cette famille d'outils.
Un WAF intervient au niveau Application du modèle OSI (différemment des firewalls qui analysent quant à eux le niveau réseau), il connait les protocoles et est capable de détecter des attaques en analysant le contenu des échanges (injection SQL, XSS, etc). Il se présente sous forme d'alliance ou sous forme de programme tel que mod_security (s'installe comme plugin dans le serveur Web Apache).


Utilisez un outil d'analyseur statique de code : un outil tel que Findbugs, permet de détecter des faiblesses dans le code (par exemple, récrire directement un paramètre de la requête HTTP dans la réponse, ou inclure directement ce paramètre dans un statement SQL).




En tant qu’utilisateurs

Ne cliquez jamais sur un lien rétréci (tinyurl, bitly, etc). Si vous utilisez Twitter, l'utilisation de réducteur d'URL est inévitable. Il existe, toutefois, des plugins pour les navigateurs qui décodent à la volée les liens raccourcis (http://longurl.org/tools ou http://www.longurlplease.com/ par
exemple).



Ne cliquez jamais sur un lien envoyé par une personne inconnue (en plus du risque de XSS, s'ajoute le risque d'attaque XSRF), même si vous connaissez la personne, il se peut que son identité soit usurpée.


Armez-vous d'un plugin de sécurité dans votre navigateur. Depuis que j'utilise NoScript, je ne peux plus m'en passer. À l'occasion de cet article, j'ai éprouvé l'efficacité de ce plugin sur la page piégée, le résultat ne m'a pas déçu (voir capture d'écran suivante).





Limitez la durée de vie de vos cookies : ne pas cocher «Se souvenir de moi» lorsque vous connectez.

Conclusion

Cette affaire nous a montré qu'il suffit d'une faille, d'un relâchement de la vigilance des utilisateurs pour que la sécurité d'un système informatique s'effondre comme un château de cartes. Les espaces collaboratifs d'entreprise se multipliant (l'explosion des offres SaaS et l'émergence des réseaux sociaux pour entreprises en témoignent), la compromission d'un seul compte utilisateur peut potentiellement affecter la sécurité du système d'informations : vol de documents confidentiels, accès aux dossiers clients (CRM), dégradation, etc.. Cela est lié à la sophistication grandissante des technologies qui peut déstabiliser les utilisateurs et fléchir leur attention. Il est donc primordial, de les sensibiliser ainsi que les développeurs aux problèmes de sécurité et de former ces derniers aux parades aux techniques d'attaque Web 2.0. Enfin, rendre les audits de sécurité systématiques et ne plus les sacrifier sur l’autel des « deadlines » nos assurera des livrables plus fiables et qui, à long terme, rentabiliseront largement l'investissement dans la sécurité.

11 mars 2009

JBoss TattleTale, un outil de vérification de dépendances

Actuellement, j'effectue la migration vers Maven de quelques applications historiques. La difficulté de cette tâche réside dans le dépouillement et l'inventaire des fichiers JAR desquels dépend une application. En effet, on se retrouve face à un amas de fichiers JAR parmi lesquels se trouvent des fichiers JAR doublons (avec un nom différent ou une version différente), des fichiers JAR appartenant au serveur d'applications (par exemple, servlet.jar ou connector.jar), d'autres qui ne sont pas ou plus utilisés par l'application et parfois même des fichiers JAR de bibliothèques de tests unitaires (par exemple junit.jar). Le travail consiste alors à ne garder que les JAR qui sont réellement utilisés et d'éliminer (avec la plus grande précaution) tous les autres. Il va sans dire que s’attaquer à un tel problème à « mains nues » n'est pas une mince affaire.

C'est en cherchant un outil de vérification de dépendances que je suis tombé sur l'utilitaire « JBoss Tattletale », qui à ma grande chance vient de sortir (en version bêta) des laboratoires de JBoss (voir l'annonce sur le Blog de JBoss).
Cet outil permet de vérifier les dépendances entre les fichiers JAR présents dans un même répertoire (considéré comme un classpath). Ses fonctionnalités les plus remarquables sont :
  • Identifier les dépendances entre les fichiers JAR (par exemple, hibernate-3.1.3.jar dépendant de antlr-2.7.6rc1.jar)
  • Lister les classes dont dépend un fichier JAR et lister celles qu'il expose.
  • Lister les classes dont dépend un JAR, mais qui sont absentes du classpath.
  • Lister les classes présentes dans le classepath et les fichiers JAR dans lesquels elles se trouvent
  • Alerter si une classe est présente dans plusieurs fichiers JAR.

L'outil s'utilise en ligne de commande et sa prise en main est rapide. Il génère un rapport au format HTML dans lequel on peut naviguer aisément (voir la capture d'écran ci-contre).

Cet outil m'a vraiment aidé à effectuer la vérification des dépendances lors de la phase préliminaire de migration vers Maven. Malheureusement, il ne dispose pas (pour l'instant?) de plugin Maven permettant l'automatisation de cette tâche (de son coté, ANT dispose déjà d'une tâche tattletale).
Enfin, si vous vous demandez ce que veut dire «tattletale» sa définition se trouve ici. En résumé, «tattletale» est une personne commère qui révèle les secrets. On voit bien que e nom n'a pas été choisi par hasard !
L'outil, qui me semble très prometteur, en est tout juste à ces débuts. Souhaitons-lui un bel avenir!

Liens utiles :

Téléchargement : http://sourceforge.net/project/showfiles.php?group_id=22866&package_id=311046&release_id=665534 (800ko environ)

JIRA : https://jira.jboss.org/jira/browse/TTALE


6 mars 2009

Comment lire la version d'un JAR à partir du fichier « Manifest » ?


Toute application doit avoir un numéro de version. Il permet d'identifier aisément, entre autres, la branche du code source à l'origine de sa création (pour corriger des bogues, effectuer des évolutions, etc.). La technique la plus répandue c'est d'écrire le numéro de version dans un fichier de propriétés (properties) dont le contenu pourrait ressembler à ce qui suit :

application.version=1.0b

Il est alors possible à l'application d'extraire le numéro de version pour l'afficher dans la barre de titre, par exemple, ou l'utiliser dans la trace applicative. Ce procédé vous oblige à maintenir le fichier et à veiller à incrémenter correctement le numéro de version.

Bonne nouvelle si vous utilisez Maven : vous n’aurez plus à effectuer cette tache ! En effet, Maven inscrit systématiquement le numéro de version dans le Manifest (MANIFEST.MF) des JAR qu'il produit (le numéro de version est exactement le même que celui qui figure dans le POM du projet Maven).

Comment extraire le numéro de version ?

Commençons par un code simple. Cela se fait en deux étapes : charger le fichier MANIFEST.MF, puis lire son contenu grâce à la classe java.util.jar.Manifest.

La classe suivante est « packagée » dans un jar nommé version.jar.
public class VersionUtil {

public static void main(String[] args) throws IOException {
System.out.println(readVersion());
}

public static String readVersion() throws IOException {

InputStream in = VersionUtil.class.getResourceAsStream("/META-INF/MANIFEST.MF");

Manifest manifest = new Manifest(in);

// Lire la propriété "Implementation-Version" du Manifest

String version = manifest.getMainAttributes().getValue(Attributes.Name.IMPLEMENTATION_VERSION);

return version;

}
}

Le code ci-dessus fonctionne sans erreur, mais affiche quand même un résultat erroné : 1.5.0_10. Il correspond en réalité au numéro de version du JDK. Le ficher MANIFEST.MF chargé n'était «manifestement» pas celui du JAR en question, mais celui de rt.jar (le jar qui contient les classes de base de Java). L'explication est la suivante : la méthode getResourceAsStream(..) délègue la lecture de MANIFEST.MF au chargeur de classe (classloader) de la classe VersionUtil.class, or ce chargeur de classe se trouve dans rt.jar et non dans version.jar. Pour qu'une classe puisse charger le fichier MANIFEST.MF du JAR dans lequel elle se trouve, elle recourt à une méthode utilitaire qui calcule le chemin dudit JAR. Elle déduit ensuite l'emplacement du Manifest.

L'extrait de code Java montre comment le chemin vers le MANIFEST.MF est trouvé. J'avoue que le code est un peu alambiqué, mais heureusement il est commenté. La méthode présente l'avantage de fonctionner, et pour une classe se trouvant dans un jar, et pour une classe se trouvant dans un répertoire. Pour une meilleure compréhension, j'ai mis en commentaires le contenu des variables à chaque étape, et ce, pour les deux cas précités.
private static String getPathToManifest(){

// 1 - Lire le nom de la classe
String classSimpleName = VersionUtil.class.getSimpleName() + ".class";
// classSimpleName = VersionUtil.class

// 2 - Récupérer le chemin physique de la classe
String pathToClass = VersionUtil.class.getResource(classSimpleName).toString();

// pathToClass = file:/C:/workspace/VersionUtil/bin/com/abdennebi/version/VersionUtil.class
// pathToClass = jar:file:/C:/version.jar!/com/abdennebi/version/VersionUtil.class

// 3 - Récupérer le chemin de la classe à partir de la racine du classpath
String classFullName = VersionUtil.class.getName().replace('.', '/') + ".class";
// classFullName = com/abdennebi/version/VersionUtil.class

// 4 - Récupérer le chemin complet vers MANIFEST.MF
String pathToManifest = pathToClass.substring( 0, pathToClass.length() - (classFullName.length())) + "META-INF/MANIFEST.MF";
// pathToManifest = file:/C:/workspace/VersionUtil/bin/META-INF/MANIFEST.MF
// pathToManifest = jar:file:/C:/version.jar!/META-INF/MANIFEST.MF

return pathToManifest;
}
L'exemple complet se trouve à cet endroit VersionUtil.java. Une modification pour Java 1.4 se trouve ici : VersionUtil14.java.

16 janvier 2009

Maven, considérer le répertoire source comme un répertoire de ressources

Par défaut, Maven sépare les sources java des autres ressources, telles que les fichiers properties ou les fichiers XML. Ceci, constitue en général, une bonne pratique. Cependant, si vous migrez une application et que vous ne désirez pas séparer les ressources des sources Java, il est impératif d'en informer Maven, sinon vous risquerez d'avoir des surprises (un WAR sans le moindre fichier properties).

Pour ce faire, ajoutez ce bout de code XML au fichier POM de votre projet :


...


src/main/java

**/*.java



...

Cette déclaration informe Maven que le répertoire src/main/java contient des ressources et qu'il ne faut pas prendre en compte les fichiers Java (sinon ils risquent d'être inclus dans l'artéfact généré par Maven).

9 janvier 2009

Ajoutez un deuxième répertoire source à votre projet Maven

Actuellement, je m'occupe de la migration du code d'une application historique vers Maven. Cette application contient deux répertoires sources Java, l'un contient du code généré (des proxies PacBase), et l'autre contient le code écrit par le programmeur. Pour ce faire, il faut indiquer à Maven d'utiliser un répertoire supplémentaire à savoir src/main/javaproxie (en plus du classique src/main/java).

Maven permet de définir un répertoire source différent du répertoire source conventionnel grâce à la déclaration suivante (en prenant comme exemple src/main/javaproxies):


src/main/javaproxies


Le problème est qu'il n'est pas possible d'ajouter (nativement) un nouveau répertoire source. C'est plutôt le rôle du plugin build-helper et son goal add-source, il permet, en effet, de définir plusieurs répertoires sources de la manière suivante :




org.codehaus.mojo
build-helper-maven-plugin


add-source
generate-sources

add-source



src/main/javaproxies







En résumé, dans des situations où il est nécessaire d'utiliser un répertoire source supplémentaire, par exemple du code généré par xDoclet, des stubs et proxies Corba ou Web Services, ce plugin vous sauvera la vie !