Another day @ Devoxx

« Et ça continue, encore et encore…. ». ne me demandez pas pourquoi j’ai cet air dans la tête. ce n’est franchement pas mon style de musique…

Effective Java by James Bloch

Du code, du code, du code…malgré des neurones pas encore complètement « up ». Une session au format Tips & Tricks sur certains aspects de la version 5 langage Java. Des subtilités autour des enum (« do not use ordinal() »), des mécanismes de lazy initialization, des generics.

On peut s’étonner du fait qu’on ne parle que de Java5 mais force est de constater qu’encore peu de personnes ont définitivement quitté la version antérieure de Java et que cela reste la version amenant le plus de modification du langage depuis un bout de temps.

La Modularité : décidément un sujet à la mode…

…mais ce matin, la keynote s’est concentrée sur la modularité du JDK, la compatibilité et les nouveautés de Java7. Le JDK se doit d’être modulaire pour faciliter les downloads, les temps de démarrage etc….une mouvance que l’on a déjà constaté au niveau des serveurs d’applications (par exemple Glassfish).

« La compatibilité ne sera pas forcément assurée tout le temps » est une synthèse du message de Mark Reinhold sur le sujet de la compatibilité ascendante entre versions du JSE. C’est surprenant, effrayant et en même temps, cela garanti ou facilite la survie du langage Java : certaines fonctionnalités, évolutions du langage se doivent d’être intégrées et la compatibilité est un frein à une réelle intégration…Affaire à suivre.

Les nouveautés du Java 7. On note un mouvement de fond de Sun qui est l’ouverture sur la communauté utilisateur comme si Sun avait compris qu’il était important de faire évoluer le langage pour répondre aux demandes du terrain et donc aux communautés de développeurs. J’aime cette idée. Java 7 intègre donc des évolutions souhaitées par Sun et des évolutions souhaitées par d’autres acteurs:

  • la JSR 277 (ou JAM) disparait au profit de la JSR 294. Là ou la JSR 277 travaillait sur le déploiement, la JSR 294 se limite au langage, aux mécanismes de super-package ou comment jouer sur la visibilité de certaines classes ou package. on se rapproche d’OSGI
  • OSGI justement. Mark Reinhold officialise le rapprochement. Dans les faits, cela c’était déjà concrétisé avec la modularité OSGI de Glassfish.
  • la machine virtuel veut supporter des langages dynamiques. Son petit nom de code est simplement JSR 292 mais le mouvement était déjà lancé depuis quelque temps
  • de nouvelles APIS de I/O. Certes les NIO mais surtout de nouvelles APIs d’accès au système de fichier (depuis le temps… ;-) )
  • une gestion des exceptions facilitée grâce à deux points.
    • Le « safe rethrow » qui permet par exemple de « catcher Throwable » et de « relancer » strictement l’exception alors que la signature de méthode ne prévoit que deux cas d’erreur fortement typé. en bref, le compilateur gère pour nous.
