Freelances JEE

Revues de code I

Au cours de mes revues de code, je tombe sur des problèmes plus ou moins réguliers.  Outre les problèmes de designs, certains aspects techniques sont récurrents.

Comparaison avec == sur des java.lang.Integer

Le problème, c’est que sur des integers entre -128 et 127, cela peut marcher.  Dans la suite de l’exemple, integer1 et integer2 seront de type java.lang.Integer, int1 sera de type primitif int.

        Integer integer1 = 127;
        Integer integer2 = 127;
        System.out.println(integer1 == integer2); // true

        integer1 = 128;
        integer2 = 128;
        System.out.println(integer1 == integer2); // false

Par contre, on a bien pour toutes les valeurs, y compris celles entre -128 et 127 :

integer1 = new Integer(127);
integer2 = new Integer(127);
System.out.println(integer1 == integer2); // false - normal on a instancié 2 objects différents

integer1 = new Integer(129);
int1 = 129;
System.out.println(integer1 == integer2); // true

Si on regarde la doc de Sun, pour tous les objets entre -128 et 127, l’autoboxing garantit que l’objet renvoyé Integer sera identique pour un même entier primitif. Ce qui ne sera pas le cas au delà de l’intervalle. De plus, rien ne garantit qu’une implémentation étende l’intervalle de cache, raison pour laquelle il est risqué de se baser dessus.
Byte,  Short,  Long ont également le même type de cache. Character a également un cache mais de 0 à 127 (un nombre négatif n’aurait pas eu de sens).

d. Autoboxing is guaranteed to return the same object for integral
values in the range [-128, 127], but an implementation may, at its
discretion, cache values outside of that range. It would be bad style

http://java.sun.com/developer/JDCTechTips/2005/tt0405.html#1

Ainsi, utiliser == en se fiant à l’autoboxing et au cache est une mauvaise pratique, même pour comparer des constantes de faible valeur.

Utiliser plutôt valueOf()  plutôt que new

Il est préferable d’utiliser un valueOf plutôt qu’une nouvelle instanciation à l’aide du constructeur. Valable pour la certains objets immutables.

Exemple avec des types java.lang.Integer, si on regarde la javadoc pour la méthode Integer.valueOf(int i) :

public static Integer valueOf(int i)
Returns a Integer instance representing the specified int value. If a new Integer instance is not required, this method should generally be used in preference to the constructor Integer(int), as this method is likely to yield significantly better space and time performance by caching frequently requested values.

Idem pour les Byte, Long, Character, BigInteger … Par contre, préférer quand c’est possible de construire les valeurs accessibles directement via une méthode statique (BigInteger.ONE plutôt que BigInteger.valueOf(1), Boolean.FALSE plutôt que Boolean.valueOf(false) …)

Éviter d’utiliser new String

String test1 = "abc";
String test2 = "abc";
String test3 = new String("abc");
String test4 = new String("abc");

System.out.println(test1 == test2); // true
System.out.println(test1 == test3); //false
System.out.println(test3 == test4); //false

Utiliser new String implique de créer un nouvel object en mémoire. Les String étant immutables, avoir 2 objets différents ayant la même valeur ne fait que consommer de la mémoire. Attention à bien noter le cas 2, “abc” est différent de new String(”abc”).  Cet exemple permet également de montrer l’importance d’utiliser la méthode equals pour comparer les valeurs des objets java.lang.String .

Comme précisé par Jérôme et Nicolas Le Coz en commentaire, l’instanciation d’un nouvel objet String est conseillée lors de l’utilisation de substring sur des très grandes chaînes de caractères. En effet, la valeur stockée avec un substring n’est pas uniquement la substring, mais la chaîne entière avec un offset (premier caractère à utiliser) et un compteur (nombre de caractères à utiliser).

