Docker Storage Driver: Don't Use Devicemapper

DISCLAIMER: I’m not a system expert. What follows is more an aggregation of things I’ve tried and informations gathered on the Internet. I also wrote it to serve as a placeholder for myself. I make sure to provide many links so that you can make your own opinion. Please don’t hesitate to give feedback if you disagree with some statements below.

For some months now, we’ve started deploying more and more Docker services internally to progressively gather experiences.

After encountering a few issues, mainly related to storage, I’ve started to read a lot about the Docker Storage drivers.

Docker default behaviour (with DeviceMapper): Wrong

As much as I love Docker, some may find a pity that the default behaviour is NOT to be used in production (on a non-ubuntu host)!

Indeed, by default, here’s what Docker will choose as a storage driver:

  • AUFS

  • Devicemapper, in loopback mode

BUT, the thing is: though AUFS is apparently great for Docker (was used by DotCloud for their PaaS, before it became public), it’s not in the standard kernel. And is unlikely to be in the future.

For this reason, distributions like RedHat (which is upstream-first) chose to support devicemapper instead, in the so-called thin provisioning mode, aka thinp.

But by default, if AUFS is not found in the current kernel, Docker will fallback to the ubiquitous devicemapper driver. And for the default again, it will create loopback files. This is great for newcomers bootstrapping, but horrible from a least surprise principle perspective: since this mode MUST NOT be used in production.

So, I can use still Devicemapper, if I make sure to use thinp?

Short answer: no.

Longer one: many Docker knowledgeable people have publicly stated that you should prefer other ones. Many have even recommended that you default to using Overlay [1]:

@codinghorror more specifically we’ve never seen devmapper work reliably… Overlayfs support is pretty good now. Also zfs & btrfs.

Even Daniel J Walsh aka rhdan, working for RedHat has stated [2]:

Red Hat kernel engineers have been working hard on Overlayfs, (Perhaps others on the outside, but I am not familiar). We hope to turn it on for docker in rhel7.2 BUT […]

Or:

Device Mapper is a complex subsystem

I can’t help thinking that this sentence may tell us more about the subject than his author was thinking. Complexity often being the reason software can not survive years? Might be.

Conclusion: if in doubt, use overlay

I’ve started converting the Docker hosts I work with from devicemapper to overlay. My first impressions are good and everything seems to be working as expected [3].

From all I’ve read, my current wager is that overlay will soon become the default driver. It has the pros of devmapper (no need to create a FS for one) apparently without much of its cons.

Only some specific use cases will still make people choose other drivers like btrfs or zfs. But as these require to create and size real FS to be used, they are unlikely to be used as widely.

Some references


1 Previously named Overlayfs, it has been renamed simply Overlay when it got merged in the Kernel
2 in a pull-request by RedHat’s Vincent Batts, one of the most active Docker committers not working for Docker Inc, about putting overlay as the default driver in place of Devicemapper. That may ring yet another bell to you. At least it did for me.
3 I’ve actually had issues with RedHat’s Docker 1.6.x but this disappeared when I upgraded the Fedora Atomic Host I was playing with to Docker 1.7.1

Why I think I failed as an architect

I was not actually planning to write that, more something about Docker.* these days. But that’s how it is.

I was listening to the Arrested Devops podcast — Episode 38 about Career Development, with Jeff Hackert.

For many reasons lately, I’ve been thinking about my career and what I wanted to do. By the way, I absolutely, positively recommend you listen to that episode (35 minutes, seriously it’s worth it).

The part that made me think about that article is when Jeff talked about making things you do visible. Providing context. Understanding people’s needs.

Architect Failure

Though I retrospectively think I should maybe have pushed sometimes some more evolved/involved solutions, I’m not actually talking about a technical failure.

No, I’m talking about human/social one.

To simplify a bit, the management decided to reorganize the development with dev teams on one side, and a separate architecture team.

Because I had earned technical respect from (at least some of) my coworkers, it went not so badly initially. Some teams were asking for reviews, or even for solutions for issues/requirements they had.

But for some people, developers and maybe even more managers, we were intruders. Not welcome.

What I did

Mainly, I think I stayed in my office way too much, and took that position for granted. Kind of the Ivory Tower issue (well, without the tone I hope. I’ve tried hard to not be condescending especially because of how much I despised self-said Architects who didn’t code).

