07 octobre 2011

Maven WishList

Certains sont surpris de voir que j'ai écrit un livre sur Maven et qu'en même temps je le critique. Et oui, je ne suis pas un évangéliste tout blanc tout noir, pour moi Maven a apporté des choses très positives mais n'est pas l'outil parfait, loin s'en faut.

Les points principaux apportés par Maven sont (ahma) :

  • la standardisation de la structure des projets, rappelez vous le plaisir de greffer des morceau de build Ant d'un projet à l'autre ...
  • le concept de dépôt de bibliothèques et de gestion des dépendances, avec la construction progressive de central, aujourd'hui incontournable,
  • le mécanisme de plugins pour enrichir un build, avec une isolation des plugins (ce que ne faisait pas maven 1)
Mais ... Maven c'est aussi des points qui me déplaisent :

Le cycle de vie est extrêmement rigide et très, très compliqué à modifier (nécessite un nouveau packaging). Or il m'est souvent arrivé de regretter qu'il manque une phase pour y greffer un plugin, ce qui aboutit souvent à déclarer le plugin sur une phase inadaptée comme contournement. Exemple type : le compresseur JavaScript placé en phase "test" pour que le war soit construit avec des scripts optimisés (depuis est arrivé prepare-package, mais vous avez l'idée générale). On en arrive à hacker l'ordre d'exécution des plugins pour obtenir ce qu'on désire.

Le déploiement n'est pas atomique, loin s'en faut. C'est même pire que ça, il a lieu de manière morcelée lors d'un build multi-module. Si ça plante au milieu, une partie des artefacts est déjà déployée. Les connaisseurs auront reconnu le rôle tenu par le RedeployPublisher de Jenkins ... Alors bien sûr, Nexus pro comme Artifactory (peut être même Achiva ;P) proposent des solutions de contournement. On compense une défaillance de l'outil par un autre outil.

La gestion "one-shot" des métadonnées. Combien de bibliothèque ont été publiées avec un POM tout pourri ? Si les choses ont un peu progressé, il aurait été plus efficace d'avoir un mécanisme de version sur ces méta-données, en plus de la version de l'artefact, quitte à figer cette version lors de la release. De ce point de vue, héberger un repo maven sous forme de dépôt svn n'aurait pas été idiot, et lors de la release on aurait juste indiqué qu'on fait référence au méta-données du dépôt @révision1234.

Le POM sert à la fois de méta-données et de support du build. Combien de POM déployés contiennent des profils, des paramètres liés au développement ou aux environnements de test. A cumuler ces deux rôles, le POM se tire une balle dans le pied. Il faudrait découpler le build (profils, plugins, etc) des méta-données (dépendances, license, pré-requis, ...)

L'identification du dépôt d'un artefact. Si aujourd'hui je dépends de Hibrenate 4, que j'obtiens depuis le dépôt jBoss, dans 6 mois en voulant reconstruire mon projet, peut être aura t-il été publié sur central, ou sur l'un des (nombreux ?) autres repos que je déclare dans mon POM. Qu'est ce qui me garantit que c'est bien le même ? Deux options pour cela :

  • indiquer explicitement, via un attribut supplémentaire sur dependency, le repo d'où je désire obtenir l'artefact, ce qui accessoirement éviterait d'interroger 36 dépôts
  • fournir le hash SHA de l'artefact que je veux utiliser. Ca pourrait d'ailleurs complètement remplacer le groupId:artifactId:version, bien que ce ne serait pas super pratique.


Non, Maven n'est pas la panacée, mais il faut reconnaitre que les alternatives viables ne sont pas légions. Chacun ira de son commentaire sur Gradle, Rake, BuildR, ou truc-chose, si des choses intéressantes sont proposées elles sont très loin d'atteindre la maturité et le support par l'outillage qu'à Maven.

Wait and See ... peut être un jour un petit nouveau dans la cours des grand pour bousculer tout ça ?


  ________              ____   ____                 
 /  _____/_______ _____ \   \ /   / ____    ____    
/   \  ___\_  _ \ \__  \ \   Y   /_/ __ \  /    \   
\    \_\  \|  | \/ / __ \_\     / \  ___/ |   |  \  
 \______  /|__|   (____  / \___/   \___  ]|___|  /  
        \/             \/              \/      \/   
                                                        v 0.0.0.2 



7 commentaires:

Arnaud a dit…

"Le déploiement n'est pas atomique" : A ce niveau les serveurs de repos n'apportent rien en tout cas sur les SNAPSHOTs là ou le probleme est le plusfréquent. La seule chose qu'ils apportent ce sont pour les releases avec le staging.
En tout cas je vois que tu as toujours le blog rapide et que nos discussions restent utiles :-)

