lundi 20 juin 2011

ant, j2ee et le complot militariste


$>ant -p
Main targets:

clean Cleans the project
make-war Creates a WAR
...
Default target: make-war
$>vi build.xml
$>ant -p
Main targets:

clean Cleans the project
make-love Creates a WAR but make love, not war !
...
Default target: make-love
$>



C'est au moins ça qu'ils n'auront pas !!!

mercredi 11 mai 2011

La foule est en délire

Ca y est ! C'est officiellement le début de la gloire. J'ai enfin atteint mon but ultime dans la vie : être cité sur un blog russe que personne ne lit.

Merci à datacompboy !

Plus sérieusement, merci à lui pour son player audio flash GPL qui a le bon goût de supporter la plupart des formats téléphoniques et qui m'a presque sauvé la vie : WavPlayer.

Si vous avez besoin de jouer des sons au format téléphonique sur une page web, c'est probablement votre meilleur chance : WavPlayer

mardi 10 mai 2011

soap-dust 0.1

Oh ! le gros événement !

Je viens de releaser la nouvelle version 0.1 de soap-dust qui intègre un tout nouveau tout beau parser wsdl/xsd.

Les plus grosses nouveautés :

Un nouveau parser qui augmente énormément les performances au moment de l'analyse du wsdl (jusqu'à un facteur 15 lors de l'analyse du wsdl de Jira, par exemple).

Quelques retouches pour permettre à soap-dust de tourner sur Android.

Vous développez en Java, vous devez vous interfacer avec cette grosse m.... de web-service soap développé par un stagiaire et imposé par votre client... ne sautez pas tout de suite ! refermez la fenêtre, la vie peut encore vous sourire : utilisez soap-dust !

vendredi 18 mars 2011

Tests unitaires, HTTP et Java

S'il vous est déjà arrivé d'écrire du code qui effectue des requêtes http, alors il vous est arrivé d'écrire des tests automatisés pour tester ce code (mais si, voyons !).

Mais alors comment faites-vous ?

Dans le cas d'un développement en Java (mais pas seulement), une solution est d'introduire, dans la classe testée, des méthodes non privées qui font effectivement les appels HTTP puis, dans les tests, de truquer ces méthodes (d'où la nécessité qu'elles ne soient pas privées) de façon à simuler différents retours du serveur web ou vérifier ce que votre code tente de transmettre au serveur.

C'est ce que je faisais dans les tests de soap-dust mais sans être vraiment satisfait de mon code.

Finalement j'ai choisi une méthode qui me parait plus élégante.

J'ai définit des urls au format test: qui simulent des urls http:. Dans mes tests, je configure le code que je veux tester pour qu'il utiliser des urls test: plutôt que des urls http:.

Dans une url test:, je suis directement capable de définir le statut HTTP lorsqu'on requête cette url, de même que les données qu'on obtient. Cerise sur le gâteau, à la fin du test, je peux récupérer les données qu'un client aurait tenté de transmettre à un serveur via cette url.

Exemple :


HttpURLConnection connection = (HttpURLConnection) new URL("test:status:500").openConnection();
assertEquals(500, connection.getResponseCode());

HttpURLConnection connection = (HttpURLConnection) new URL("test:status:200;file:hello.txt").openConnection();
assertStreamContent("Hello World !", connection.getInputStream);

byte[] written = new byte[] {1, 2, 3, 4};
HttpURLConnection connection = (HttpURLConnection) new URL("test:").openConnection();
OutputStream out = connection.getOutputStream();
out.write(written);
out.flush();
out.close();
assertTrue(Arrays.equals(written, Handler.saved.get("test:").toByteArray()));


Pour que les URLs test: soient reconnues par la jvm, il suffit de créer un classe test.Handler dans le package de votre choix puis de déclarer ce nouvel handler dans la jvm. Par exemple dans le cas des tests de soap-dust :


String handlers = System.getProperty("java.protocol.handler.pkgs");
if (handlers == null) handlers = "";
handlers += "|soapdust.urlhandler";
System.setProperty("java.protocol.handler.pkgs", handlers);


Grâce à cela, j'ai pu à nouveau rendre privée les méthodes que j'avais exposée uniquement pour les tests et ainsi j'ai eu plus de liberté dans la réorganisation de mon code.