I thought the requests were going to flow naturally. How wrong, and dumb, I was.

Don’t get me wrong. I was not hiding and playing video-games on my computer :-). I was actually working for some teams. But even those teams eventually didn’t even ask us for help, and worked us around.

What I should have done

I should have hanged out more with the teams (which is somehow ironic I didn’t when you know me). Go see them, ask them if they were needing help. Get involved with them. Simply be more empathetic. Let them know what we did, why, for whom, constantly. Make that publicly available.

I should also have refused to work on some subjects supposed to be useful in 1 or 2 years, without any actual need. How many hours I lost on useless PoCs, studies, that will never get used.

Wrap up

That made me realize something. Something that may be obvious to more experienced people: the fact that the current management structure, the current organization will NOT stay as-is forever. And that you should always strive to break barriers, reach out the people who do the actual work and help them, work with them.

This way, people will know you’re basically useful wherever you are, and whatever position you hold. And that might also transitively prove your team is useful.

If you don’t, then you’re dead. At the next shakeup, you’ll be wiped out. And you will have deserved it.

De l'intérêt de Docker pour tout développeur !

Dans l’article qui suit, je vais vous montrer comment j’ai récemment eu l’occasion d’utiliser Docker pour un cas concret.

La particularité ici est que cela était un cas utile à un travail de développement : cela n’avait pas pour but de faire tourner une application, simplement d’accéder à un environnement (via Docker, donc), de récupérer des informations, puis de jeter.

Pour ce cas, j’estime avoir gagné au bas mot plusieurs dizaines de minutes.

Le contexte

Alors que je travaillais sur une pull request pour le projet maven-scm, j’ai eu besoin pour les tests d’intégration d’une vieille version de Subversion (oui, j’utilise Git sinon :-)).

Plus précisément, j’avais besoin de pouvoir faire un checkout d’un dépôt SVN avec les métadonnées au format SVN 1.6.

Or, ma machine est à jour, et la version que j’ai en local est une récente 1.8.8…

Que faire ?

  • Rétrograder la version de ma machine ? Bof, pas trop envie de risquer de péter mon existant.
  • Une VM ? Où ? En local ? Pfiou, ça va être long… En IaaS ? Bof.

Mais dis-donc !

Docker à la rescousse

Au final, cette manipulation m’a pris maximum 5 minutes. Le plus long a été de trouver sur Google la version du paquet debian correspond à SVN 1.6 la bonne version de Debian (pour aller au plus simple, puisqu’on pourrait aussi prendre une version plus récente et tenter d’installer une version spécifique de SVN).

Sur https://packages.debian.org/search?keywords=subversion, donc :

Paquet subversion
squeeze (oldstable) (vcs): Système de contrôle de version avancé 
1.6.12dfsg-7: amd64 armel i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 sparc
wheezy (stable) (vcs): Système de contrôle de version avancé 
1.6.17dfsg-4+deb7u6: amd64 armel armhf i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 s390x sparc
wheezy-backports (vcs): système de gestion de version évolué 
1.8.10-1~bpo70+1: amd64 armel armhf i386 ia64 kfreebsd-amd64 kfreebsd-i386 mipsel powerpc s390 s390x
jessie (testing) (vcs): système de gestion de version évolué 
1.8.10-2: amd64 arm64 armel armhf i386 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc ppc64el s390x
sid (unstable) (vcs): système de gestion de version évolué 
1.8.10-2: alpha amd64 arm64 armel armhf hppa hurd-i386 i386 kfreebsd-amd64 kfreebsd-i386 m68k mips mipsel powerpc ppc64 ppc64el s390x x32 
1.8.8-2: sparc 
1.7.13-3 [debports]: sparc64 
1.6.17dfsg-3 [debports]: sh4

OK, on va donc partir sur une version stable.

$ sudo docker run --rm -it debian:stable /bin/bash
root@d2645d786f6e:/# apt-get update
[snip]
root@d2645d786f6e:/# apt-get install subversion zip
[snip]
root@d2645d786f6e:/# svn --version
svn, version 1.6.17 (r1128011)
   compiled Mar 12 2014, 02:44:28
[snip]
root@d2645d786f6e:/# svn co -N http://svn.apache.org/repos/asf/maven/pom/trunk/asf/
A    asf/pom.xml
A    asf/site-pom.xml
 U   asf
