jeudi 21 octobre 2010

Les génériques java et EasyMock

Parfois nous devons exécuter un traitement et si le résultat est null nous voulons renvoyer un résultat par défaut. par exemple une liste vide. cela permet d'éviter les NullPointerExceptions si nous parcourons la liste. Exemple :

List<Contact> contacts = getContacts();
for (Contact contact : contacts){
      contact.setActive(true);
}

Si getContacts() renvoie null le code renverra une NullPointerException. il est possible avec les génériques Java de le faire d'une manière élégante :

 public static <T> T notNull(T test, T defaultvalue){
    return t == null ? test : defaultValue;
  }

On peut alors écrire :

List<Contact> contacts = notNull(getContacts(),new ArrayList<Contact>);

Ce code n'est pas révolutionnaire mais il montre à quel point les génériques de de Java peuvent être utiles. C'est d'ailleurs de cette manière que EasyMock fonctionne. Lorsque vous écrivez

Myclass mock = EasyMock.createMock(MyClass.class);
EasyMock.expect(mock.function()).andReturn(value);

Le type de value est déterminé en générique Java par le retour de function() :

 public <O> O expect(O t) {
        return t;
    }

lundi 1 mars 2010

Détecter et corriger les fuites mémoire java

Ceux qui ont déjà développé en C, puis en Java auront probablement apprécié la gestion de la mémoire par la JVM. En effet, Java masque la complexité de la gestion de la mémoire aux développeurs. Cette tache est déléguée au garbage Collector. Cependant même si cette gestion est dite 'automatique', cela ne permet pas de faire n'importe quoi. Que ce soit en C, Java, ou un autre langage, la mémoire est une ressource limitée ! En java lorsque la JVM n'a plus assez de mémoire pour s'exécuter, elle génère une Erreur java.lang.OutOfMemoryError.

Plusieurs cas sont alors possible :

  • Soit vous n'avez pas alloué assez de mémoire à la JVM
  • Soit votre code a ce qu'on appelle un fuite mémoire

Si vous êtes dans le premier cas, les choses se résolvent assez facilement : il vous suffit d'allouer plus de mémoire grâce aux paramètres -Xmx, -Xms et -XX:PermSize (ou de modifier le code pour qu'il gaspille moins de mémoire). Dans le deuxième cas vous allez devoir trouver où se situe la fuite mémoire. Si vous avez utilisé des logiciels pour vous y aider, vous avez peut être été perdu par toutes les possibilités qu'ils offrent et par la profusion d'informations qu'il fournissent.

Le but de ce billet est d'expliquer comment détecter et corriger les fuites mémoires avec Eclipse Memory Analyser Tool un outil gratuit et très utile qui aide vraiment à trouver les fuites mémoires. Nous allons voir comment extraire les informations pertinentes, les comprendre, et trouver les responsables des fuites mémoire en ayant une approche pragmatique. Je vous propose de nous appuyer sur du code simple (disponible en fichier attaché à ce billet) générant une fuite mémoire.

Lire la suite...

lundi 7 décembre 2009

Untar en java

Autant trouver un bout de code pour de-zipper un fichier est assez facile, autant en trouver un pour de-tarrer est déjà un peu plus complexe. Ayant eu à le coder, Je vous propose (ça évitera peut être des galères à certains ;) ) une classe qui permet de le faire. Elle permet de décompresser les fichiers tar, tar.gzip, tar.gz, tar.bz2, et tar.bzip2, le choix du traitement se fait selon l'extension.

Lire la suite...

lundi 23 novembre 2009

Retenter l'execution d'une fonction plusieurs fois en Java

Certains d'entre vous connaissent peut être la fonction javascript Try.these de Prototype.

Elle permet d'exécuter plusieurs fonctions et de retourner la valeur de la première fonction qui ne génère pas d'exception. Cela permet d'essayer plusieurs façons de faire, mais aussi de retenter l'exécution d'une fonction, si on lui passe plusieurs fois la même fonction.

Je vous propose un code qui permet de faire l'équivalent en java. Pour cela J'ai utilisé le patron de conception 'template' et les génériques Java 5. J'ai eu besoin de coder cela afin d'être plus tolérant aux erreurs (retenter plusieurs fois une requête HTTP qui pouvait aboutir à un timeout serveur). Je vous conseille de restreindre le catch de la fonction retry() afin de de ne retenter l'exécution, uniquement pour une exception donnée et de propager les autres exceptions le cas échéant.

Lire la suite...

jeudi 19 novembre 2009

Faire des tests combinatoires avec les theories JUnit (partie2)

Lors du précédent post je vous parlais des Theories. Aujourd'hui je vous propose d'aller un peu plus loin dans la définition du jeu de données en faisant de la combinatoire et en définissant un jeu de données dynamiquement.

Lire la suite...

mardi 17 novembre 2009

Faire des tests combinatoires avec les theories JUnit

Il arrive parfois que l'on ait à faire des tests avec des jeux de données combinatoires. Par exemple, on a un jeu de données A : disons {A1,A2}, et un jeu de données B : {B1,B2}, et on voudrait faire un test où toutes les combinaisons A * B soit testées :

  • testMethode(A1,B1)
  • testMethode(A1,B2)
  • testMethode(A2,B1)
  • testMethode(A2,B2)

Il est possible dans ce cas d'utiliser les theories. Il s'agit d'une technique, pour l'instant expérimentale (cf : nom du package), disponible à partir de JUnit 4.4.

Lire la suite...