Pour plus de détails, consultez :


Ce gestionnaire d'url test: est en version alpha et livré avec soap-dust.

mardi 22 février 2011

Utiliser deux dispositions différentes de clavier simultanément

J'utilise un clavier avec disposition Dvorak. J'ai toujours un clavier avec disposition azerty branché sur ma machine pour les copains.

Un jour j'en ai eu assez de devoir faire une manipulation pour changer la disposition système du clavier à chaque fois que je tapais sur l'un ou l'autre des claviers.

J'ai fini par trouver une solution qui fonctionne sur une Ubuntu squeeze/sid pour que, lorsqu'on tape sur le clavier Dvorak, on utilise une disposition Dvorak et pour que, lorsqu'on tape sur le clavier azerty, on utilise une disposition azerty... le tout sans aucune manipulation.

Le principe est de définir des règles udev qui vont positionner le layout de chaque clavier séparément. Il faut donc pouvoir distinguer chacun de ces claviers. Pour cela j'utilise le couple vendor-id:product-id. Dans mon cas, j'ai :
  • un clavier USB Dell azerty avec vendor-id:product-id qui vaut 413c:2003 ;

  • un clavier USB TypeMatrix Dvorak avec vendor-id:product-id qui vaut ffff:8081.
Je veux que le clavier azerty ait un layout azerty et le clavier Dvorak un layout us_intl (oui, je sais, c'est bizarre mais c'est comme ça). Pour cela, je crée le fichier /etc/udev/rules.d/99-keyboards.rules avec le contenu suivant :


SUBSYSTEMS=="input",ACTION=="add",ENV{ID_VENDOR_ID}=="413c",ENV{ID_MODEL_ID}=="2003", RUN+="/usr/bin/logger configuring Dell keyboard"
SUBSYSTEMS=="input",ACTION=="add",ENV{ID_VENDOR_ID}=="413c",ENV{ID_MODEL_ID}=="2003", ENV{XKBLAYOUT}="fr"
SUBSYSTEMS=="input",ACTION=="add",ENV{ID_VENDOR_ID}=="413c",ENV{ID_MODEL_ID}=="2003", ENV{XKBVARIANT}="oss"
SUBSYSTEMS=="input",ACTION=="add",ENV{ID_VENDOR_ID}=="413c",ENV{ID_MODEL_ID}=="2003", ENV{XKBOPTIONS}=""

SUBSYSTEMS=="input",ACTION=="add",ENV{ID_VENDOR_ID}=="ffff",ENV{ID_MODEL_ID}=="8081", RUN+="/usr/bin/logger configuring TypeMatrix keyboard"
SUBSYSTEMS=="input",ACTION=="add",ENV{ID_VENDOR_ID}=="ffff",ENV{ID_MODEL_ID}=="8081", ENV{XKBLAYOUT}="us"
SUBSYSTEMS=="input",ACTION=="add",ENV{ID_VENDOR_ID}=="ffff",ENV{ID_MODEL_ID}=="8081", ENV{XKBVARIANT}="intl"
SUBSYSTEMS=="input",ACTION=="add",ENV{ID_VENDOR_ID}=="ffff",ENV{ID_MODEL_ID}=="8081", ENV{XKBOPTIONS}=""


Et hop ! Lorsque je branche mes deux claviers, le layout adéquate s'applique à chacun d'eux. Si je tape sur le clavier azerty, la touche 'a' écrit 'a'. Idem lorsque je tape sur mon clavier Dvorak :)

Si vous utilisez gnome, vous devez désactiver la gestion du clavier par gnome pour que cela fonctionne. Pour cela, lancez la commande gconf-editor et désactivez la clé /apps/gnome_settings_daemon/plugins/keyboard. Déconnectez-vous et reconnectez-vous pour que cela soit pris en compte.

Un bêmol : je ne sais pas pourquoi mais lorsque je redémarre ma machine ou lorsque je me déconnecte, je dois parfois débrancher puis rebrancher un clavier pour qu'il utilise la bonne disposition... si quelqu'un a la solution à ce problème, je suis preneur :)

Si vous ne connaissez pas le vendor-id:product-id de chacun de vos claviers, vous pouvez le découvrir avec la commande lsusb. Par exemple dans mon cas cette commande m'affiche :


