Blog myBlog = BlogFactory.getWordPressBlog();
Article tagué Maven
Maven au pays des proxys
15/01/12
Le problème…
Il y a quelques temps, j’ai eu pour mission de stabiliser et de « mavenizer » une application legacy, dont le build était devenu ingérable (dépendances dans divers répertoires, mélanges de scripts shell, Ant, etc.).
Au sujet de la mavenization elle-même, je vous recommande cet article, donnant une méthode fiable permettant de retrouver la version exacte des dépendances lorsqu’elles ne sont pas connues. Je passe cependant rapidement sur cette étape qui n’est pas le sujet ici. Nous arrivons donc directement au moment où nous avons un fichier « pom.xml » convenable, dont nous voulons vérifier le bon fonctionnement pour assurer le packaging de l’application. Et c’est là que les choses commencent à se compliquer.
Car ce que j’ai oublier de préciser, c’est que cette mission est effectuée pour « Gros client », chez qui les règles de sécurité sont strictes : l’accès internet se fait uniquement au travers d’un proxy. Et plus particulièrement le modèle PALC avec toutes les options : identification individuelle obligatoire sur ledit proxy, mot de passe à modifier tous les 3 mois, verrouillage du compte après 5 tentatives ratées, etc. Pour Maven qui aime bien « télécharger l’univers », c’est problématique.
Petite digression sur une mauvaise surprise découverte lors de cette mission… Ubuntu 11.10 n’est pas du tout adapté au travail dans un environnement utilisant un proxy : il souffre en effet d’une régression empêchant le paramétrage d’exceptions (pour les serveurs du réseau local).
Paramétrer le proxy pour Maven
Maven fournit un guide pour paramétrer un proxy. L’opération consiste à renseigner les paramètres du proxy dans le « settings.xml » :
1 2 3 4 5 6 7 8 9 10 11 | <proxies> <proxy> <active>true</active> <protocol>http</protocol> <host>palc.grosclient.com</host> <port>8080</port> <username>user</username> <password>password</password> <nonProxyHosts></nonProxyHosts> </proxy> </proxies> |
Une fois ce paramétrage effectué, les dépôts sont bien résolus et les dépendances téléchargées. Mais il reste un soucis : certains dépôts irréductibles résistent encore… Par exemple le dépôt JBoss, ou encore Sonatype OSS. La cause est vite identifiée : ces dépôts utilisent le protocole « https » et non « http ».
Qu’à cela ne tienne : on duplique le bloc « proxy » en modifiant le protocole. A ceci près que ça ne marche pas… Maven ne sait utiliser qu’un seul proxy à la fois. Si on utilise le proxy « https », on pert le « http », et inversement. Peut-être une idée de correction à implémenter pour le hackergarten de mercredi prochain…
La seule solution que j’ai pu trouver à ce jour est de paramétrer les proxys au niveau de la ligne de commande :
1 2 3 4 5 6 7 8 9 10 | mvn -Dhttp.proxyHost=palc.grosclient.com -Dhttp.proxyPort=8080 -Dhttp.proxyUser=user -Dhttp.proxyPassword=password -Dhttps.proxyHost=palc.grosclient.com -Dhttps.proxyPort=8080 -Dhttps.proxyUser=user -Dhttps.proxyPassword=password install |
Il est possible de paramétrer un proxy dans le « settings.xml » et le deuxième en ligne de commande mais ce n’est pas très intuitif. J’aime autant que tous les paramètres soient au même endroit.
Une fois les paramètres correctement configurés, on peut les pérenniser en les enregistrant dans la variable d’environnement MAVEN_OPTS.
Utiliser un dépôt Maven interne
Suite au paramétrage correct des proxys (http et https), Maven peut à nouveau télécharger tout internet… et le build peut fonctionner. Nous pouvons donc aller plus loin et installer un dépôt Maven chez « Gros client », afin d’y publier les artefacts produits.
Cependant, ce serveur peut également servir à régler autrement notre problème de proxy. Pour cela, il y a un pré-requis : le serveur doit être accessible directement depuis le réseau de développement, et avoir accès à internet (si possible sans proxy). Dans notre cas, c’est Nexus qui fait office de dépôt Maven (mais la même technique doit fonctionner avec Artifactory ou autre…). Ensuite :
- On configure différents dépôts de type « proxy » vers chacun des dépôts externes dont on a besoin.
- On ajoute tous ces dépôts au dépôt groupe « public ».
Enfin, nous devons expliquer à Maven qu’il doit systématiquement utiliser notre serveur interne au lieu de tenter d’accéder directement aux dépôts externes (Maven central, etc.). Pour cela, retour dans « settings.xml », mais cette fois dans le bloc mirrors. Il suffit d’expliquer à Maven que tous les dépôts dont ont a besoin ont pour miroir notre serveur interne :
1 2 3 4 5 6 7 8 | <mirrors> <mirror> <id>nexus.grosclient.com</id> <name>Serveur Nexus de Gros client</name> <url>http://nexus.grosclient.com/content/groups/public</url> <mirrorOf>*</mirrorOf> </mirror> </mirrors> |
Avec cette configuration, le paramétrage des proxys fait précédemment doit être supprimé (ou une exception doit être ajoutée pour le dépôt interne).
Cette dernière configuration présente plusieurs avantages :
- L’ensemble des dépôts susceptibles d’être utilisés dans les différents projets de l’entreprise sont configurés de manière centrale, au niveau du dépôt. Cela permet
à l’équipe agileau chef de projet (rappel : nous sommes chez Gros client) de contrôler les dépôts/librairies utilisées sur le projet. - Le premier développeur qui demande une librairie au serveur Nexus va déclencher son téléchargement depuis son dépôt initial. Mais celle-ci sera ensuite mise en cache sur le serveur. Ainsi, les appels suivants (par les autres développeurs) se contenteront d’effectuer un téléchargement sur le réseau local, avec un gain de temps (voire de bande passante) non négligeable.
Premiers pas en Scala
24/05/11
Cela fait maintenant pas mal de temps que j’entends parler de Scala, mais je n’avais jamais pris le temps m’y attarder. Il y a maintenant deux semaines, l’annonce du lancement de Typesafe (on pourra lire l’article de Nicolas pour plus d’informations) m’a donné envie de regarder de plus près ce langage.
En attendant mon prochain passage par la FNAC pour trouver un bon livre sur la question, j’ai été glaner quelques informations pour débuter :
- La liste des billets de Nicolas sur la question
- Les 99 Scala Problems, que je suis en train de faire petit à petit
- Les différents liens de documentation du site officiel (il y a de quoi faire…)
J’ai eu la chance d’avoir des cours de Caml Light en prépa et de Lisp en école d’ingénieurs : la programmation fonctionnelle ne m’est donc pas inconnue, ce qui m’a grandement facilité l’entrée en matière (même si j’ai rapidement dû me mettre à niveau avec les Case Class et autres concepts que je n’avais encore jamais rencontré).
Les cours de prépa que j’ai pu avoir sur la question étaient excellents. Même s’ils concernent le langage Caml, ils fournissent des exemples originaux dans lesquels la programmation fonctionnelle permet de s’en sortir bien plus facilement qu’en programmation procédurale. Je propose donc aux curieux d’aller les consulter sur le site de notre enseignant.
La suite >
Gérer AUTREMENT un projet Maven avec Git
13/04/11
Comme vous avez été nombreux à apprécier mon article sur Maven et git, en voici la suite ! Il s’agit d’une solution alternative permettant de répondre à la même problématique, basée sur les subtree.
Rappel : mon but était de séparer la gestion de configuration de plusieurs modules Maven d’un même projet, tout en conservant un dépôt pour maintenir le projet (pom racine du projet, etc.).
La problématique étant la même, nous allons nous baser sur le même exemple : un projet créé à partir de l’archetype appfuse-modular-jsf. Pour sa mise en place de ce projet, je vous renvoie donc aux étapes Créer le projet de démonstration et Mise en place des dépôts distants.
Revenons à notre espace de travail
Maintenant que nous avons nos dépôts distants, la première chose à faire pour mettre en place les subtrees est de supprimer les répertoires des deux modules dans l’espace de travail. En effet, avec cette méthode, les modules n’ont pas de dépôt git locaux dédiés.
Déclarons ensuite les dépôts distants de notre espace de travail :
1 2 3 | git remote add origin $BARE_REPOS/demo.git # S'il n'existe pas déjà git remote add core $BARE_REPOS/demo-core.git git remote add webapp $BARE_REPOS/demo-webapp.git |
A ce stade, les habitués de git qui ne sont pas trop endormis doivent crier « KEUOUA ??? ». Effectivement, les démos distants sont normalement des clones du dépôt local. Or nous venons de déclarer trois dépôts distants qui n’ont pas un seul commit en commun.
Ce n’est pas une erreur, et c’est le mode de fonctionnement des subtrees. Contrairement aux submodules pour lesquels on avait trois dépôts locaux, avec les subtree, on a un unique dépôt local : le lien entre cet unique dépôt et les dépôts distants passe donc par les « remotes » du dépôt local.
Des branches locales pour travailler sur les modules
Nous allons maintenant créer des branches locales associées aux branches distantes afin de pouvoir travailler sur nos modules.
1 2 3 4 | git fetch core git fetch webapp git branch localcore --track core/master git branch localwebapp --track webapp/master |
Il est maintenant possible de travailler sur les modules localcore et localwebapp dans leurs branches locales respectives. Le tracking étant défini, les push seront effectués vers les dépôts respectifs des deux modules.
Et l’arborescence globale de notre projet ?
Depuis notre unique dépôt local, nous avons vu comment travailler séparément sur nos différents modules. Mais à ce stade, nous n’avons pas reconstitué l’arborescence de notre projet Maven. C’est à ce stade qu’interviennent les subtrees.
On rebascule dans la branche master de notre projet, et on exécute :
git read-tree --prefix=core/ -u localcore git read-tree --prefix=webapp/ -u localwebapp
Après cette étape, on n’oublie pas de commiter l’ensemble et nous avons récupéré l’arborescence globale de notre projet.
Mettre à jour le projet lorsque les modules évoluent
Notre module core a maintenant évolué dans sa branche. Ces modifications ne sont pas automatiquement reportées dans la branche master de notre projet.
Pour récupérer ces mises à jour, il suffit d’utiliser la commande :
1 | git merge -s subtree localcore |
Cette opération aura pour effet de fusionner dans la branche master les modules (ainsi que leurs historiques respectifs).
On peut juger que ces historiques sont « parasites » à ce niveau : on les a déjà dans la branche du module. On préfèrera dans ce cas la commande :
1 | git merge -s subtree --squash --no-commit localcore |
Cela aura pour effet d’agréger tous les commits en un seul et de préparer le message de commit (qui concatène les messages de tous les commits agrégés). Il ne reste plus qu’à corriger ce message et à valider le commit.
Submodules ou Subtrees ?
Nous avons donc deux méthodes permettant de traiter la même problématique. Il ne reste plus qu’à en choisir une. Les deux approches ont leurs avantages et leurs inconvénients.
Les subtrees sont plus faciles à manipuler : ils nécessitent moins d’opérations, et il est plus difficile de faire une erreur qu’avec les submodules (oubli d’un push par exemple).
Les submodules sont plus complexes à utiliser, mais plus structurés (il s’agit là d’un avis subjectif de ma part) : chaque dépôt distant est associé à un dépôt local.
Personnellement, ce sont les submodules que je préfère.
Gérer un projet Maven multi-modules avec Git
4/03/11
J’ai récemment assisté à l’atelier Git avancé de Christophe Porteneuve. Au programme, de nombreuses choses intéressantes, dont les submodules Git, La partie de la formation les concernant m’intéressait particulièrement pour une problématique que je rencontre très fréquemment : travailler avec un projet Maven multi-modules.
Il y a bien sûr la solution qui consiste à utiliser un unique dépôt Git à la racine du projet. Ca fonctionne bien, mais pour des gros projets, je préfère avoir un dépôt dédié à chacun des modules Maven. Cela ne poserait aucun problème, s’il n’y avait une arborescence de répertoires entre le projet principal, et ses modules.
Voyons donc avec un exemple comment mettre en place une gestion de configuration séparée pour chacun des modules d’un projet Maven.
La suite >
Découverte de IntelliJ IDEA
4/10/10
Je pourrais titrer ce billet « Confessions d’un éclipsien repenti », mais on m’accuserai de mauvais plagiat… et malgré la très bonne impression que m’a faite IntelliJ IDEA, j’apprécie toujours également mon fidèle Eclipse.
Mais revenons un tout petit peu en arrière… Depuis plus d’un an, j’entends parler de cet IDE : blogs, un récent comparatif, le Paris JUG, etc. J’avais donc décidé d’y regarder de plus près, mais sans jamais vraiment prendre le temps de m’y mettre. J’en ai eu récemment l’occasion, en testant le Play! Framework. Celui-ci dispose en effet d’une commande « idealize » permettant de générer le projet au format IDEA, qui n’a pas d’équivalent pour Eclipse. J’ai donc décidé de faire d’une pierre deux coups et de tester Play! en même temps qu’IntelliJ IDEA.
J’ai rapidement beaucoup apprécié les fonctionnalités de l’IDE, et j’ai donc étendu mon test à un projet Java/J2EE. Voici pas à pas le déroulement de ma découverte de l’IDE, pour les retardataires qui, comme moi, n’avaient pas encore franchi le pas…
La suite >
Nombreuses sorties dans le monde Java
4/05/10
Le retour des beaux jours est riche en nouvelles versions (et en annonces de nouveautés) pour la communauté Java :
- Le repository Nexus pour Maven 2 en version 1.6.0 : cf. la liste des nouveautés.
- La version 3.0 (immédiatement suivie de la 3.0.1) de JRebel, un outil permettant de gagner du temps dans les développements en prenant en compte les modifications de code “à chaud” dans la JVM, sans avoir à procéder à un arrêt-déploiement-relance de l’application (qui peut être très long sur des applications complexes). Cet outil offre un support spécifique pour la prise en compte de modifications dans la plupart des Frameworks (Hibernate, EJB, Spring, etc.)
- Le SpringSource TC Server 2.0 (un serveur Tomcat customisé pour l’utilisation de Spring).
- Nouvelle version de Groovy.
- Le serveur d’intégration continue Teamcity, qui passe en version 5.1, suivie par une version de correctifs 5.1.1. Par rapport à mon serveur d’intégration continue fétiche Hudson (dont une nouvelle version est publiée chaque semaine), Teamcity est également extensible par des plugins, mais n’est malheureusement pas Open Source. Cependant, une version gratuite existe, limitée à 20 projets et 20 utilisateurs (ce qui est très généreux par rapport à d’autres licences d’évaluations, et amplement suffisant pour tester l’outil). Au delà du Java, l’énorme avantage de cet outil est qu’il gère également l’intégration continue des projet .NET (ce qui permet de mutualiser la plateforme IC des entreprises travaillant sue les deux technologies).
- Patch du serveur d’applications Glassfish (en version 2.1.1). On remarque d’ailleurs sur cette page d’accueil la volonté d’Oracle qui (heureusement) ne compte pas abandonner ce serveur : les versions professionnelles du serveur (qui existaient déjà du temps de Sun) ont été renommées en “Oracle Glassfish Server”.
- Une nouvelle “Milestone” (la 7ème) de la future version “Helios” d’Eclipse, qui sortira en version définitive le 23 juin selon la roadmap officielle.
- Annonce de la sortie de VMForce, une solution de Cloud Computing Java pour les développeurs. Cette solution est annoncée conjointement par VMWare et SalesForce, et fait déjà couler beaucoup d’encre, car elle pourrait concurrencer la plateforme de Google, la “Google App Engine”, avec des options orientées pour l’entreprise ; intégration de Spring, d’une persistance de données Haute Disponibilité, etc. Pour plus d’informations sur ce sujet très intéressant, je recommande le billet de developpez.com.
Ces nouveautés sont toutes plus alléchantes les unes que les autres… le soucis étant malheureusement comme toujours le manque de temps disponible pour s’en occuper !
Mise à jour le 06 mai 2010 : A peine deux jours et Je m’aperçois que de nouveaux outils sont apparus (et que j’en avais oubliés) :
- La version 4.0.1 des produits Talend est parue. Elle corrige de nombreux bugs de la version 4.0.0 (dont un particulièrement gênant pour les développeurs de composants dans Talend Open Studio : la disparition de l’éditeur XML)
- La version 2.1 de Sonar, apportant un ensemble de nouvelles fonctionnalités (validation de nouvelles règles, nouvelles métriques et options de recherche, meilleure intégration avec Maven, etc.)
- La première beta du très attendu Maven 3. Pour mémoire, je recommande cet article de Romain Linsolas faisant la liste des nouveautés qu’il doit apporter.
- La version 3.5 de yEd, mon éditeur de diagrammes préféré : la liste des nouveautés est sur la page de téléchargement.