-
Acceleo 2.3
La version 2.3.0 d’Acceleo est sortie vendredi dernier !
On peut noter les principales nouveautés :- Compatibilité Eclipse 3.4
- Recherche de référence des templates
- Support partiel des EOperations
- Acceleo indépendant du bridge
- Compatibilité EA 7
Vu que j’ai participé à la mise en place du bridge pour Entreprise Architect, je peux vous confirmer qu’il fonctionne bien pour les diagrammes de classes. Par contre, Acceleo a oublié d’indiquer que cela ne fonctionne qu’avec la version 7.1 Build 830. Comme EA a la mauvaise habitude de modifier son export XMI régulièrement, faites bien attention d’avoir la bonne version.
Acceleo est un très bon produit open source pour faire des transformations M2T (Modele to Texte) parfaitement intégré à Eclipse. Et à propos d’Eclipse, Obeo (la société développant Acceleo) vient de passer au statut de « Strategic member » de la fondation Eclipse.
-
Java Virtual Machine Tool Interface
En lisant l’excellent blog de xebia, j’ai découvert l’interface JVMTI : une API native de profiling. Elle permet non seulement de profiler des applications Java mais aussi de les manipuler directement au niveau du bytecode pendant leur exécution.
Je travaille justement sur une application sur laquelle j’aimerais bien savoir s’il n’y a pas de goulot d’étranglement à cause d’un bloc synchronized. Donc ni une ni deux, je me lance !
Pourquoi JVMTI ?
Après tout il existe pas mal d’outils de profiling Java, à commencer par TPTP intégré dans Eclipse. Le problème avec ces outils c’est qu’ils fonctionnent tous à peu près bien avec une petite application, mais dès que l’on utilise un serveur d’application ou que l’on a un code un peu volumineux… c’est le drame. Au pire l’application ne démarre pas, au mieux les temps de traitement sont multipliés par 1000 et on ne voit plus grand chose. Vu que JVMTI utilise une interface native, je suis persuadé que ce sera beaucoup moins lourd que les autres outils.
JVMTI remplace depuis la JDK5 les librairies JVMPI (Profiling) et JVMDI (Debug). Celles-ci sont passées deprecated sur la JDK5 et sont disparus en JDK6.
Ecrire une DLL
Une librairie native c’est bien, mais ça a un prix : il faut l’écrire en C.
Et c’est à ce moment que je me suis rendu compte que ça fait un bon moment que je n’ai pas écrit du C. La dernière fois ça doit faire 10 ans pour programmer un 68HC11 à l’IUT. Mais bon, ça doit être comme le vélo, ça ne s’oublie pas. Et bien c’est tout à fait cela, refaire du C c’est comme refaire du vélo après une pose de 10 ans : on va moins vite et ça fait mal
La première étape a été d’exécuter l’exemple de sun sans toucher au code. Premier problème : comment construire une DLL ? Et oui venant du monde Java je n’avais jamais eu besoin de générer une DLL. Je commence donc par télécharger « Microsoft Visual C++ 2008 Express Edition », mais impossible de faire fonctionner le code de SUN. Je n’arrive pas à inclure les .h de JVMTI à mon projet et encore moins à générer une DLL. En cherchant un autre outil je suis tombé sur Dev-C++ et j’ai enfin réussi. Il faut créer un projet DLL en C et modifier deux options du projet. Dans l’onglet Fichiers il faut décocher l’option « Compiler en tant que C++ » sur notre fichier C. Et dans l’onglet Répertoire il faut ajouter les deux répertoires $JDK_HOME/include et $JDK_HOME/include/win32. Après on clique sur compiler et hop ! on a une DLL !
Dev-C++ est un peu triste au niveau IHM mais il a l’avantage d’avoir été très rapidement pris en main.
L’agent
Une fois la barrière de la langue franchie, il faut attaquer le vif du sujet : construire un Agent.
Le point d’entrée c’est la méthode Agent_OnLoad. C’est dans cette méthode qu’il va falloir indiquer quels événements on souhaite écouter. Cela se passe en trois étapes.
1.Capabilities
En fonction des événements que vous souhaitez écouter et des méthodes dont vous avez besoin il faudra activer les bonnes capabilities. Attention, plus vous activerez de Capabilities, plus les performances en seront affectées.
// Activation des capabilities
(void)memset(&capa, 0, sizeof(jvmtiCapabilities));
capa.can_get_current_contended_monitor = 1;
capa.can_generate_monitor_events = 1;
capa.can_get_line_numbers = 1;
error = (*jvmti)->AddCapabilities(jvmti, &capa);can_get_current_contended_monitor : Pour écouter les entrées/sorties de block synchronized
can_generate_monitor_events : Pour activer la génération d’event sur l’activité du moniteur
can_get_line_numbers : Pour récupérer les numéros de lignes d’une méthode avec GetLineNumberTable().2.EventCallbacks
Ensuite il faut abonner nos méthodes aux événements monitorés.
// Déclaration des méthodes de callback
(void)memset(&callbacks, 0, sizeof(callbacks));
callbacks.VMInit = &callbackVMInit;
callbacks.VMDeath = &callbackVMDeath;
callbacks.MonitorContendedEnter = &callbackMonitorContendedEnter;
callbacks.MonitorContendedEntered = &callbackMonitorContendedEntered;
error = (*jvmti)->SetEventCallbacks(jvmti, &callbacks, (jint)sizeof(callbacks));Dans mon cas je vais écouter les événements de début et de fin de vie de la JVM ainsi que la mise en attente et la libération d’un Thread sur un block synchronized.
3.EventNotificationMode
Pour finir on active la génération d’événement
// Déclaration des événements à écouter
error = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, JVMTI_EVENT_VM_INIT, (jthread)NULL);
error = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, JVMTI_EVENT_VM_DEATH, (jthread)NULL);
error = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, JVMTI_EVENT_MONITOR_CONTENDED_ENTER, (jthread)NULL);
error = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, JVMTI_EVENT_MONITOR_CONTENDED_ENTERED, (jthread)NULL);Et voilà ! Maintenant à chaque fois qu’un Thread est mis en attente ma méthode callbackMonitorContendedEnter est appelée et lorsqu’il est libéré c’est callbackMonitorContendedEntered qui est executé.
OMG WTF memory leak !
On peut traduire poliment ce titre par : Mon dieu que c’est dur de perdre son garbage collector !
En effet après avoir mis en place le moniteur, la tache me paraissait simple. Il suffit de stocker dans le contexte du Thread l’heure de mise en attente et au moment où on le libère on peut en déduire le temps d’attente. Mais ça n’a pas été aussi trivial car la gestion de la mémoire m’a posé beaucoup de problèmes.
Dans JVMTI il y a deux types de gestion de la mémoire. Soit c’est la lib qui gère l’allocation de la mémoire, comme pour la méthode GetMethodName, et dans ce cas il ne faut pas oublier de lui demander de libérer cet espace :
char *methodName;
err = (*jvmti)->GetMethodName(jvmti, frames[i].method, &methodName, NULL, NULL);
(*jvmti)->Deallocate(jvmti, (unsigned)methodName);Soit c’est à vous de réserver l’espace mémoire avant l’appel, comme pour GetMethodDeclaringClass.
jclass* declaring_class_ptr;
declaring_class_ptr = malloc ( sizeof(jclass));
err = (*jvmti)->GetMethodDeclaringClass(jvmti, frames[i].method, declaring_class_ptr);
free(declaring_class_ptr);Dans un premier temps je n’avais pas vraiment fait attention à la gestion de la mémoire en pensant naïvement qu’une petite fuite sur une petite application qui n’a pas vocation à s’exécuter longtemps, n’avait pas d’importance. Grave erreur ! Même si mon code fonctionnait sur mon petit exemple à 3 Thread, c’est lorsque je l’ai lancé avec Jonas que j’ai rencontré des problèmes. Mais une fois que l’allocation et la libération de la mémoire a été bien faite, je n’ai plus eu de problème.
Conclusion
J’ai fait ma première DLL !! Ca a été un peu laborieux, mais j’ai fini par y arriver. C’est vrai que de devoir programmer en C m’a beaucoup ralenti, mais d’un autre coté si j’étais un développeur C je n’aurais pas besoin de faire du profiling sur une application Java.
Une autre difficulté venait du manque de documentation. Il y a très peu d’exemple d’utilisation de cette librairie sur le net. En français c’est simple : il n’y en a pas. C’est aussi pour cette raison que je publie cette article à fin d’aider les futurs utilisateurs francophones
Je ne suis pas encore totalement satisfait de mon code car pour le moment le timer fonctionne en secondes. Il ne peut donc détecter que les Thread bloqués au minimum une seconde. Ce n’est pas l’idéal mais ça permet déjà de détecter les plus gros blocages.
Liens :
-
Le MDA c’est quoi ?
Je suis toujours étonné de lire autant de réticences à propos du MDA. Cette méthode est peut être victime d’une communication trop éloignée des problèmes concrets des développeurs. Alors soyons clairs, moi non plus je ne suis pas en phase avec les grands théoritiens. Deux exemples concrets :
J’ai participé il y a 3 ans à une présentation d’une thèse sur le MDA. J’ai vu pendant 1 heure des séries d’équations pour m’expliquer le principe du MDA. Au final, je n’ai pas vu une ligne de code et je suis sorti avec un beau mal de crâne.
Un autre expert MDA m’a très sérieusement expliqué qu’il passait par 3 à 4 transformations successives pour arriver au code Java. De plus pour lui le principe du « round trip » ne sert à rien car son modèle ne change jamais. Bien sûr son super architecte a pensé à tout et les petits développeurs n’ont pas besoin de réfléchir… On rève..
Si on vous a présenté le MDA de cette façon je comprends mieux vos griefs.
Mais pour moi le MDA c’est :
- Mettre le modèle au centre du pojet.
- Un outil pour produire mieux et plus vite.
- Une façon d’abstraire des mécanismes techniques complexes.
Il faut que le passage du modèle au code soit simple et rapide. Il faut aussi que ce soit le transformateur qui s’adapte au projet et non l’inverse. Là aussi j’ai vu trop d’outils imposer une façon de faire qui rebutait l’équipe de développeurs.
Oui on m’a déjà reproché de faire des PIM orientés Java et c’est aussi pour cette raison que l’on parle maintenant plutôt de MDD Model Driven Developpment. Mais mon objectif n’est pas d’être conforme à 100% avec la définition du MDA rédigée par l’OMG, mais bien de réaliser les trois points notés plus haut.
C’est assez paradoxal de pousser la modélisation UML et de mettre nos beaux modèles au placard lorsqu’ils sont terminés. C’est ça le MDA : s’appuyer sur un modèle pour structurer son développement.
-
Le MDA c’est Agile !
Je viens de lire un article intéressant résumant la soirée Paris JUG d’hier soir.
Et au milieu on peut lire : « non MDA n’est pas une méthode Agile »
Horreur ! Je ne peux donc pas m’empecher de réagir
Bien sur que le MDA aide à être plus agile ! Mais attention, il ne faut pas non plus trop écouter les puristes…
Je ne crois pas non plus à la notion « d’indépendance du langage »… c’est utopique, mais ça permet une certaine abstraction. C’est aussi une absurdité de mettre un fossé entre les développeurs et les architectes. L’architecte va oublier des choses dans le modèle, il faut laisser les développeurs l’aider à le compléter.Un exemple concret :
Il y a 4 ans j’ai commencé un projet avec des EJB 2 session et entity. Pour les personnes qui n’ont pas la chance de connaitre les EJB 2…. c’est atroce. Pour persister une classe il faut écrire 4 classes Java + des descripteurs xml.
Pour nous simplifier la vie nous avons modélisé notre système sans parler d’EJB. Un modele de haut niveau donc… un PIM.
Ensuite nous avons écrit un transformateur PIM-> PSM EJB 2 (15j de travail )
On génère classe Java + descripteurs EJB + script SQL.Et la c’était magique !!
1 - A la fin de la phase de modélisation, j’ai appuyé sur UN bouton et j’ai obtenu 100 % de mes squelettes de code Java. Sans aucun codage j’avais un EAR deployable !Attention ! cet EAR était bien une coquille vide, il est pour moi hors de question de modéliser le comportement. Il restait donc à notre équipe de développeurs à coder les services EJB.
Mais il était déjà deployable, on pouvait donc écrire des JUnits avant d’écrire l’implémentation.2 - Justement à propos de l’équipe… allez trouver sur le marché des développeurs EJB 2. (pas chers donc débutants…)
Et bien grâce à l’approche MDA nous avons pu prendre des débutants. En effet le coté EJB était transparent au début ils codaient de simples méthodes Java.Et au fur et à mesure ils sont montés en compétences sur les EJB 2 bien sur.
3 - Notre modèle est en phase avec notre code après 4 ans de dev… qui dit mieux ?
4 - Le MDA est agile !!
C’est une approche qui nous aide à être plus agile car elle facilite les changements.
Ajouter un attribut à un entity, c’est modifier 2 classes Java + un descripteur Java + un script SQL. Soit 4 chances d’oublier une modif ou de faire une erreur.
Avec nos outils MDA : une modif dans le modele + un clic = c’est fini.Pour finir : la cerise sur le gâteau.
L’année dernière nous avons migré nos EJB 2 vers de l’hibernate. Et bien nous avons juste changé de transformateur MDA… zero modif dans notre code.C’est pas de l’agilité ça !
-
Paris JUG et MD Day
Le mardi 8 Juillet à 20h15 une conférence sur le MDA est organisée au Paris JUG : Pourquoi tout le monde ne fait-il pas du MDA ?
Une très bonne question auquelle va essayer de répondre Grégory Weinbach d’Object Direct. J’ai eu l’occasion de rencontrer Grégory à propos d’Entreprise Architect car Object Direct en est le revendeur officiel en France. Je l’ai aussi vu au dernier MD Day où il présentait une solution mise en place au Crédit Agricole. Après ce premier MD Day il a ouvert un blog sur le MDA : http://mdblog.fr/.
Une autre date à réserver dès mintenant c’est le 25 novembre pour le prochain MD Day justement. Il aura lieu au Toit de la Grande Arche à Paris-La Défense. Les partenaires sont toujours les mêmes et après 6 mois d’utilisation d’Entreprise Architect je suis presque impatient de retrouver l’équipe d’Objecteering (j’ai dit presque.. 6 mois c’est pas assez long pour oublier mes pertes d’OFP et l’utilisation du module multi-user
).