1
2
3
4
5
void doIt() throws X1, X2{
 
try{}
 
catch(Throwable e){throw e}
    • Le « multicatch » qui permet d’avoir un seul catch(X1, x2…) et donc un seul traitement pour les exceptions X1 et X2.
1
2
3
try{...}
 
catch(X1, X2){
  • peut etre de nouvelles annotations sur plus de type. L’exemple pris est celui d »une annotation @NonNull sur un paramètre de méthode. Cette annotation permet de préciser que le paramètre doit etre non null et facilite la vérification de NullPointerException et autres bugs. C’est intéressant car cela nous rapproche des classiques outils de qualimétrie mais on peut regretter la forte adhérence et intrusion au code.

Event Driven Architecture & Complex Event Processing

Les architectures orientées évènements fonctionnent sur la base d’évènements échangés entre un « publisher » et un « subscriber ». L’utilisateur a alors la responsabilité de s’abonner aux évènements qui l’intéressent; le système s’auto organise (enfin…).

Le Complex Event Processing est une évolution des architectures orientées évènements ou Event Driven Architecture qui vise à agréger beaucoup plus finement qu’un simple Publish/Subscribe des informations, des évènements provenant de différentes sources. Il est possible de requêter le contenu des messages; par exemple, les ordres d’achat qui dépasse tel ou tel montant ou bien les évènements de crédit et débit qui ont en commun un numéro de compte…

Les cas d’utilisation sont autour des systèmes de trading, de détection de fraudes ou bien un système de monitoring de système

La session est l’occasion de présenter un produit nommé Esper qui implémente et facilite (normalement bien entendu car rappelez vous qu’il s’agit d’une présentation…) le développement de systèmes basées sur cette architecture. Esper propose donc une API permettant de réagir aux évènements, d’en créer de nouveaux, de requêter le contenu des message avec une syntaxe proche de SQL.

La modularité Java

Je crois que je n’aurai jamais autant entendu ce terme: modularité. Cette présentation se concentre sur la JSR-294 ou comment gérer la modularité de JDK mais également des applications afin d’améliorer quelques limitations sur l’existant:

  • le « jar hell » et les problématiques de classpath. Apparemment, l’idée de supprimer le classpath et sa nécessaire configuration au profit de quelque chose – que j’avoue ne pas avoir trés bien saisi…
  • les temps de download
  • les « memory footprint »

Bref, cette JSR veut faire évoluer le langage et la VM pour être plus simple et flexible. Alors voilà dans les grandes lignes ce qui nous attend (au risque de ne pas être exhaustif). En premier lieu, le concept de module. le package est hiérarchique. le module, lui, permettra de regrouper des classes de différents packages dans un composant « logique ». Ainsi le code suivant pourra être écrit

1
module com.octopackage com.octo.core public class DoIt

puis dans une autre classe

1
module com.octo package com.octo.ext module class DoItDifferently

la classe DoItDifferently utilise le mot-clé module qui lui donne simplement la visibilité – et donc la possibilité d’être utilisée – au sein du module, indépendamment de son package.

Mais le module introduit également la gestion des dépendances. Ainsi il peut référencer d’autres modules qu’ils utilisent et que la JVM aura à charge de récupérer (comment? ca non plus je n’ai pas compris…ben oui désolé.)

1
module com.octo{ require com.octo.core require ceQueVousVoulez }

Bien entendu, il faut rajouter les notions de versionning; là encore, c’est le développeur qui gère cela.

1
module com.octo @ 1.2{ require com.octo.core @ 1.2 require ceQueVousVoulez @ 2.2 }

Il reste à voir comment la JVM va gérer ces dépendances de modules. Reste qu’à ce jour, ces évolutions du langage me semblent plutôt destinée aux éditeurs mais cela risque d’impacter nos processus de build car aujourd’hui des outils comme Maven gère pour nous et au build ces histoires de dépendances et de version de binaires.
Peut être que la JSR 294 aura le même destin que sa quasi homonyme JSR- 277; Java Module. Peut-être pas.

JEE 6 : Coming Soon, March 2009

Là encore, le keyword est « modularité ». JEE continu à grossir par rapport à sa version précédente mais introduit la notion de profile. L’idée dérrière les profiles est de regrouper des technologies « cohérentes » entre elles. Le premier de ces profiles est le « Web Profile » ou quelles sont les APIs nécessaires et utiles pour réaliser une application Web complète.
Ainsi, le Web Profile va réunir Servlet 3.0, JSP 2.1, JSF 2.0, EJB Lite 3.1, JTA 1.1, JPA 2.0..Un beau programme mais la limite ou la difficulté auquel Sun devra faire face avec les profils, c’est de créer le consensus sur ce quelles APIs seront présentes ou non dans le profile…Au regard des réactions du public, la tâche me parait complexe.

« Faute avouée est à moitié pardonnée » disait ma mère (et en fait j’imagine toutes les mères…). Sun appelle le « pruning » ou comment déprécier des pans complet de JEE; les éditeurs auront le choix d’implémenter ou non ces parties. On y trouve des APIs comme JAX-RPC…

JEE 6 s’ouvrira également sur la communauté au proposant les « Extensibility »; un mécanisme permettant à des solutions open source, des framework comme Spring, de bundler leur configuration (typiquement les servlet-filter…) pour que cette dernière soit simplement et de façon transparente, pour le développeur, prise en compte par le container.

Pour aller un peu plus dans le détail. Servlet 3.0 propose :

  • un mode de développement à base d’annotations (@WebServlet, @ServletFilter)
  • une modularité du fichier web.xml. Cela rejoint les « extensibility » mais il est possible d’embarquer un fichier META-INF/web-fragment.xml dans un jar, un framework et ce dernier sera mergé avec la configuration de l’application réalisée par annotation.
  • l’intégration de Comet. Encore une configuration à base d’annotations @WebServlet(asyncSupported=true)…Les choses bougent vraiment trop vite…

Concernant EJB 3.1, on note:

  • l’appartion d’un nouveau type de Bean. Annoté @Singleton, ce dernier est un Bean qui joue le rôle de singleton. Semble idéal pour les classiques problématiques de « Startup class », attention à ce que ce dernier ne deviennent pas le bottleneck de l’applicatif. L’API rajoute un gestionnaire d’accès concurrent (@ConcurrencyManager), un gestion des lock (@Lock)…
  • le support de méthodes asynchrone sur un EJB Session. L’ajout de l’annotation @Asynchronous rend l’exécution asynchrone et laisse le container définir le moment opportun pour son exécution.
  • les EJB 3.1 Lite…Modularité quand tu nous tiens! Bref, un sous ensemble d’EJB 3.1 qui propose Session Beans, gestion des transactions, de la sécurité, les intercepteurs et un mode EJB Container embedable. Cet embeddable Container peut être facilement démarrer via des APIs. Il permet donc d’utiliser des EJBs avec un JSE, de faire de tests unitaires. Enfin, ces EJBs peuvent être directement intégrables dans une application web; il n’est donc plus nécessaire de passer par un jar tiers.

Un outil a essayer : Javarebel

Commencons par le but du produit : supprimer le turnover; ie le temps entre une modification du code et la visualisation du changement dans une application déployée sur un serveur.

La présentation commence par poser le problème : en tant que développeurs Java d’application web, on passe 10% du temps à attendre que notre application se redéploie et a peu pès autant à retrouver ce qu’on était en train de faire vu que pendant notre temps d’attente, notre cerveau à perdu le fil. Bref, chaque seconde compte.

Des solutions plus ou moins bonnes existent déjà.

  • Les serveurs d’applications savent recharger une application en changeant de classloader, le problème est qu’il faut alors réinitialiser et recharger le contexte, avec des applications spring cela peut prendre relativement longtemps.
  • OSGI va plus loin et permet de ne plus recharger toute l’application, mais seulement un module (et les modules qui en dépendent). On réduit, mais ce n’est pas encore ça.
  • Les frameworks comme tapestry ou RIFE permettent de recharger un composant uniquement. On approche… mais il reste des problèmes (tout ce qui est hors composant par exemple, et il faut toujours recharger le contexte)
  • Hotswap, c’est un peu ce qu’on vise, car avec hotswap, on ne recharge plus de contexte, c’est le code de l’objet qui est directement changer. Cette (très bonne) solution reste limitée : on ne peut peut changer que le code interne à une méthode et on est obligé d’être dans un debuggeur.

Javarebel est assez similaire a hotswap : il change directement le code des objets (donc pas de rechargement de contexte), mais il supporte lui plus de fonctionnalités comme l’ajout de méthodes, de
variables d’instances, de classes etc… Les limitations sont repoussées aux changement d’héritage (l’objet n’étant plus X mais Y par exemple).

Une partie de certains frameworks comme Spring ou Struts sont aussi gérés (tant que la configuration est gérée par annotation dans la classe) : par exemple, on peut rajouter à chaud une méthode d’un controlleur spring avec l’annotation qui va bien pour qu’elle soit bindé sur l’URL correspondante, ou encore on peut rajouter un bean « autowired », le bean sera mis à jour automatiquement.

Des plugins sont prévus pour intégrer ce produit aux outils comme Maven ou Eclipse.

Conclusion du speaker : « chaque secondes comptent. Il y a plein de solutions efficaces, gratuites et qu’il faut utiliser, si vous voulez aller encore plus loin, il y a une solution payante (mais pas chere) » .
A noter, que vous pouvez payer en bières si vous voulez (4 pour la version individuelle et une dizaine pour la version entreprise)

La société développe aussi un serveur d’application basé sur la même technologie qui vous permet de réaliser une montée de version de votre application avec zéro interruption de service.

Hibernate Performance Tuning

Session très intéressante qui énumère toutes les optimisations possibles et leur contexte d’application. Toute la chaîne participant à la persistance est passée en revue, on commence par parler des paramétrages au niveau de l’OS (et oui, à la fin nos données son bien sauvegardées sur de vulgaires fichiers ;-), les accès disques (compression, cryptage, fragmentation), communication réseau, etc… Puis on remonte d’un niveau pour aborder la base de données et les configurations permettant là encore de gagner en performance: la taille du cache (the bigger, the better ;-), les indexs, la taille des buffers, les table space… là on se dit, tiens je vais aller payer un café à mon DBA préféré ;-) Puis on remonte doucement vers Hibernate (en abordant le choix judicieux du driver JDBC); petite piqure de rappel sur les différents caches Hibernate (1er et 2ème niveaux). On entre ans le vif du sujet avec les optimisations au niveau code et design d’implémentation: on prendra bien soin de ne pas avoir une hiérarchie d’héritage trop importante, de bien choisir le type de la colonne discriminante (on préférera utiliser un char(1), certes moins explicite mais bien plus performant.

Idée reçu: le DDL automatiquement généré par hibernate n’est pas optimisé pour la production ! Volker insiste bien sur le fait de se rapprocher le plus possible du DBA pour qu’il puisse « tuner » les scripts de génération et poser correctement les bons indexs (sans doute l’optimisation qui fournit le meilleur retour sur investissement). La session se termine par l’optimisation des requêtes HQL: toujours utiliser les « parametrized queries », maximiser les bulks/batch invocation pour optimiser les allers-retours vers la base de données, préférer le eager-loading pour les cas d’utilisation de navigation dans les grappes d’objet…

L’optimisation des performances s’effectue à de très nombreux niveaux depuis les fichiers jusque dans le code de l’application. Pour que ce chantier soit utile et concluant, Il ne faut jamais oublier de se fixer un objectif… et là, le test de monté en charge nous aidera pour fixer cet objectif à atteindre grâce aux métriques que nous pourront alors suivre.

Efficient Enterprise Build

Les nouveautés de Maven 3 :

  • Une gestion des plages de versions qui fonctionne : les plages de fonctions par exemple : version=[1.1,) étaient présentent dans les dernières versions de Maven2, mais il restait pas mal de problèmes dans leur implémentation.
  • Plexus (le framework d’IOC de maven) va être remplacé par un autre framework, probablement XBean ou Guice Maven devient encore plus modulaire (encore…). Cette modularité ouvre de nombreuses possibilités de réutilisation ou d’ouverture notamment :
    • La partie embedder permet une meilleure intégration aux outils comme Eclipse, Netbean ou Hudson
    • Le « Plugin manager » est réutilisée dans Nexus
    • Le project builder peut-être changer pour intégrer des projets Visual Studio ou pour permettre de construire son POM avec un script ruby ou groovy à la place du fichier XML.
  • Une amélioration de la partie « code coverage » qui ne se limitera plus aux tests unitaires, mais permettra de visualiser la couverture de code par les tests unitaires, les tests d’intégration et les tests
    d’acceptance sous le même rapport.

L’équipe travaille avec Hudson pour offrir une meilleure intégration de Maven, notamment grâce à l’embedder. Une intégration de workflow (via drools) permettra de définir un workflow pour une release par exemple : « build – envoi de mails – vote des intéressés – release ».

Au final, un gros accent sur la modularité et l’intégration aux outils du développeur, Jason van Zyl nous à fait une bonne démo de m2eclipse et l’objectif est clairement que le développeur reste dans son IDE et que celui-ci lui apporte tout ce qu’il a besoin : documentation pour construire son projet, autocomplétion, vue sur les repositories centraux, etc…

By Benoit Lafontaine, Fabrice Robini, Olivier Mallassi