Checked out revision 1629441]
root@d2645d786f6e:/# zip -rq asf.zip asf

Ensuite, depuis le host, dans un autre onglet de votre émulateur de terminal favori :

$ sudo docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
dbd6d39cbdb1        debian:stable       "/bin/bash"         25 minutes ago      Up 25 minutes                           sick_archimedes
$ sudo docker cp sick_archimedes:/asf.zip .
$ unzip -t asf.zip 
Archive:  asf.zip
    testing: asf/                     OK
    testing: asf/.svn/                OK
    testing: asf/.svn/dir-prop-base   OK
    testing: asf/.svn/props/          OK
    testing: asf/.svn/entries         OK
    testing: asf/.svn/all-wcprops     OK
    testing: asf/.svn/tmp/            OK
    testing: asf/.svn/tmp/props/      OK
    testing: asf/.svn/tmp/prop-base/   OK
    testing: asf/.svn/tmp/text-base/   OK
    testing: asf/.svn/prop-base/      OK
    testing: asf/.svn/prop-base/pom.xml.svn-base   OK
    testing: asf/.svn/prop-base/site-pom.xml.svn-base   OK
    testing: asf/.svn/text-base/      OK
    testing: asf/.svn/text-base/pom.xml.svn-base   OK
    testing: asf/.svn/text-base/site-pom.xml.svn-base   OK
    testing: asf/pom.xml              OK
    testing: asf/site-pom.xml         OK
No errors detected in compressed data of asf.zip.

Et voilà, en à peine quelques minutes, j’ai mon checkout, je jette mon conteneur, et je continue.

Je sais pas vous, mais moi c’est ce genre de petit exemple tout simple qui me place du côté de ceux qui disent que Docker n’est pas une simple nouveauté, mais effectivement une véritable révolution !

Atelier forge à l'AgileTour : préparez vos machines !

Michäel Pailloncy et moi allons animer un atelier lors de l’AgileTour Toulouse 2013, jeudi 10 octobre (cf. les détails de la session). Oui, c’est dans 3 jours :-).

Quelques informations complémentaires si vous prévoyez de venir à cet atelier :

  • sachez qu’il nécessite absolument un ordinateur. Si vous n’en avez pas, libre à vous de venir avec un ami qui en a un, mais ce sera probablement moins intéressant pour vous.
  • vous devrez aussi disposer d’un client Git fonctionnel (nous clonerons un dépôt local fourni sur la clé USB car nous n’aurons pas accès à Internet).
  • la machine devra posséder un JDK en version 7 installé. Nous en fournirons les binaires sur une clé USB, mais vous gagnerez beaucoup de temps si vous n’avez pas à le faire en début de TP.

Cf. aussi le dépôt GitHub suivant et son README

Si vous avez besoin de précisions, n’hésitez pas à me contacter via Twitter ou dans les commentaires de ce billet.

Merci de votre attention, faites passer le message :-).

Investir dans l'humain ?

Qu’est-ce qu’on va faire si on investit dans nos collaborateurs, et qu’ils s’en vont ?

Qu’est-ce qu’on va faire si on n’investit pas, et qu’ils restent ?…

Envie de participer à un projet opensource ? Jenkins a besoin de vous

Woui Nide You
!Jenkins est certainement le serveur d’Intégration Continue le plus utilisé dans le monde. Si vous vous intéressez de près ou de loin à l’open-source et que vous aimeriez contribuer à un projet de ce type, lisez la suite.

L’année dernière, en août, nous avons attaqué la traduction en français du Jenkins Definitive Guide, écrit en bonne partie par John Ferguson Smart. Le travail a avancé doucement, mais a avancé tout de même. A ce jour, sur la quinzaine de chapitres, trois sont traduits et relus, et presque tout le reste est en cours.

Mais je ne parle pas bien anglais…

Ce n’est pas grave. Il y a plusieurs chapitres où il faut simplement relire, et donc parler français est suffisant. Si éventuellement, vous ne comprenez pas certaines parties traduites, et qu’il faut relire l’original, vous pouvez toujours soulever la question sur la liste de diffusion du projet où on parle français.

Je ne suis pas développeur, ou je ne connais pas Git, ou les deux

si vous voulez vous former à Git, c’est l’occasion. On se fera un plaisir de répondre à vos questions sur la liste de diffusion, même si elles sont exclusivement liées à Git, et pas (encore) à la traduction :-).