$> lsusb
Bus 008 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
...
Bus 007 Device 002: ID 046d:c00e Logitech, Inc. M-BJ58/M-BJ69 Optical Wheel Mouse
Bus 004 Device 004: ID 413c:2003 Dell Computer Corp. Keyboard
Bus 002 Device 004: ID ffff:8081
Bus 002 Device 003: ID 0424:2514 Standard Microsystems Corp. USB 2.0 Hub
...


Cela me permet de déduire que mon clavier Dell est identifié par le couple vendor-id:product-id 413c:2003 et que mon clavier TypeMatrix est identifié par le couple ffff:8081 (oui, d'accord, celui-ci est plus difficile à reconnaitre mais j'ai quand même fini par deviner).

Merci à

jeudi 20 janvier 2011

Méthodes d'entrainement au développement

C'est le titre d'une séance à laquelle j'ai participé ce matin à l'Agile Open France.

Je retranscrit ici de manière brute la liste des méthodes que nous avons énumérées.

Participer activement à un projet (open-source ou pas)
  • c'est en forgeant qu'on devient forgeron
  • c'est ça l'entrainement ?
Répéter un micro-projet from scratch
  • refaire la même chose encore et encore
  • fonctionnel trivial
  • contraintes à respecter
  • exemple : application web de gestion de TODO-list avec mise en place du dépôt svn, génération des livrables, tests, ...
Lire un livre et faire les exercices
  • exemple : video store dans le livre Refactoring de M. Fowler
Faire des petites modifications souvent sur une variété de projets
  • s'habituer à toucher du code
  • apprentissage par comparaison / essayage de code
Binômage
  • découverte, avec le temps, des compétences de l'autre
  • apprentissage par surprise (Pierre ne pensait pas que ça pouvait intéresser quelqu'un, Paul ne pensait pas qu'il apprendrait cela)
Randori
  • on tourne toutes le 5/7 minutes
  • on travail en binôme et c'est tout le binôme qui change à chaque tour
  • on travail en binôme et c'est la moitié du binôme qui change à chaque tour
  • on travail en solitaire et on change d'individu à chaque tour
  • celui/ceux qui (fait/font) programme(nt) à voix haute
  • les autres esssayent de ne pas troubler ceux qui font
  • apprentissage dans un groupe hétérogène
  • limiter les ambitions de l'exercice
  • au moins un participant devrait avoir déchiffré le sujet
Arret sur image
  • décrire pourquoi je fais les choses dans le détail, y compris les choses triviales
  • pourquoi est-ce que j'aligne les paramètres ?
  • pourquoi est-ce que j'ajoute un saut de ligne ?
  • outil de transmission pédagogique
(auto-)screencast
  • s'enregistrer en train de faire quelque chose
  • se regarder
  • effet de la répétition
  • le screencast montre tout ce que ton binôme n'ose pas te dire
Challenges
  • tirer au sort des exercices/défis écris par les participants
  • tenter de les faire/résoudre
  • divertissant
Project EulerLien
  • résoudre les problèmes d'Euler
  • consulter les programmes des autres
  • il faut résoudre le problème pour pouvoir lire les solutions des autres
Pleac
  • refaire le perl cookbook dans d'autres langages
Kata
  • refaire en un temps limité un exercice précis
  • avancement étape par étape et description de ce qu'on fait
  • screencast en live
  • travail de préparation
Apprendre de nouveaux langagesLien
  • ce que j'apprend dans un langage m'apprend des choses sur ce que je fais dans un autre langage
  • apprendre un langage par an
  • seven languages in seven weeks ?

dimanche 9 janvier 2011

Conférence téléphonique pour les pauvres


Là où je travail, on a les moyen de s'offrir des conférences téléphoniques régulièrement. C'est tellement bien que je me suis dit qu'il fallait aussi penser aux autres, à ceux qui n'ont pas accès à cette technologie.

Pour eux, j'ai pensé au kit conf-call low tech : quelques bandeaux pour les yeux, de la corde pour s'attacher les mains dans le dos et des baillons pour ceux qui ne sont pas là pour parler et hop ! Le tour est joué. Tous les bénéfices de la conférence téléphonique pour pas un rond !