nicolas deloof a dit…

Hey, ça doit être la première fois que je fais un billet sur Maven sans parler de Sonatype ;P

olamy a dit…

déploiement atomique en maven3 il suffit de créer un point d'extension étendant AbstractExecutionListener attendre le sessionEndeed et là tu déploies les artifacts via wagon.
Et voili faut juste contribuer :P

Piwaï a dit…

Préciser le SHA-1 de l'artifact est une très bonne idée!. L'ensemble groupdId/artifactId/versionId ne garantit hélas pas grand chose, mais est évidemment bien plus comprehensible. Quand on y pense, un repo avec comme clé des SHA-1, ça pourrait ressembler à un repo Git :-) .

Sinon je crois que certains repo manager peuvent capturer ces informations (SHA-1 des dépendances lors d'un build), mais évidemment comme tu le dis c'est un contournement;

julienG a dit…

whish list très pointue je trouve. moi je suis beaucoup plus basique.

je voudrais :
- un parseur xml correct qui me permettre d’écrire une dépendance en une ligne
- des modules "light" au sens : même pom que papa
- une possibilité de separation main/test plus fine (avec src/main/testInteg src/main/testUnit) et le lancement des tests facilement filtrables.

nicolas deloof a dit…

@JulienG polyglot maven répond plus ou moins à ta première demande. Je n'ai pas parlé du format XML car on se rend compte que tout le monde s'en fout en fait.

Je ne comprend pas tes modules light. Tu hérite de qui tu veux...

Il n'y a jamais eu de consensus sur l'organisation des tests d'intégration, faut dire que ça dépend de ce que tu fais... Pour un lancement sélectif, c'est à surefire qu'il faut demander - ici je parle de ce qui manque dans maven-core.

Dominique De Vito a dit…

Le problème avec Maven, c'est que quand on développe avec Eclipse, on a 3 artéfacts qui vivent ensemble:
- Eclipse
- Maven
- le plugin Maven

Et il faut que tout ce beau monde s'accorde comme il faut, ce qui n'est pas facile.

Avec GWT, c'est encore pire, on a :
- Eclipse
- Maven
- le plugin Maven
- le plugin GWT

Perso, en faisant du dev Eclipse+GWT+Maven, je constate des instabilités de folie, à la puissance quinze. Ainsi, de temps en temps, le mode dev (hosted mode, de mémoire) ne fonctionne pas, et il faut faire un refresh sous Eclipse, et en faisant, par ex, un "update Maven configuration" au cas où un truc serait "coinçé" qque part, et là, paf, alors que je lance une commande Maven, Eclipse perd, comme par magie, des infos de configuration GWT (!), infos qu'il faut à nouveau redéfinir à la main. Et après, ca fonctionne à nouveau (sans que je sache trop où cela a changé), ou pas... car le pb peut se nicher dans un coin encore plus obscur (je vous passe les détails).

Comment en est-on arrivé là ?

Je pense que, faute d'avoir des vrais modules dans Java, et faute que les IDE s'entendent sur la gestion des modules, cette gestion a été prise en charge par un 3eme larron : Maven. Et donc, on a forcément Eclipse et Maven, et un plugin Maven d'intégration, plus ou moins bien gaulé.

Si l'on ajoute d'autres couches, comme GWT, j'ajoute aussi d'autres plugins pas tjrs très stables aussi, lié à un env de dev open source Eclipse dont le développement avance cahin-caha comme tout dev open source.

Il y a 10 ans, j'étais productif avec mon env de dev, mais maintenant, je ne peux plus dire que je suis productif. Ou alors, pour retrouver un niveau de codage satisfaisant, il faudrait que je me dirige vers des env comme Adobe Air par ex.

Donc, perso, ma Maven wishlist, c'est que Java inclut au plus tôt de vrais modules natifs, que ces IDE se greffent là-dessus et implémentent eux-mêmes une partie de l'intelligence de Maven (le rôle de Maven devenant, j'imagine, pour le coup, beaucoup moins important/central). De sorte que l'on n'ait plus N plugins réalisés par différentes parties/sociétés qui se causent plus ou moins bien entre elles.

En attendant ce jour qui n'est pas près d'arriver (il faut attendre Java 8, en 2013), je crains que ma productivité soit encore largement impactée par les outils Java actuellement les plus disponibles, dont Maven... Et je comprends les propos d'un Sébastien Douche qui se moque de la complexité des outils Java... http://jduchess.org/duchess-france/blog/entrevue-avec-sebastien-douche-vous-reprendrez-bien-encore-un-peu-de-git-et-dagilite/