Mais si vous ne le sentez pas ou n’avez pas le temps, ce n’est pas grave. Vous devez simplement savoir éditer un fichier XML. Il y en a un pour chaque chapitre.

Super ! Par où je commence alors ?

Si vous êtes intéressé, mais que vous avez des questions, surtout n’hésitez pas à les poser.

On vous attend ! :-)

Want to push your git changes, but no connection on Holiday? No worries, git bundle is here !

I’m currently writing this article offline, since I’m in a place where even phones don’t work fine. Imagine the following situation:

  • Granted, it’s the summer, but outside the weather is more suited to the frogs than to the human beings…;
  • Your laptop is sitting next to you, waiting for you to tackle this long overdue task on a dev project ;
  • You use git, but your Internet connection is between lacky and inexistent. Your only way to receive updates is to regularly take your computer to some place where the network is a bit better (so you can sync your emails, for example).

So, what you would like to do is quite simple: work offline with git (it’s one of its best forces, right?), then push a mail somewhere with your commits. To do that, you have many possibilities:

  • Zip -9 your repository and send it as attachment!
    • Ahem, mine is 400MB. Forget about it.
  • Git request-pull/am/format-patch to send mails and integrate them automatically on the other side
    • Requires too many configurations for what I want.

So what’s left? git bundle. Let’s have a look at the documentation:

git-bundle - Move objects and refs by archive

Ahem, well, not very explicit if you ask me. Let’s look at the description:

Some workflows require that one or more branches of development on one machine be replicated on another machine, but the two machines cannot be directly connected. This command provides support for git fetch and git pull to operate by packaging objects and references in an archive at the originating machine, then importing those into another repository using git fetch and git pull after moving the archive by some means (e.g., by sneakernet).

More interesting.

I’ll rephrase it: we’re going to create a special archive, containing only the commits I want, and finally send it as an attachment. People receiving this mail will be able to just pull from this archive, as from a normal repository! Sounds great, doesn’t it?

So, how to use it? Here’s my use case: I have to do some kind of code review. So I’m gonna create a new branch from the main one “develop”, I’ll call that new one reviewFeatX. Then, that‘s at least the content of this branch I’d like to be able to send.

The principle

For bundling to be efficient and interesting, it’s assumed that both repositories have a common basis. That’s quite obvious anyway: if the repository you’re working on is totally new, then you are likely to have to send it in its entirety. Sending “some commits” only makes sense when there’s in fact commits already present in both places. A Git
Tree

Thanks to git’s “everything-is-a-sha” policy + every commit has a parent, it’s quite easy for it to find the link between your work tree and another one.

Creating the archive

Looking at the picture above, what we would like to do is quite obvious: send the blue part as an archive, and not a lot more if possible. Now, how do we do that?

$ git bundle create ../reviewFeatX.gitbundle develop..reviewFeatX

Notice the “develop..reviewFeatX”: this part will be passed through the git rev-list command, which will in fact return all the hashes (sha) corresponding to the blue part above in the diagram. Now you have a reviewFeatX.gitbundle file that you can send by email, dropbox or whatever you want.

Using the archive

On the other end of the pipe, someone is hopefully going to want to retrieve commits from the file. Here’s how to do that:

  • First, you can just check if the bundle contains enough information to apply to your repository (that is: your local repository contains at least the commit basis onto which the bundle was created)
$ git bundle verify ../reviewFeatX.gitbundle
The bundle contains 1 ref
8c7feeb8d13233a466459cffc487ca08334af838 refs/heads/reviewFeatX
The bundle requires these 1 ref
6807f3ac794d72a410ac23fa8e2dc5c0bbd6c422 some log
../reviewFeatX.gitbundle is okay
  • So now, we can just apply it! To do that, just use the bundle as a remote repository.
$ git ls-remote ../reviewFeatX.gitbundle
1fd7         refs/heads/reviewFeatX

$ git fetch ../reviewFeatX.gitbundle reviewFeatX:reviewFeatX
From ../reviewFeatX.gitbundle
 * [new branch]      reviewFeatX -> reviewFeatX

$ git branch
* develop
  master
  reviewFeatX

$ git checkout reviewFeatX
Switched to branch 'reviewFeatX'

$ git log --oneline develop..reviewFeatX
1fd7 log3
df56 log2
abc1 log1

