Publié le 24 mars 2008 par Thomas Recloux
Quelques astuces en vrac pour intégrer un projet maven1 (oui, il y en a encore
) dans continuum.
- Continuum ne supporte pas l’import de POM qui étendent un autre POM. la solution est de créer un POM minimal dédié à cet import et qui indique l’URL du SCM. Ensuite Continuum va déclencher un “checkout” à partir du SCM et récupérer le véritable POM.
- Sous windows, le script bat de maven ne permet pas à continuum de récupérer le code de sortie et donc de savoir si le build est un succès. La solution est de récupérer la dernière version du script maven.bat et d’affecter la valeur “on” à la variable d’environnement “MAVEN_TERMINATE_CMD”. Il est possible d’affecter la variable d’environnement à l’aide des profils continuum.
Tags: continuum, java, maven | Aucun commentaire »
Publié le 8 mars 2008 par Thomas Recloux
Bruce Johnson, le papa de GWT a annoncé la disponibilité de la version 1.5M1 de GWT.
La version 1.5 est largement attendue par la communauté GWT car elle apporte le support de Java 5 avec les annotations, generics, autoboxing, enums, ….
Attention, ce n’est pas une version stable, elle n’est pas documentée et ne doit donc pas être utilisée serieusement.
Tags: gwt, java | Aucun commentaire »
Publié le 8 mars 2008 par Thomas Recloux
Je prépare actuellement une formation au profiling avec JProfiler, j’ai choisi de travailler à partir de l’application Jpetstore, application exemple fournie avec le framework spring. Le tout étant déployé dans un conteneur Tomcat 5.5.25
J’ai inséré dans cette application quelques problèmes à corriger par les stagiaires et notamment une fuite mémoire, j’ai eu la surprise en contrôlant l’efficacité de ma fuite de constater que d’autres fuites étaient présentes.
En effet, certains objets du domaine restent présents dans la mémoire de la JVM et ne sont pas récupérés par le garbage collector . L’application utilise la librairie de tag (taglib) JSTL via l’implémentation de Jakarta, c’est un des tags de cette librairie, le tag forEach qui garde des références vers les objets de la liste parcourue.
En creusant un peu plus, le problème est identifié depuis longtemps dans au sein du projet taglib et au sein du projet tomcat.
En fait le composant taglib présente une méthode qui libère ses données, mais elle n’est pas appelée par le moteur de JSP de Tomcat (Jasper), les deux équipes semblent se renvoyer la balle en expliquant qu’ils implémentent bien leurs spécifications respectives. Le problème est censé disparaître en désactivant le pooling des tags dans tomcat, mais je n’ai pas pu constater d’amélioration.
Tout cela est bien décevant de la part de ces deux projets, je vais essayer de mesurer prochainement le comportement de la fuite dans le temps, est ce que le nombre références augmente ou au contraire plafonne ?.
Tags: java, jsp, performances | Aucun commentaire »
Publié le 5 mars 2008 par Thomas Recloux
Log4J est un composant de Log qui s’est imposé de manière universelle dans le monde Java, je l’utilise depuis mon premier projet Java en 2001 (oh my god).
Cela fait quand même du bien de se replonger dans sa documentation de temps en temps, j’ai cette fois ci été attiré par les composants qui permettent d’ajouter des données contextuelles aux traces.
En effet, le besoin de rajouter ce type de données pour faciliter la corrections de bugs est récurent, ces données peuvent aller de l’identifiant de l’utilisateur au processus applicatif en cours en passant par la version de l’application, les besoins et solutions sont variés.
Log4J offre deux composants qui remplissent ce rôle de manière élégante :
Le NDC est une pile qui permet de stocker des messages contextuels, ces messages sont stockés par Thread et sont donc (par exemple) partagés durant l’exécution d’une requête HTTP par un moteur de servlet.
La méthode push permet de rajouter un message en haut de la pile, la méthode pop permet de dépiler d’un niveau.
Pour ajouter le contenu du NDC dans un PatternLayout, il faut ajouter la variable %x au pattern.
Par exemple, cette séquence d’appels :
Logger logger = Logger.getLogger("foo");
logger.info("homepage");
NDC.push("ClientID : " + clientId);
logger.info("client identifié");
NDC.push("Process : Commande de chequier");
logger.info("Nb de chequiers commandés: " + nbChequiers);
associée à ce pattern Log4J :
log4j.appender.STDOUT.layout.ConversionPattern=%-5p %c [%x] %m%n
génère la sortie suivante :
INFO foo [] homepage
INFO foo [ClientID : 123456] client identifié
INFO foo [ClientID : 123456 Process : Commande de chequier] Nb de chequiers
commandés: 2
INFO foo [ClientID : 123456 Process : Demande de RIB] Code IBAN : 441 45645
6456 45645645 456
A l’instar du NDC, le MDC est un espace de stockage propre à un Thread, cependant cet espace de stockage est réalisé à l’aide d’une Map et non pas d’une pile. Il permet donc d’associer des messages à des clefs et de spécifier dans le pattern quelles clefs sont à afficher.
Par exemple, cette séquence d’appels :
logger.info("homepage");
MDC.put("ClientID", clientId);
logger.info("client identifié");
MDC.put("Process","Commande de chequier");
logger.info("Nb de chequiers commandés: " + nbChequiers);
MDC.put("Process","Demande de RIB");
logger.info("Code IBAN : " + codeIBAN);
Associée au pattern :
log4j.appender.STDOUT.layout.ConversionPattern=%-5p %c
[Client:%X{ClientID}] [Process:%X{Process}] %m%n
Produira ces traces :
INFO foo [Client:123456] [Process:] client identifié
INFO foo [Client:123456] [Process:Commande de
chequier] Nb de chequiers commandés: 2
INFO foo [Client:123456] [Process:Demande de RIB] Code IBAN :
441 456456456 45645645 456
Tags: java, log4j | 4 commentaires »
Publié le 26 février 2008 par Thomas Recloux
Au grès des missions et des projets, j’ai plusieurs fois eu l’occasion d’optimiser des applications Java / J2EE.
Pour optimiser une application, il faut détecter les éléments consommateurs à l’aide d’un profiler. Le profiler est un logiciel qui se connecte à la machine virtuelle et récupère des informations sur les enchainements de méthodes et les allocations d’objets.
Cela permet de détecter quelles méthodes prennent du temps soit en consommant de la CPU soit en attendant un traitement distant (requête SQL ou LDAP, Appel d’un EJB ou d’un Web Service, ….).
Les profilers permettent d’avoir une vue arborescente des piles d’appel, par exemple quelles méthodes sont déclenchées par une requête HTTP ou quel composant consomme le plus de temps sur cette requête
Pour alimenter le profiler en données à analyser, il faut faire travailler les applications que l’on veut optimiser. L’idéal est de définir des scénarios d’utilisation de l’application à partir de statistiques de production, afin de reproduire les actions les plus utilisées.
Pour automatiser ces scénarios, des outils comme OpenSTA, The Grinder ou JMeter sont très adaptés.
Une fois le profiler mis en place et les scénarios automatisés, je fonctionne de manière itérative en effectuant les actions suivantes :
- Lancement du tir en utilisant les scénarios automatisés
- Analyse des résultats
- Correction / tests unitaires / déploiement
La présence de tests unitaires et de tests fonctionnels permet d’accélérer la phase de corrections et de déployer plus rapidement les corrections en production en s’assurant de la non régression.
Je pense que des interventions de ce type sont nécessaires sur toutes les applications ou groupes d’applications dont le niveau de performance est important et sont obligatoires quand on constate que l’infrastructure de production est trop sollicitée.
Les profilers phares du marché sont :
Tags: java, performances | 2 commentaires »
Publié le 12 février 2008 par Thomas Recloux
Xebia a lancé une série de quizz autour de Java / J2EE, les 50 premiers au classement seront conviés à un tournoi de poker qui va permettre de gagner des lots intéressants.
Je trouve cette initiale originale et très sympathique, même si le but n’est sûrement pas philanthropique. J’imagine que cette opération est bonne en terme d’image et de recrutement.
A vos questionnaires et qui sait, rendez vous autour d’une table de poker ?
Tags: java | Aucun commentaire »
Publié le 1 février 2008 par Thomas Recloux
Après avoir découvert les continuations de jetty, voici les Advanced IO de Tomcat.
Le modèle de programmation permet aussi de déconnecter les Thread des connexion HTTP, la mise en œuvre me semble un peu plus complexe que pour Jetty mais permet un contrôle plus fin des évènements de la connexion.
Tags: comet, java, tomcat | Aucun commentaire »
Publié le 21 janvier 2008 par Thomas Recloux
Dans cet entretien vidéo, Mark Richards donne son point de vue sur le choix entre Hibernate et iBatis.
J’ai souvent rencontré des intégristes des deux solutions et je trouve que son point de vue est très bon :
- Quand on peut construire le modèle de données et le modèle objet de concert, Hibernate est adapté
- Si on en arrive à écrire du SQL, iBatis est adapté
- Il ne faut pas hésiter à utiliser les deux outils dans le même système. Mark donne l’exemple d’un système dans lequel hibernate est utilisé pour les fonctionnalités de gestion traditionnelles alors que iBatis est utilisé pour le reporting.
Comme souvent il n’y a pas de mauvais produits, uniquement des mauvais choix
Via application-servers
Tags: hibernate, ibatis, java | Aucun commentaire »
Publié le 21 janvier 2008 par Thomas Recloux
Guillaume Bodet a publié un bêtisier rassemblant des exemples de code source original, voici un exemple de méthode récursive qui prend bien des détours pour accomplir sa mission.
public void completeParentsList (String id, List<MyBean> fathers) {
for (BigDecimal key : idsList) {
MyBean bean = beansById.get(key.toString());
if (bean.getId().equals(id)) {
fathers.add(bean);
completeParentsList(bean.getParentId(), fathers);
}
}
}
Tags: java | 2 commentaires »
Publié le 15 janvier 2008 par Thomas Recloux
Il y a 4 ans, j’avais été chargé d’une étude sur le “push” en client léger, le but était de pouvoir notifier les utilisateurs d’évènements importants.
Comme le protocole HTTP est basé sur un système de requêtes / réponses, qui s’apparente à du “pull”, le serveur ne peut pas déclencher d’évènements en direction du client. L’idée est donc de faire en sorte que le client vérifie régulièrement si le serveur veut lui présenter un évènement.
J’avais implémenté un système de “pooling” HTTP avec une servlet qui se mettait en attente sur un conteneur de messages pour une durée de plusieurs dizaines de secondes avant de retourner une réponse au navigateur qui s’empressait de déclencher une nouvelle requête. Bien sur, l’inconvénient majeur de cette architecture est que chaque utilisateur bloque un Thread coté serveur, ce qui est gourmand en ressources.
Avec les applications AJAX, les besoins de ce type se multiplient. Heureusement les nouvelles implémentations d’I/O Java permettent de ne pas monopoliser un thread par socket. Il est donc possible d’affecter le thread à une autre tache pendant l’attente d’un évènement.
La version 6 du conteneur de servlet Jetty propose une implémentation de cette solution via les Continuations. Cette API permet de suspendre une requête et de libérer le thread. En général, intégrer des spécificités dans un conteneur web est délicat car il y a un risque : on grève la portabilité vers un autre conteneur. Cependant dans ce cas, l’API est utilisable dans un autre conteneur en basculant dans un classique wait/notify qui bloque le thread. De plus, les continuations vont être proposées au groupe de travail sur les Servlet 3.0 .
Une bonne nouvelle pour les applications de type CTI qui pourront se passer d’Applet et autres ActiveX.
Via ongwt.
Tags: comet, java, jetty | Un commentaire »