C’est clair si l’on regarde la classe java.lang.String

  public final class String
  	implements java.io.Serializable, Comparable, CharSequence
  {
  /** The value is used for character storage. */
  private final char value[];

  /** The offset is the first index of the storage that is used. */
  private final int offset;

  /** The count is the number of characters in the String. */
  private final int count;
[...]
public String substring(int beginIndex, int endIndex) {
 [...]
 return ((beginIndex == 0) && (endIndex == count)) ? this :
 new String(offset + beginIndex, endIndex - beginIndex, value);
 }

Plus d’infos ici http://blog.xebia.fr/2009/08/03/revue-de-presse-xebia-120/#AttentionvotremmoireavecString et dans les autres liens en commentaires.

Se méfier de la construction des BigDecimal.

On utilise ici 3 manières de faire pour créer un BigDecimal que l’on souhaite égal à 4.12.  Néanmoins, les résultats ne sont pas conformes à ce qu’on pourrait en attendre.

Double myDouble = 4.12D;

BigDecimal bd1 = new BigDecimal(myDouble);
BigDecimal bd2 = new BigDecimal(String.valueOf(myDouble));
BigDecimal bd3 = BigDecimal.valueOf(myDouble);

System.out.println(bd1.equals(bd2));  // false !
System.out.println(bd1.equals(bd3)); // false !
System.out.println(bd2.equals(bd3));  // true

Il n’y a donc pas égalité de valeur entre l’object construit à partir du double et les 2 autres objets. En effet, si on affiche les différentes valeurs des 3 BigDecimal, le problème est facilement visible :

RESULT 1: 4.12000000000000010658141036401502788066864013671875
RESULT 2: 4.12
RESULT 3: 4.12

Il vaut mieux donc éviter d’utiliser le constructeur BigDecimal(double double) et de lui préférer les deux autres méthodes.

public BigDecimal(double val)
Translates a double into a BigDecimal which is the exact decimal representation of the double’s binary floating-point value. The scale of the returned BigDecimal is the smallest value such that (10scale × val) is an integer.Notes:

  1. The results of this constructor can be somewhat unpredictable. One might assume that writing new BigDecimal(0.1) in Java creates a BigDecimal which is exactly equal to 0.1 (an unscaled value of 1, with a scale of 1), but it is actually equal to 0.1000000000000000055511151231257827021181583404541015625. This is because 0.1 cannot be represented exactly as a double (or, for that matter, as a binary fraction of any finite length). Thus, the value that is being passed in to the constructor is not exactly equal to 0.1, appearances notwithstanding.
  2. The String constructor, on the other hand, is perfectly predictable: writing new BigDecimal("0.1") creates a BigDecimal which is exactly equal to 0.1, as one would expect. Therefore, it is generally recommended that the String constructor be used in preference to this one.
  3. When a double must be used as a source for a BigDecimal, note that this constructor provides an exact conversion; it does not give the same result as converting the double to a String using the Double.toString(double) method and then using the BigDecimal(String) constructor. To get that result, use the static valueOf(double) method.

4193293024_eef35683c7_oIl n’y a pas à dire, Février est un mois chargé vu l’ensemble des conférences et rencontres qui nous sont proposées gratuitement autour de Java et du Web.

MAJ :  la date de l’évènement Clojure a été avancée au 8 février !

Ajout événement noSQL 17 février

Le KawaCampParis1 - 3 février - Décalé en mars

Les BarCamp sont des rencontres, non formelles sous forme d’ateliers-événements participatifs ou simplement de discussions libres autour d’un thème. Chacun arrive avec son propre contenu.  Comme lors des JavaCamps les participants finissaient la plupart du temps par parler d’autres choses que Java, l’idée d’un KawaCamp, plus large, a germé :) Les sujets seront donc nombreux, de NoSQL à Groovy en passant par les technos Google, sans oublier  HTML5, les frameworks Javascript etc ..

Site web : http://barcamp.org/KawaCampParis1
Wave publique : with:public KawaCampParis1

Clojure : Vers l’essence de la programmation - 8 février

Clojure est un langage fonctionnel apparu en 2007 de type Lisp et tournant sur la JVM. Howard Lewis Ship , créateur de Tapestry, présentera le langage, ses atouts ainsi que les concepts fondamentaux de la programmation fonctionnelle.