That’s it! You’ve now imported the commits from the bundle you received by mail.

As said in the introduction, you see there’s many ways to exchange commits. I hope you’ll have found this one interesting and that it will be useful to you.

Configure Hudson CI Server to automatically disable itself when main SVN repositories become unreachable

Note: I wrote this post some months ago, and just made it public since the problem making it impossible to use was fixed some weeks ago. In the meantime, you should also be aware that Hudson has recently been renamed to Jenkins, and its new house is now http://jenkins-ci.org/

Sometimes, we encounter erratic issues accessing our subversion repositories. Even apart from the server upgrade information that just dont reach the interested people, but only managers who didn’t forward (since there’re obviously not the ones that use the dev server…), we also have random problems like everyone.

The problem

When SVN becomes unreachable, every one starts receiving mails about it from Hudson… For example, last week-end I received 6000+ emails about that. So, I wrote this small script to update all our jobs to not run during both the night and the week-end.

But sure, this won’t solve everything. For example, if the server goes down during a working-day, and you’re not in front of your computer for some reason. When coming back to your box, you might discover the big amount of mails from Hudson, or even from the devs if you’re in charge of operating the CI server.

So I’ve been looking for a way to just automatically disable Hudson builds when a problem is detected.

The solution

For some days now, I’ve been playing with the Hudson script console since I discovered how greatly powerful it can be.

My starting point was the hudson command used to prepare a shutdown. How to do it through the groovy console? I gave it here in one tweet: hudson.model.Hudson.instance.doQuietDown(). Once I found this, I just had to find a way to interact with the SVN inside the groovy/hudson console system and build around it a small groovy script.

After some struggle about how to programmatically use SVNKit (Subversion pure Java API), and then how to use an anonymous class with Groovy, I was done.

Here’s the resulting script:

import hudson.model.*
import org.tmatesoft.svn.core.*
import org.tmatesoft.svn.core.wc.*

String[] repoToCheck = ['svn://svn/scle', 'svn://svn:3691/pgih']

class MyHandler implements ISVNDirEntryHandler
{
  def void handleDirEntry(SVNDirEntry dirEntry)
  {
    // nothing
  } 
}

org.tmatesoft.svn.core.internal.io.svn.SVNRepositoryFactoryImpl.setup();
Map<String, Throwable> problematicRepos = new LinkedHashMap<String, Throwable>();
for(String repo:repoToCheck)
{
  SVNURL url = SVNURL.parseURIDecoded(repo);

  SVNClientManager clientManager = SVNClientManager.newInstance();

  SVNLogClient c = clientManager.getLogClient();
  try
  {
    // Special groovy anonymous class construct
    def handler = new MyHandler()
    c.doList(url, SVNRevision.UNDEFINED, SVNRevision.HEAD, false, false, handler);
  }
  catch (Exception e)
  {
    problematicRepos.put(repo, e);
  }
}

if(!problematicRepos.isEmpty())
{
  for(Map.Entry<String, Throwable> entry:problematicRepos.entrySet())
  {
    println("Problem accessing \""+entry.getKey()+"\"");
    String s = entry.getValue();
    println(s)
  }
  println("Disabling hudson build")
  hudson.model.Hudson.instance.doQuietDown()
  return 1
}
else
{
  println("No problems with repos");
}

How to install and configure it

Install the Groovy Plugin for Hudson. This way, you’ll be able to add job directly written in Groovy. Then create a job that will run every minute! (”* * * * *”) and put the script above inside an “Execute system Groovy script”.

Then, configure the notification you like. It’s probably a good idea to target admin email when this jobs fails. That’s what I did.

Important note: there used to be a difference of behaviour with classloading between “groovy script console” and “groovy system script” in a job. This made the script above unable to work. The good news if that it was fixed with Hudson 1.352 and HUDSON-6068. So the bad news is that you can’t use this technique if you’re using an older version (time to upgrade? ;-)).

Possible improvements

Sure the script isn’t perfect, here’s a few thought of what’s currently missing:

  • At the moment, watched repositories are explicitly declared in the script. Maybe it would be more interesting to iterate through the whole list of jobs to find the actual used repositories. But I feel this approach might be a problem: if only one job is failing, maybe the team HAS to be notified. You’re not going to disable the whole hudson instance (or even cluster) for only one job failing, right?
  • About svn :
    • this is the only supported scm in the script above
    • Only the “svn” protocol is supposed to be supported. If you want to access http exposed repos, then you might have to also initialize the webdav subsystem by calling DAVRepository.setup() first.
  • Groovify the script a bit. I first wrote it in Java, and then adapted it a bit to be more groovy-like, but my experience in Groovy is only about two weeks, so please be indulgent.

Hope this helps!

Mon avis sur le livre "Apache Maven" de Nicolas De Loof et Arnaud Héritier

J’ai lu le livre Apache Maven, édité chez Pearson. Pour un premier livre en français sur Maven, on peut dire que l’expérience est globalement très réussie.

Mon expérience de maven

Disons-le tout de suite, je ne suis pas néophyte sur Maven. J’ai été utilisateur de maven 1 un tout petit peu (preuve ici :-)), avant de me plonger dans maven 2 depuis maintenant plusieurs années. Bon, ça c’est fait. J’espère que vous comprendrez que là, je veux pas me la péter hein. Je veux juste dire que nombre de concepts du livre m’étaient déjà connus. Et que, donc, mon analyse ne sera forcément pas celle d’un nouvel arrivant sur Maven.

Le style du livre

J’avoue que j’ai trouvé la lecture très agréable. C’est volontaire de la part des auteurs, et c’est réussi. Ils ont réussi à apporter beaucoup de concepts dans un style facile à lire. Ils ne sont pas tombés dans le piège de la documentation de référence, parfois un peu dure à lire, voire carrément chiante, qu’on n’ouvrirait que pour y faire un grep sur ce qu’on cherche (et ce n’est à mon sens pas le but pour un livre papier).

Le livre se lit un peu comme un roman : un petit projet débute, et rencontre les problèmes classiques du packaging qui devient une usine à gaz, et que seul celui qui l’a développé (et encore) peut lancer. Au fil de l’eau, on explique donc comment fonctionne maven (et pourquoi il a été créé), comment packager simplement, etc. Ensuite, on se rend compte que l’écriture et le lancement de tests est fastidieuse, alors on explique comment ajouter des tests, et ainsi de suite en décrivant la mise en œuvre de choses de plus en plus complexes.

La structure et le contenu du livre

“Premiers pas avec Maven”

La première partie introduit maven, d’où il arrive, qui l’a créé et pourquoi. Exemple : un projet, quel qu’il soit (et dans quelque langage que ce soit), rencontre presque toujours les trois besoins suivants lors de sa construction : préparer la construction (initialisation), compilation, puis assemblage.

Tout y est, “convention-over-configuration”, la notion de dépendance, la transitivité, les scopes, les classifiers, etc… Et tout passe comme une lettre à la poste. Vraiment, je le redis : l’exploit de Nicolas et Arnaud réside dans la capacité à nous permettre de lire le livre sans avoir l’impression de lire une documentation technique.

Comme je le disais sur twitter, je pense que ce livre est un outil formidable sur lequel s’appuyer pour préparer des sensibilisations à Maven dans vos boîtes. Mais surtout, CITEZ VOS SOURCES !!! :-)

Dans la première partie, on la jouait petit. En tant qu’utilisateur expérimenté de maven, ça m’a surtout donné envie de voir comment on pourrait déployer Selenium et FitNesse en IC chez nous.

“Maven en entreprise”

Là, on commence à ouvrir les vannes. Le projet est devenu complexe : comment gérer les dépendances proprement avec un repo manager, centraliser les informations dans un pom parent, utiliser Maven dans l’IDE.., et on arrive enfin à “mais diantre, comment on release un projet avec Maven ? On pourrait pas gérer automatiquement ces actions répétitives, rébarbatives qu’on se tape à chaque livraison, et sur lesquelles on se trompe une fois sur deux ?“.

“Encore plus loin avec Maven”

On lâche les chevaux : écriture de plugin maison, comment le tester, intégrer de l’assurance qualité (analyse de code, couverture de code), la génération des rapports et enfin on parle de Sonar, la rolls de l’analyse qualité d’un projet.

Une fois la partie “technique” terminée, Arnaud et Nicolas se livrent même à l’exercice périlleux de prédiction : Maven 3 et consorts (Encore bon pour le moment : Maven 3 à attendre plutôt pour fin 2010, d’après le livre imprimé en novembre 2009. On en est à l’alpha-7 à ce jour.).