Site web : http://www.zenika.com/conference/web_ria/clojure-essence-de-programmation-par-howard-lewis-ship

2ème Anniversaire du Paris Jug - 9 février

Le Paris JUG fête ses deux ans en grand ! Un amphi de 500 places nous accueillera entre 18h45 et 19h (donc 30 minutes plus tôt que d’habitude) sur le sujet de l’open-source en France. Au moins 6 présentations sur des thèmes variés :

  • Keynote de Sacha Labourey
  • Obeo : exemple d’un éditeur d’outils de développements Open Source ayant réussi à se développer
  • Les licences permettant la diffusion libre de la documentation
  • Le framework Play!
  • jCaptcha
  • jax-doclet , permettant de génèrer de la JavaDoc à partir des des commentaires JavaDoc et des annotations de manières spécifiques (notamment pour JAX-RS et JAXB)

Et toujours suivi d’une 3ème mi-temps pour des discussions plus informelles mais tout aussi intéressantes !

Comme au mois de Décembre, la salle est à la faculté de la Sorbonne : http://www.parisjug.org/xwiki/bin/view/Location/SorbonneParisIV

Site web : http://www.parisjug.org/xwiki/bin/view/Meeting/20100209

Les secrets de la concurrence Java - 11 février

Heinz Kabuts est un des premiers Java Champion. Il publie régulièrement une newsletter très pointue sur Java et la JVM sur http://www.javaspecialists.eu/ suivie par approximativement 30 000 développeurs Java. Il abordera au cours de cette soirée 10 lois pour nous apprendre à mieux gérer le multi-threading.

Site web : http://www.zenika.com/conference/java/secret-de-la-concurrence-java-par-heinz-kabutz

Domain Driven Design : Les modèles en action - 17 février

Eric Evans est de retour à Paris. Auteur de Domain-Driven Design, il  présentera les différents modèles (comment les choisir, les faire cohabiter …). Cette conférence s’adresse plutôt aux développeurs expérimentés.

Site web : http://www.zenika.com/conference/architecture/domain-driven-design-par-Eric-Evans

Deuxième rencontre noSQL - 16 février

Les sujets de cette deuxième conférence sont “noSQL for Fun and Profit” et Redis.

Site web http://sites.google.com/a/octo.com/nosql/project-updates/usergroupparis-round2

Création du Spring User Group - 25 février

La première conférence du Spring User Group balayera les différentes nouveautés de la version 3.0 de Spring par Arnaud Cogoluègnes. La migration vers Spring 3.0, les nouveautés (Spring Expression Language, Support Rest) ainsi que le rapport avec Java EE seront abordés.

Site web http://groups.google.fr/group/sugfr/web/evnements

Src image :  Iulian Nistea

Premiers pas avec Scala

Je suis tombé amoureux de Scala. Et je suis fier de vous présenter mes premières lignes de code en Scala :

import java.io._

class Reader(dir: String) {

	// Concatène les contenus de n fichiers dans une liste
	def readAll() = {

		// Mets toutes les lignes d'un fichier dans une liste
		def readLines (name : String) = {

			// Mets toutes les lignes d'un bufferedReader dans une liste
			def read(buf : BufferedReader, acc : List[String] ) : List[String] = buf.readLine match {
				case null => acc
				case s => read(buf, s::acc)  // Appel recursif optimisé par Scala
			}

			// Compose le nom complet du fichier et appel read
			read(new BufferedReader(new FileReader(dir + "/" + name)), Nil).reverse
		}

		// Applique readLine sur tous les fichiers et renvoi la concaténation des listes
		// Pas de return : En scala c'est la derniere expression qui fait office de retour
		new File(dir).list.flatMap(readLines)
	}
}

13 lignes de code, pour lire tous les fichiers d’un répertoire puis concaténer l’ensemble des lignes dans une liste chaîné.

Une compatibilité à 100% avec Java