Les reproches

Il en faut, sinon, vous allez penser que je ne suis pas objectif :-).

  • Tests d’intégration : les mettre dans le projet, ou dans un projet externe ? Le livre dit que les deux approches sont valides, mais sans creuser. J’aurais aimé davantage de retours sur le sujet. Au moins essayer de donner des pistes ou des exemples sur quelle stratégie plutôt adopter qu’une autre dans une situation en particulier. Ou même simplement l’avis d’Arnaud et de Nicolas (je suis sûr que vous en avez un :)) si aucun consensus n’existe effectivement.
  • *Problèmes d’impression en N&B* : je suppose que quelques captures ou diagrammes (exemple : p.206, un des écrans de sonar) ont dû être envoyés à l’éditeur en couleur. Le passage au noir&blanc les rend peu lisibles (essayez de différencier du bleu et du vert une fois dans des nuances de gris…). Je pense qu’il aurait fallu soit vérifier la conversion au noir&blanc, soit voir avec l’éditeur pour imprimer en couleur au moins ceux-là (je suppose que ça permet de baisser le prix de revient du livre).
  • Évolution de Maven 3 : pouvoir référencer un pom parent sans version. Le problème de la poule et de l’œuf de Maven. Cette évolution me paraît à la fois intéressante, et en même temps pose question. En effet, l’une des forces de Maven est qu’il est actuellement possible de checkouter un seul module (et non tous) et de travailler dessus. Un peu comme SVN, on peut checkouter n’importe quel niveau, et Maven s’y retrouve très bien. Je suppose que si la version parent n’est plus spécifiée, il devient impossible de checkouter de cette façon. Je pense que ce sera comme ça, mais j’aurais aimé quelques détails sur le sujet.

Mon impression générale

Dans la description de ce petit projet devenu gros, j’ai retrouvé une très grande partie des choses que nous avons faites chez nous. Je pense que certains choix n’ont pas toujours été faits immédiatement, et la lecture d’un tel livre nous aurait économisé pas mal de temps et de recherches (le release-plugin marche très bien, une fois qu’il marche. Mais il peut être difficile d’initialiser les premières releases, où il y a toujours un truc qui plante au milieu).

Petit bonus en prime : le style adopté, et la partie à la fin du livre vous donnent l’impression de connaître tout le monde, de faire un peu partie de la famille :). Maintenant on connait l’âge de tous les développeurs francophones de Maven, même celui de Vincent qui a tenté un chiffrement en héxa :-).

Globalement, donc, je recommande chaudement ce livre à toute personne qui utilise maven et qui souhaite maîtriser l’outil. Le livre offre un accès facile à toutes les facettes du projet, des plus simples au plus avancées, sans omettre le côté humain qui est si important dans les projets opensource.

Comment connaître la provenance d'une classe programmatiquement en Java

Il est possible par programmation de savoir d’où vient une classe : un jar ? un répertoire ? autre ?

Use case classique : vous pensez (et devez) ne plus avoir les commons-logging nulle part dans votre classpath, parce que vous êtes (intelligemment :-)) passés à SLF4J. Malgré cela, il semble que cette fichue classe soit toujours trouvée, mais vous n’arrivez pas à savoir dans quel jar (ou quel répertoire si vous travaillez directement avec les .class). Résultat, ça vous fout un bazar monstre dans la configuration de vos logs. Certains continuent à apparaitre alors que vous avez demandé à ce qu’ils ne soient pas affichés…

Le code est un peu sioux, alors je le mets ici au cas où ça vous servirait :

System.out.println(MaClasse.class.getProtectionDomain().getCodeSource().getLocation());

MAJ du 15/03/2010

Suite à l’incompréhension ci-dessous, voici quelques exemples pour illustrer ce que fait ce code :

Le code :

System.out.println(org.springframework.mail.MailSender.class.getProtectionDomain().getCodeSource().getLocation());
System.out.println(MyJunitTest.class.getProtectionDomain().getCodeSource().getLocation());

Affiche sous Windows :

file:/C:/m2repository/org/springframework/spring-context-support/2.5.6/spring-context-support-2.5.6.jar
file:/C:/tests/myproject-core/target/test-classes/

J’espère que l’utilité est un peu plus claire à présent.

Page 1 of 32 Older