Ce qui n’est pas une surprise, car Scala est compilé en ByteCode.

Cela se traduit par la possibilité d’importer  n’importe quelle classe pourvu qu’elle soit dans le classpath :

import java.io._

Et d’appeler des méthodes Java dans le code Scala :

buf.readLine
new BufferedReader(new FileReader(dir + "/" + name))

Et même d’utiliser très simplement un framework comme JUnit :

import org.junit.Test

class ReaderTest() {
  @Test
  def unTest() : Unit = {
    val read = new Reader("src/test/resources/cotations")
    read.readAll().map((x) =>println(x));
  }
}

Oui je sais, ce test n’est pas un test, c’est juste un exemple :)

Chaque méthode que j’ai écrite ne fait qu’un seul traitement. Cela les rends faciles à comprendre, à maintenir et à tester. La programmation fonctionnelle n’étant pas “impérative”, il est de toute façon très difficile d’écrire une méthode sur 1000 lignes alors qu’il est malheureusement très fréquent d’en trouver dans du code Java…

Pas de boucle

En programmation fonctionnelle il est tout à fait possible, et même conseillé de ne pas utiliser de boucle. La façon de penser et de concevoir son programme n’est plus la même. C’est je  pense, la principale raison qui rend les langages fonctionnel “obscurs” pour un développeur impératif.

En programmation impérative, on pense “enchaînements d’instructions”, c’est un peu comme écrire une recette de cuisine : faire ci, puis ça, puis ça.

En programmation fonctionnelle on s’attache au “comment”. Comment transformer tel fichier en liste et tel liste en table de base de données. C’est le principe d’une fonction : transformer une entrée en “autre chose”. Les éléments impératifs, comme les boucles ne sont utiles que dans un langage impératif (encore que..).

On utilisera plutôt la récursion :

			def read(buf : BufferedReader, acc : List[String] ) : List[String] = buf.readLine match {
				case null => acc
				case s => read(buf, s::acc)  // Appel recursif optimisé par Scala
			}

			// Compose le nom complet du fichier et appel read
			read(new BufferedReader(new FileReader(dir + "/" + name)), Nil).reverse

Notez qu’il ne se produira pas de StackOverflowError car ce code récursif est traduit par une boucle. Oui ne riez pas, c’est vrai. Un code récursif identique en java produira un beau StackOverflowError lorsque les fichiers dépasseront un certain nombre de lignes.

Scala a quand même une petite faiblesse, il n’optimisera que si l’appel récursif est direct. Une pile {read, read, read, read, read} sera optimisée alors qu’une pile {read2, read1, read2, read1} ne le sera pas. Ce qui nous empêche d’écrire ce code qui aurait été plus élégant :

def read(buf : BufferedReader) : List[String] = buf.readLine match {
      case null => Nil
       case s => s::read(buf)  // Appel recursif
}

  // Compose le nom complet du fichier et appel read
  read(new BufferedReader(new FileReader(dir + "/" + name)))

La stack ici est {read, ::, read, ::, read, ..} “::” est la fonction d’ajout d’élément à une liste en Scala !

En fait, Java nous interdit carrément d’utiliser la récursion sur une trop grande profondeur, ce qui est clairement une énorme lacune du compilateur Java, qui pourrait très bien optimiser les fonctions récursives pour éviter les stackOverflow. Scala à une longueur d’avance sur ce point. Ceci dit je pense que cela donnera des idées pour Java7.

Cette traduction en Java ne sera pas optimisée malgré une pile d’appel optimisable :

private List readLines(final BufferedReader buf, final List acc) {
		String line;
		try {
			line = buf.readLine();
			if (line != null) {
				acc.add(line);
				return readLines(buf, acc);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}

		return acc;
	}

Voici une autre façon de ne pas utiliser de boucle :

// flatMap est une méthode native.
new File(dir).list.flatMap(readLines)

Ici on créé un objet java.io.File, on appel la fonction list() puis on appel la fonction readLines sur chacun des fichiers.

La méthode “map” applique la méthode readLines à tous éléments de la liste et retourne cette nouvelle liste. On effectue donc bien un mapping d’une liste de valeurs vers une nouvelle liste de valeurs : List<FileName> => List<ContenuDuFichierFileName>. Le tout, sans boucle !

La méthode flatMap() diffère de la méthode map() car au lieu de renvoyer une List<List<String>> (ReadLines renvoie une List<String>, elle va “aplanir” (ou concaténer) les listes, ce qui donnera une simple List<String> contenant toutes les lignes de tous les fichiers situés dans le répertoire “dir”.

Alors en vérité, et je pense que c’est une lacune du langage Scala, il existe un mot clé “for” qui permet d’écrire certaine ligne de mon code d’une autre manière faisant grandement penser à une boucle “for” Java… mais sans l’être.. bref, je conseil d’éviter cette écriture, Scala étant déjà assez difficile à appréhender pour un programmeur impératif, inutile d’ajouter de la confusion en codant un truc ressemblant à de l’impératif..

Et pas de variable

Scala encourage l’utilisation d’objet immutable. C’est à dire avec un état fixe, sans setters par exemple. Je vous renvoie à la lecture de l’excellent livre “Effective Java” pour en savoir plus sur les avantages de l’immutabilité en Java, et donc a fortiori en Scala. Et bien entendu il beaucoup plus simple de faire de l’immutable en Scala qu’en Java !

Scala permet de différencier très clairement les valeurs des variables via les mots clé “val” et “var”. “val s : MyObject ” est l’équivalent de “final MyObject o;” alors que “var s : MyObject ” sera l’équivalent de “MyObject o;” En Scala les paramètres des fonctions sont des “val”. Un objet immutable sera forcément une valeur.

Il est donc tout à fait possible et même conseillé de ne jamais utiliser de variables. En fait, lorsqu’on aura besoin d’un objet avec état changeant on utilisera le pattern “Actor”, dont Scala fourni le support et qui permet d’avoir des objets mutables “sans risques”.

Développer avec le Bloc-notes : Facile !

Le gros défaut de Scala, c’est qu’il n’existe pas d’IDE aussi avancé que pour Java. Ceci dit, je n’ai pas du tout souffert de ce manque. J’utilise le plugin eclipse fourni sur le site officiel, qui permet l’auto complétion et rajoute de la couleur et honnêtement, ça suffit largement. C’est à se demander si une grosse partie de l’outillage nécessaire en Java n’était finalement pas lié aux lacunes de Java !

Pour comparer voici les 2 codes Java et Scala mis côte à côte. J’ai essayé de réduire au maximum le code Java ! On remarquera qu’en Java, j’ai été obligé d’avoir une variable non final.

import java.io.*;
import java.util.*;

public class Reader {

	private final String directory;

	public Reader(final String dir) {
		this.directory = dir;
	}

	public final List<String> readAll() {
		final String[] fileNames = new File(directory).list();
		final List<String> ret = new LinkedList<String>();

		for (String name : fileNames) {
			try {
				BufferedReader buf = new BufferedReader(new FileReader(directory + "/" + name));
				String line = buf.readLine();
				while (line != null) {
					ret.add(line);
				}
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		return ret;
	}
}

No comment :

import java.io._

class Reader(dir: String) {
    def readAll() = {

        def readLines (name : String) = {

            def read(buf : BufferedReader, acc : List[String] ) : List[String] = buf.readLine match {
                case null => acc
                case s => read(buf, s::acc)
            }

            read(new BufferedReader(new FileReader(dir + "/" + name)), Nil).reverse
        }

        new File(dir).list.flatMap(readLines)
    }
}

Réactiver votre cerveau

Apprendre un nouveau langage, c’est apprendre à penser autrement, cela bouscule nos neurones et comment dire : Ça fait du bien !

Scala offre beaucoup d’autres choses intéressantes, comme les traits,  les actors, sa gestion native du XML, son framework web “Lift”, Comet etc. J’espère avoir le temps d’approfondir tout ça et d’en faire quelques articles.

Plus généralement, la programmation fonctionnelle offre d’énormes avantages, rendant obsolète bon nombre de patterns et de framework qui n’existent finalement que parce que, Java et les langages impératifs en général ont de nombreuses imperfections.

Source : http://www.scala-lang.org/

C’est malheureux, mais j’ai discuté récemment avec un indépendant qui m’a démontré par A+B qu’entre le statut de TNS et celui de salarié, il pouvait ne pas y avoir de différence en terme de taux de cotisations obligatoires.

Voici son calcul de charges obligatoires :

TNS RSI (Commerçant / Artisan) :  45,2 %

TNS Prof. Libérale : 33%

Salarié : 22% de cotisations salariales et 30% de charges patronales donc : charges = 50%.

Vu comme ça, et étant donné la différence de prestation entre un salarié et un TNS (indemnités journalières, retraite, chômage..), il est plus souvent avantageux d’être salarié, voir complétement préférable pour un artisan au RSI.

Où est l’erreur ?

Alors pourquoi tout le monde ne se met pas salarié ? Les solutions pour le faire sont pourtant multiples ! L’erreur est simple, les taux sont corrects mais la base de calcul n’est absolument pas la même.

Pour le régime salarié, on applique les taux sur le brut versé alors qu’en TNS on applique le taux sur le net versé.

Petit rappel mathématique : y * taux = x  n’est pas égal a x * taux = y.

D’un coté on a brut * (1-taux) = net

de l’autre coté on a : net * (1 + taux) = brut (<=> net = brut * (1/(1+taux)) )

Jusqu’à preuve du contraire 1/(1+taux) n’est pas égal a (1-taux). On compare donc des choux et des carottes.

Pour être plus clair, voici un tableau comparatif avec des exemples facile à comprendre :

charges-sociales1

Attention, les taux ne sont qu’un ordre de grandeur, en réalité cela varie un peu en fonction des situations.

La comparaison entre salarié et TNS pour un indépendant en informatique, donc en profession libérale, se fera  soit en comparant 81% à 33%  de charges sur le net,  soit en comparant 45% à 25% de charges sur le brut.

En passant, attention au simulateur que l’on trouve sur http://www.freelance-info.fr, il est faux pour les mêmes raisons. Utilisez plutôt notre simulateur.

Devoxx - Day 3

logodevoxx

La troisième journée est assez différente des deux précédentes. Le planning des journées change. Le matin, plus de session de 3 heures mais une Keynote de deux heures suivie par une conférence d’une heure.

Après un rappel de quelques chiffres (2500+participants, 56 jugs …),  Stephan Janssen, l’organisateur de Devoxx nous présente la prochaine version de parleys.com . Parleys.com permet de voir de chez soi l’ensemble des conférences de devoxx mais également d’autres évènements, comme par exemple certaines présentations des différents JUG. Le service est également proposé aux entreprises pour héberger leurs vidéos. Outre cette nouvelle version, les présentations de devoxx 2009 sont déjà arrivées en grand nombre,  les versions gratuites des conférences seront disponibles au compte goutte tout au long de l’année. Toutes les conférences seront disponibles gratuitement  à la fin 2010. A noter qu’il est possible de télécharger les présentations sur son PC très facilement avec ce site et de les revoir à volonté.

Oracle

Le deuxième sujet est une présentation d’Oracle. J’avoue avoir envisagé quelque chose de plus grand, mais l’acquisition de Sun par Oracle n’étant pas finalisé, il n’y aura rien de croustillant de ce côté là. On a le droit à la place d’une démo du moteur de module dynamique de Weblogic.

Sun

La présentation de Sun a été plus intéressante. Outre le fait que la final release sortira le 10 décembre 2009, une belle démo, bien rodée, a pu démontrer la puissance de JEE6. Création d’une Servlet, intéraction avec EJB et ensuite avec un service OSGi. La simplicité de l’ensemble est vraiment à remarquer, aucun plantage lors de la démo. Certaines fonctionnalités de Glassfish V3 notamment le rechargement à chaud … sans perte de session a vraiment eu un impact chez tous ceux qui auront essayés de debugger un problème liée à une session.

Flash Catalyst

La dernière présentation fut celle d’Adobe. Une démonstration de Flash Catalyst et son intégration avec les différents outils Adobe très bien ficelée, avec un vrai show des deux présentateurs. La puissance de Flash Catalyst et son intégration avec la suite Adobe donnent une réelle impression de simplicité, que ce soit pour mapper deux vues, pour modifier un bouton, pour permettre d’envoyer le code vers Flash Builder, qui est plus à destination des développeurs. A voir ce que cela donne dans la réalité.

JDK 7 Update

Place ensuite à JDK7 update. Les plus grandes nouveautés sont le project Jigsaw, qui permet une grande modularité de la jdk, avec la possibilité de n’embarquer que les librairies utiles à notre application. Le project coin qui regroupe quelques évolutions du langage :

L’apparition de l’opérateur diamond qui nous permet d’écrire :

Map<String,String> myMap  = new Hashmap<>();

Il sera également plus simple de construire des collections sans avoir des myList.add(…) à la chaine, la solution implémentée aura une syntaxe proche de celle des tableaux. D’autres nouveautés, comme la possibilité de faire un switch sur des String ou l’apparition  de closures (simples). Un point à également été clarifié sur la différence entre Java SE et le jdk, le Java SE représentant la spécification, le jdk7 l’implémentation. A noter que bien qu’il y ait un open jdk 7, il n’y a pas de Java SE 7.

Comet

Jean-Francois Arcand présente ensuite le framework Atmosphère qui permet de pousser un message du serveur vers le client.
Il existe trois types de méthodes pour pousser ce message :

  • Le Polling
  • Le long Polling
  • Http Streaming, souvent utilisé dans les jeux mais qui devient compliqué dans certaines situations.

Atmosphère se veut un framework simple, basée essentiellement sur des pojos et disponibles sur de nombreux serveurs (de tomcat à google app engine) et supporte certains frameworks de présentations (GWT/Wicket). La démo, très simple, se déroule bien. Encore une fois, il faut voir ce que cela donne dans la réalité de nos environnements.

Distributed programming the google way

Gregor Hohpes présente ensuite une conférence d’une heure sur “Distributed programming the google way”. Cette conférence se révèle être une des plus intéressantes conférences de Devoxx. Il détaille le fonctionnement de BigTable, de MapReduce, de Sawzall et de Google File System au travers de 8 recommandations :

  • Utilisez la fragmentation, ne pas hésiter à partionner les données.
  • Rester simple et n’implémentez que les fonctions de base
  • S’attendre à  l’échec
  • Faites des processus autonome, pouvant poursuivre sans supervision
  • Le runtime est le plus important. Mieux vaut une circulation fluide à des règles très strictes.
  • Préférer la vitesse à la précision. Plus c’est rapide, mieux c’est.
  • Privilégier tout ce qui est sans état. Les processes qui conservent un état sont plus couteux que les opérations sans états
  • Tout est affaire de compromis

L’importance de ces 8 règles permettent d’avoir une bonne scalabilité. Il n’est souvent pas nécessaire de produire toutes les fonctions possibles pour avoir un outil scalable. Ainsi, les différents outils présentés ont chacun leurs limites :  par exemple, Sawzall permet de faire des aggrégations extrêmement rapide mais ne permet pas de faire de traiter la duplication.


Les deux BOFs auquel j’ai assisté de la soirée n’ont pas été interessante du tout. Trop de monde, impossible à entendre.

 
 

A propos

Freelances sur les technos Java, nous avons crée début 2009 notre société, A-Consulting. De formations ingénieurs, nous avons mener à bien plusieurs projets pour le compte de grands groupes dans les domaines de l'assurance, de la banque, des télécoms et des médias.