programmation gwt 2

Upload: ahmed-aniss

Post on 09-Apr-2018

231 views

Category:

Documents


0 download

TRANSCRIPT

  • 8/7/2019 Programmation GWT 2

    1/33

    Programmation

    GWT 2Dvelopper des applications RIAet Ajax avec Google Web Toolkit

    S a m i J a b e r

    Groupe Eyrolles, 2010

    ISBN : 978-2-212-12569-6

  • 8/7/2019 Programmation GWT 2

    2/33

    Toute lingniosit de GWT est davoir su construire un compilateur Java vers Java-Script. Un compilateur intelligent capable doptimiser et de gnrer du code tout enrespectant les prceptes de base du Web. Toute cette face cache de GWT est encoretrs mconnue du grand public, qui, aprs tout, na pas se soucier des implmenta-tions internes du compilateur. Et pourtant, les vraies ppites, la vraie beaut de ce

    framework rside dans cette partie passionnante de GWT. Pour celui qui saitdcrypter un minimum les nombreuses subtilits et configurations du compilateur,chaque fonctionnalit est une source dinspiration unique.

    Le compilateur GWT est en perptuelle volution car la taille du framework ne cessedaugmenter (il suffit dobserver le nombre de nouvelles API). Les utilisateurs nontde cesse de rclamer des applications ractives avec des temps de chargementinstantans ; impossible dans ce contexte de sassoir sur ses lauriers. Plus quune

    ncessit, lamlioration du JavaScript gnr par le compilateur est devenue pourchaque version une urgence vitale.

    Ce chapitre explore les nombreuses facettes du compilateur GWT et aborde la struc-ture des fichiers gnrs et les diffrentes optimisations. Un clairage particulier estapport au mcanisme permettant dtendre le processus de gnration pour yajouter des traitements spcifiques.

    12

    Sous le capot de GWT

  • 8/7/2019 Programmation GWT 2

    3/33

    Programmation GWT 2288

    Introduction au compilateur

    Le compilateur de GWT est lessence mme du framework. Lorsquon sait larichesse des sept mille classes du JDK, on ralise que celui qui ose imaginer un jourque ce langage peut produire du code JavaScript a du gnie.

    Mme sil est vrai quil existe des similitudes entre Java et JavaScript, certaines subti-lits peuvent poser problme. Java propose des classes, JavaScript des prototypes demthodes. Java dispose dun mcanisme despaces de nommage (les fameux pac-

    kages), JavaScript non. Java permet deffectuer des appels polymorphiques, ils sontplus complexes en JavaScript. Java est un langage typage statique, JavaScript unlangage typage dynamique.

    Malgr tous ces points, GWT russit marier ces deux langages sans briser aucunmoment leur smantique respective.

    Pour bien comprendre les subtilits du compilateur, analysons ce quil gnre sur descas triviaux.

    Vive les fonctions JavaScript !

    Prenons la classe Animal suivante. Elle contient un constructeur avec deux param-tres, deux variables membres et une mthode parle(). Nous invoquons dans lamthode onModuleLoad(), la mthode parle(), puis nous affichons une des deuxproprits par le biais dune alerte JavaScript.

    En Java, cela donne :package com.dng.client;

    public class Animal {String race ;public String getRace() {

    return race;}

    public void setRace(String race) {this.race= race;

    }

    int age ;

    public Animal(String race, int age) {super();

    this.race= race;

    http://app/CahiersTitres.pdfhttp://app/CahiersTitres.pdf
  • 8/7/2019 Programmation GWT 2

    4/33

    Sous le capot de GWT

    CHAPITRE12289

    Pour le compiler en JavaScript, nous utilisons le script Ant gnr par GWT lors dela cration du squelette projet. Ce script contient une tche gwtc laquelle nous

    ajoutons les options de compilation suivante draftCompile et style PRETTY. Lapremire demande au compilateur de ne pas trop optimiser le script cible. En pro-duction, cette option est proscrire, car elle a tendance gnrer un gros fichier. Enrevanche, pour des raisons pdagogiques, cela permet dobtenir une version fidle duJavaScript avant optimisation.

    La seconde option demande GWT dafficher un fichier source JavaScript lisiblenon obfusqu. Cela permet de mieux comprendre le contenu du script.

    this.age = age;

    }

    public void parle() {// En fonction de l'animal, aboie, miaule, etc.

    };}

    // Et la mthode onModuleLoad()public class CompilateurSample {

    public void onModuleLoad() {Animal a = new Animal("berger allemand",2);a.parle();Window.alert(a.getRace());

    }}

  • 8/7/2019 Programmation GWT 2

    5/33

    Programmation GWT 2290

    Voici le rsultat gnr par le compilateur aprs suppression de quelques mthodes

    techniques pour plus de clart :

  • 8/7/2019 Programmation GWT 2

    6/33

    Sous le capot de GWT

    CHAPITRE12291

    Quand on sattarde un instant sur le contenu de ce script, on comprend quel pointil est difficile de traduire en JavaScript les concepts objet existant dans le monde Java.

    La premire chose noter est labsence totale de dmarcation objet. En JavaScript,tout est fonction ! Et GWT la bien compris.

    Dans le listing prcdent, la mthode onModuleLoad() est bien prsente. Celle-cicommence par crer un objet de type $Animal lors de ltape . Dans le monde de

    lorient objet, une classe drivant dune superclasse appelle toujours le constructeurde sa classe mre lors de sa propre construction . Cest bien le cas dans le codeJavaScript : ltape invoque le constructeur de la classe Object.

    Enfin, les tapes et invoquent respectivement les mthodes parle() etgetRace(). Malgr certains dtails (comme la prsence systmatique du mot-clthis$static dans chaque fonction), ce code JavaScript est limpide.

    Les tapes du compilateur

    Nous allons ici dtailler les diffrentes tapes menant la gnration des artfactslors de la compilation dun programme GWT. Lide est ici de bien comprendre leprocessus doptimisation et le modle interne au compilateur.

    GWT a besoin du code source Java.

    Il y a un dbat rcurrent au sein des contributeurs GWT qui est celui du modle decompilation. lorigine, le choix a t de sappuyer sur le code source Java pourgnrer le JavaScript plutt que rutiliser le byte code. Nous ne discuterons pas ici dela pertinence de cette dcision. Il faut simplement savoir que GWT a besoin du codesource car il extrait certaines informations telles que le code JSNI. Une autre raisonavance par les crateurs de GWT est la possibilit doptimiser partir dinforma-

    tions prsentes uniquement dans le code source. Si on prend, par exemple, les typesgnriques (Class), ceux-ci sont rcrits par le compilateur.

    Voyons maintenant les diffrentes tapes intervenant lors de la compilation.

    function $onModuleLoad(){

    var a;a = $Animal(new Animal, 'berger allemand', 2); $parle();alert_0($getRace(a));

    }

    function CompilateurSample(){}

    -->

  • 8/7/2019 Programmation GWT 2

    7/33

    Programmation GWT 2292

    Lecture des informations de configuration

    La premire tape consiste charger rcursivement les informations contenues dansles fichiers de configuration de tous les modules. Cela inclut le module compil maisgalement lensemble de ses dpendances.

    Tous les paramtres lis aux diffrentes permutations de la liaison diffre (pro-prits, conditions, types), mais galement les ventuels scripts embarqus (ceux quidfinissent les valeurs des proprits) sont analyss.

    partir de mtadonnes extraites lors de ce parcours, GWT va gnrer les diff-rentes permutations.

    Cration de larbre syntaxique GWT

    La seconde tape consiste parcourir rcursivement lensemble des modules dpen-dant du module que lon souhaite compiler pour construire une sorte darbre syn-taxique en mmoire. Un arbre syntaxique est un modle objet spcifique qui a pour

    but de reprsenter un programme source au travers des diffrentes structures de con-trle qui le composent.

    En Java, il existe une sorte de standard dans ce domaine, le JDT (Java DevelopmentTool) issu de lIDE Eclipse. Comme le montre la figure suivante, il est possible de seservir du JDT pour crer un arbre syntaxique. JDT propose une API riche constituedes types IPackageFragment, ICompilationUnit, IType, IMethod, etc.

    Si les concepteurs de GWT avaient fait le choix de gnrer du code JavaScript partir du source Java, larbre JDT aurait constitu un candidat pour construire unarbre syntaxique (arbre AST) automatiquement.

    Mais au lieu de cela, il a fallu crer de zro un modle spcifique adapt aux con-traintes de GWT (fonctions JSNI, liaison diffre, etc.). Lors du parcours rcursif, lecompilateur examine le code source Java et construit en mmoire un arbre AST detype JProgram. Le schma suivant illustre globalement le concept : une mthode estcompose dun ou plusieurs blocs de programmes, chaque bloc est lui-mme com-

    Figure 121

    Loutil JDT(Java Development Tool)

    http://app/CahiersTitres.pdfhttp://app/CahiersTitres.pdf
  • 8/7/2019 Programmation GWT 2

    8/33

    Sous le capot de GWT

    CHAPITRE12293

    pos de variables, dexpressions ou de structures de contrles (condition, boucle,

    etc.). Bref, en fin danalyse, GWT dispose en mmoire dun arbre (potentiellementnorme) compos de lensemble des modules de lapplication (notez au passagelintrt de rduire les dpendances).

    Une fois cet arbre construit (quon nomme arbre unifi , car il nest li aucunepermutation), le compilateur ralise une prcompilation. Cest--dire quil substitueet gnre toutes les classes Java partir des rgles dfinies dans les mtadonnes(substitution de classe, gnration de code, etc.), lobjectif tant dobtenir un arbresyntaxique unifi auquel on accole des sous-arbres spcifiques. Notez que, lors decette opration, des optimisations interviennent dj car certaines rgles peuventconduire des permutations semblables.

    Une fois ces conditions runies, la compilation Java vers JavaScript proprement dite

    peut commencer.

    La gnration de code JavaScript et les optimisations

    Pour chaque permutation, GWT fusionne larbre unifi et les sous-arbres spcifiques chaque fois quil tombe sur linstruction GWT.create(). On pourrait penser que la gn-ration est finalement une banale conversion de code Java vers JavaScript mais il nen est

    rien. Une telle conversion aurait conduit GWT gnrer un fichier JavaScript de plu-sieurs dizaines de mga-octets, vu la taille initiale du framework GWT. Impensable.

    Figure 122

    Structure de larbre AST GWT

    RETENIR GWT ne gnre pas de permutations darbre

    aucun moment, GWT ne gnre n permutations en mmoire dun arbre syntaxique ; ce serait troplourd grer dun point de vue des performances. Il cre un seul arbre AST unifi puis lui associe desmtadonnes correspondant aux diffrentes rgles de substitution.

  • 8/7/2019 Programmation GWT 2

    9/33

    Programmation GWT 2294

    En ralit, lors de cette tape, un inexorable processus doptimisation dmarre. Un pro-

    cessus montr du doigt par des milliers (peut-tre un jour des millions) de dveloppeursGWT travers le monde. Les temps de compilation de GWT sont longs, et ce, parfoishorriblement. Mais lorsquon dcouvre ce qui se cache derrire cette phase indispen-sable, on en veut instinctivement moins GWT et on prend son mal en patience.

    Il ny a de meilleur exercice pdagogique que dexpliquer GWT travers son codesource. Voici la mthode compilePermutation() de la classe interneJavaToJavaScriptCompiler, excute lorsque lutilisateur dclenche une compila-

    tion. Cest srement lune des mthodes les plus importantes du framework. Toutesles tapes de la compilation y sont illustres, jugez-en par vous-mme :

    public static PermutationResult compilePermutation(, int permutationId){long permStart = System.currentTimeMillis();AST ast = unifiedAst.getFreshAst();()// Remplace tous les GWT.create() et gnre le code JavaScriptResolveRebinds.exec(jprogram, rebindAnswers);

    // Optimise un peu (plus rapide) ou beaucoup (forcment plus lent)if (options.isDraftCompile()) {draftOptimize(jprogram);

    } else {// Presse le citron de l'optimisation jusqu' ne plus pouvoir gagner d'octetdo {

    boolean didChange = false;

    // Enlve tous les types non rfrencs, champs, mthodes, variablesdidChange = Pruner.exec(jprogram, true) || didChange;

    // Rend tout "final", les paramtres, les classes, les champs, les mthodesdidChange = Finalizer.exec(jprogram) || didChange;

    // Rcrit les appels non polymorphiques en appels statiquesdidChange = MakeCallsStatic.exec(jprogram) || didChange;

    // Supprime les types abstraits// - Champs, en fonction de leur utilisation, change le type des champs

    // - Paramtres : comme les champs// - Paramtres de retour de mthode : comme les champs// - Les appels de mthodes polymorphiques : dpend de l'implmentation// - Optimise les conversions et les instanceofdidChange = TypeTightener.exec(jprogram) || didChange;

    // Supprime les types abstraits lors des appels de mthodedidChange = MethodCallTightener.exec(jprogram) || didChange;

    // Supprime les ventuelles portions de code mortdidChange = DeadCodeElimination.exec(jprogram) || didChange;

    http://app/CahiersTitres.pdfhttp://app/CahiersTitres.pdf
  • 8/7/2019 Programmation GWT 2

    10/33

    Sous le capot de GWT

    CHAPITRE12295

    if (isAggressivelyOptimize) { // On supprime les fonctions en dplaant leur corps dans l'appelant

    didChange = MethodInliner.exec(jprogram) || didChange;} while (didChange);

    }

    ()

    // Generate a JavaScript code DOM from the Java type declarations()JavaToJavaScriptMap map = GenerateJavaScriptAST.exec(jprogram, jsProgram,options.getOutput(), symbolTable);

    // Ralise cette fois des optimisations JavaScriptif (options.isAggressivelyOptimize()) {boolean didChange;do {

    didChange = false; // Supprime des fonctions JavaScript inutilises, possible

    didChange = JsStaticEval.exec(jsProgram) || didChange; // Inline JavaScript function invocations

    didChange = JsInliner.exec(jsProgram) || didChange;// Remove unused functions, possibledidChange = JsUnusedFunctionRemover.exec(jsProgram) || didChange;} while (didChange);}

    // Permet de crer une pile d'appels pour simuler la StackTrace JavaJsStackEmulator.exec(jsProgram, propertyOracles);

    // Casse le programme en plusieurs fragments JavaScript// (aka CodeSplitting)SoycArtifact dependencies = splitIntoFragment(logger, permutationId,

    jprogram, jsProgram, options, map);

    // Ralise l'opration d'obfuscation (OBFS, PRETTY, DETAILEDMap obfuscateMap = Maps.create();switch (options.getOutput()) {case OBFUSCATED: ()case PRETTY: ()case DETAILED: ()}

    // Gnre le rendu final au format texte.PermutationResult toReturn = generateFinalOutputText(logger, permutationId,

    jprogram, jsProgram, options, symbolTable, map, dependencies,obfuscateMap, splitBlocks);

  • 8/7/2019 Programmation GWT 2

    11/33

    Programmation GWT 2296

    Explicitons un peu ce morceau de code.

    La premire action consiste rsoudre les instructions GWT.create(). Puis le compi-lateur extrait loption draftCompile qui indique si lutilisateur souhaite rduire lenombre doptimisations au profit de la vitesse de compilation. Le JavaScript gnr

    dans ce mode est plus volumineux mais les temps de compilation moindres.En mode normal, la totalit des optimisations est applique de manire squentielletel un citron press jusqu ne plus pouvoir extraire une seule goutte. Mais pourquoirexcuter les optimisations de manire quasi infinie ? Ce qui est vrai linstant tnelest plus linstant t+1. Certaines optimisations ont pour effet de dtacher de larbreAST certaines classes qui deviennent aussitt candidates la rduction (pruning).Do lintrt ditrer constamment.

    Voici les tapes intervenant dans la compilation et invoques par la fonction prc-dente compilePermutation() : la rduction de code (pruning) ; la finalisation de mthodes et de classes ; la substitution par appels statiques ; la rduction des types ;

    llimination de code mort ; linlining.

    La rduction de code (pruning)

    La rduction de code est un procd qui permet de supprimer toutes les classes,mthodes, champs et paramtres non utiliss dans une application.

    Pour se faire une ide prcise de lefficacit du pruning, tablissons un parallle avec unautre framework, celui du SDK Java. Ce framework contient plus de 7 500 classes et il fautsavoir quen moyenne limmense majorit des projets Java utilisent environ 5 10 % desclasses du SDK. En pratique, cela signifie quil est possible de produire un JRE de 1 Mo.Sun a dailleurs dj commenc uvrer dans ce sens avec le framework RIA JavaFX.

    Si la rduction de code nexiste pas dans le monde Java proprement dit, cela est d enpartie linstanciation dynamique de classes. Avec Java, il est possible tout momentde crer des instances via le mcanisme de rflexion (Class.forName("classe") ouclass.newInstance()). Cette possibilit met fin de facto toute vellit doptimisa-tion via un framework allg.

    System.out.println("Permutation took "+ (System.currentTimeMillis() - permStart) + " ms");

    return toReturn;}

    http://app/CahiersTitres.pdfhttp://app/CahiersTitres.pdf
  • 8/7/2019 Programmation GWT 2

    12/33

    Sous le capot de GWT

    CHAPITRE12297

    Or, GWT prend comme hypothse que le chargement dynamique de classes estinterdit. Le compilateur a besoin de matriser lensemble de larbre syntaxique ainsique les tenants et aboutissants du code source. Dans ce contexte, le pruning apporteun gain considrable car il supprime ainsi les dizaines de classes prsentes dans leJRE mul de GWT. Aussi minime soit-il, sans le mcanisme de rduction, le fichier JavaScript gnr pourrait slever plusieurs dizaines de mga-octets dans uneapplication mtier complexe. Chose inconcevable.

    Voici titre dexemple un code source Java et le rsultat JavaScript opr aprs pruning.

    public class Animal { String race ;

    int age ;public String getRace() {

    return race;}

    public void setRace(String race) {this.race= race;

    }

    public int getAge() {return age;

    }

    public void setAge(int race) {this.age= age;

    }

    public Animal(String race, int age) {super();this.race= race;this.age = age;

    }

    public void parle() {// En fonction de l'animal, aboie, miaule, etc.

    };}

    // Classe onModuleLoad()public class CompilateurSample implements EntryPoint {

    public void onModuleLoad() {Animal a = new Animal("berger allemand",2);

    Window.alert(a.getRace());

    }

    }

  • 8/7/2019 Programmation GWT 2

    13/33

    Programmation GWT 2298

    Dans le code prcdent, nous nutilisons que la proprit race de la classe Animal.Voici ce que GWT gnre au niveau JavaScript :

    Le rsultat est patant. On ne trouve plus aucune trace de la proprit age, comme sielle navait jamais exist dans le code source. Le champ et les mthodes getAge() ouparle() et le paramtre du constructeur ont disparu !

    Vous dcouvrez l une des plus-values les plus importantes de GWT et comprenezpar la mme occasion pourquoi le chargement dynamique de classe est interdit.

    La finalisation de mthodes et de classesLapproche objet a pour principal avantage de fournir des mcanismes volus telsque lhritage et la redfinition mais souvent au dpend dune complexit dexcutionaccrue. Le simple fait de marquer une mthode finale en phase de dveloppementpermet au compilateur dinsrer (inlining) son contenu. Dans la pratique, cela con-siste supprimer la mthode pour dplacer son code dans lappelant (notammentpour les variables). Linlining libre de la mmoire en vitant de maintenir lexcu-

    tion une pile dappels et permet parfois dconomiser quelques lignes de code.Globalement, il est dailleurs recommand en Java de marquer systmatiquement unemthode ou une classe du mot-cl final si on est certain quelle ne sera pas redfinie.

    La substitution par appels statiques

    Mme si ce nest pas une optimisation en soit, la substitution statique modifie le code

    pour faciliter les prochaines optimisations.

    _ = Object_0.prototype = {};function $Animal(this$static, race){this$static.race = race;return this$static;

    }

    function Animal(){}

    _ = Animal.prototype = new Object_0;_.race = null;

    function init(){var a;a = $Animal(new Animal, 'berger allemand');$wnd.alert(a.race);

    }

    http://app/CahiersTitres.pdfhttp://app/CahiersTitres.pdf
  • 8/7/2019 Programmation GWT 2

    14/33

    Sous le capot de GWT

    CHAPITRE12299

    Cette tche consiste rechercher tous les appels non polymorphiques (cest--diremettant en uvre une mthode non redfinie) pour rcrire lappel en passant parune mthode statique. Le paramtre de cette mthode statique est linstance surlaquelle on souhaite invoquer la mthode.

    Au premier abord le principe peut paratre un peu tordu mais les bnfices sont pr-cieux.

    Voici un exemple :

    Compare une version polymorphique, la version statique prsente lavantage demettre plat les appels de mthodes en les transformant en fonctions basiques Java-Script. Par ailleurs, cela facilite non seulement les suppressions lorsquune oprationde rduction intervient (car on sait prcisment qui appelle quoi) mais permet degagner des octets en rcrivant le mot-cl this par une chane plus courte. Il fallaitsimplement y penser !

    La rduction de type

    La rduction de type ou Type Tighteningfait partie des autres optimisations gnialesdu compilateur GWT.

    Pour rsumer le principe en quelques mots, le compilateur infre les types les plusspcifiques pour mieux supprimer les types abstraits.

    Comme tout bon dveloppeur qui se respecte, nous utilisons rgulirement lesgrands principes de la programmation objet, les interfaces, les types abstraits ou lagnricit pour instaurer une forme de dcouplage entre classes. Une fois le type con-cret cr, il est dusage de prfrer linterface List la classe ArrayList ou linterfaceMap la classe HashMap.

    Le compilateur GWT ayant pour objectif principal la rduction de code, toute abstrac-tion va progressivement disparatre du source Java pour ne laisser place qu des types

    concrets. Ce processus commence par linspection des variables locales, des champs,

    // Code JavaAnimal instance = new Animal();instance.parle()// Est transform en JavaScript parfunction $Animal(instance){parle(instance);

    }function parle(instance){()

    }

  • 8/7/2019 Programmation GWT 2

    15/33

    Programmation GWT 2300

    des paramtres et des types de retour puis se poursuit par lanalyse de larbre syntaxiquepour analyser les changements intervenant sur un type (appels galement type flow).

    Lorsquun type ArrayList est cr la base, toutes les rfrences de type List sonttransformes en rfrences de type ArrayList avec pour effet immdiat dallger parle pruning le code gnr via la suppression des types abstraits.

    Certaines variables peuvent galement prtendre tre rduites, notamment cellesqui nont jamais t initialises ou celles qui contiennent null. Ces dernires ouvrentla voie de nombreuses optimisations possibles.

    Aprs la rduction gnralise de type ralise, le compilateur effectue la mme op-ration sur les appels de mthode polymorphique. Lors de cette tape, lambigut(quelle mthode de quelle classe appeler pour un hritage donn) qui existait avant larduction de type est leve.

    Llimination de code mort

    Llimination de code dit mort consiste supprimer tout code inatteignable outoute expression invariante. Ainsi lexpression "x || true" sera par exemple rem-place par "x".

    Mais cette limination va plus loin : elle remplace galement les post-incrmentationspar des pr-incrmentations, plus performantes (cela vite de stocker une variable tem-poraire), en sassurant bien videmment quaucun effet de bord nest gnr. Llimina-tion vrifie galement lutilisation des conditions (switch case), optimise les calculssur les boolens, optimise les expressions de type try{} catch{}, supprime le code desboucles condition constante de type while (faux) { //code }, et supprime les suc-cessions de break inutiles.

    Linlining

    Lorsquune mthode ne cre pas deffet de bord sur des parties tierces de lapplica-tion et que son contenu est suffisamment matris, le compilateur remplace la fonc-tion appele par son code. Cela simplifie les optimisations ultrieures et pargne lexcution une pile dappels complexe.

    Les mthodes getXX() ou setXX() sont souvent de bons candidats linlining.

    switch(i) { default: a(); b(); c(); } devient { a(); b(); c(); }switch(i) { case 1: a(); b(); c(); } devient if (i == 1) { a(); b(); c(); }switch(i) { case 1: a(); b(); break; default: c(); d(); }

    devient if (i == 1) { a(); b(); } else { c(); d(); }

    http://app/CahiersTitres.pdfhttp://app/CahiersTitres.pdf
  • 8/7/2019 Programmation GWT 2

    16/33

    Sous le capot de GWT

    CHAPITRE12301

    En voici un exemple :

    Magique non ?

    Tracer les optimisations

    Le compilateur fournit une option trs intressante permettant de tracer les diff-rentes optimisations observes sur une mthode. Le mode de trace sutilise en poin-tant le nom dune mthode de la manire suivante :

    Voici pour un exemple donn, le type daffichage produit par loption de trace. Lesmodifications de code ralises entre chaque optimisation sont en surbrillance :

    Forme f = new Carre(2);int a = f.getSurface()// Devient via le jeu de l'inliningForme f = new Carre(2);int a = f.length * f.length;// Puisint a = 4;

    java com.google.gwt.dev.compiler-Dgwt.jjs.traceMethods=com.dng.sample.onModuleLoad

    com.dng.CompilateurSample

    public abstract class Animal {

    String race;int age;

    public int getAge() {return age;

    }

    public void setAge(int age) {this.age = age;

    }

    public Animal() { }

    public Animal(String race, int age) {this.race = race;this.age = age;

    }

    public abstract String getRace();}

  • 8/7/2019 Programmation GWT 2

    17/33

    Programmation GWT 2302

    public class Chien extends Animal {String race = "BERGER ALLEMAND";

    @Overridepublic String getRace() {

    return race;}

    }

    public class CompilateurSample implements EntryPoint {

    public void onModuleLoad() {Animal a = new Chien();String race = a.getRace();

    Window.alert("La race du client est " + race);

    }}// La compilation gnre la trace suivante avec l'option active

    JAVA INITIAL:---------------------------public void onModuleLoad(){Animal a = (new Chien()).Chien();String race = a.getRace();Window.alert("La race du client est " + race);

    }---------------------------FinalizeVisitor:

    ---------------------------public final void onModuleLoad(){

    final Animal a = (new Chien()).Chien(); final String race = a.getRace();

    Window.alert("La race du client est " + race);}---------------------------JAVA INITIAL:---------------------------

    public static final void $onModuleLoad(CompilateurSample this$static){final Animal a = (new Chien()).Chien();final String race = a.getRace();Window.alert("La race du client est " + race);

    }(...)---------------------------TightenTypesVisitor:---------------------------

    public static final void $onModuleLoad(CompilateurSample this$static){ final Chien a = Chien.$Chien(new Chien());

    http://app/CahiersTitres.pdfhttp://app/CahiersTitres.pdf
  • 8/7/2019 Programmation GWT 2

    18/33

    Sous le capot de GWT

    CHAPITRE12303

    final String race = a.getRace();Window.alert("La race du client est " + race);

    }---------------------------PruneVisitor:---------------------------

    public static final void $onModuleLoad(){final Chien a = Chien.$Chien(new Chien());final String race = a.getRace();Window.alert("La race du client est " + race);

    }

    ---------------------------RewriteCallSites:---------------------------public static final void $onModuleLoad(){final Chien a = Chien.$Chien(new Chien());final String race = Chien.$getRace(a);Window.alert("La race du client est " + race);

    }---------------------------

    InliningVisitor:---------------------------public static final void $onModuleLoad(){final Chien a = (((()), new Chien()));final String race = (("BERGER ALLEMAND"));Window.alert("La race du client est " + race);

    }---------------------------DeadCodeVisitor:

    ---------------------------public static final void $onModuleLoad(){final Chien a = new Chien();final String race = "BERGER ALLEMAND";

    Window.alert("La race du client est BERGER ALLEMAND");}---------------------------CleanupRefsVisitor:---------------------------

    public static final void $onModuleLoad(){ new Chien(); "BERGER ALLEMAND";

    Window.alert("La race du client est BERGER ALLEMAND");}---------------------------DeadCodeVisitor:---------------------------public static final void $onModuleLoad(){

    Window.alert("La race du client est BERGER ALLEMAND");}

  • 8/7/2019 Programmation GWT 2

    19/33

    Programmation GWT 2304

    Les options du compilateur

    Le compilateur GWT est assez riche et ses options (comme la prcdente) pluttmconnues du grand public. La version 2 apporte son lot de nouveauts avec lintro-duction du mode draftCompile et les rapports de compilation.

    Tableau 121 Les options du compilateur

    Option Description

    -logLevel Spcifie le niveau de trace : ERROR, WARN, INFO, TRACE, DEBUG,

    SPAM, ou ALL

    -treeLogger Affiche les messages de sortie dans larbre du shell.

    -workDir Spcifie le rpertoire de travail du compilateur (doit tre en criture).Par dfaut, pointe vers le rpertoire temporaire du disque.

    -gen Le rpertoire contenant tous les fichiers sources gnrs par la liaisondiffre.

    -ea Enable Assertion. Prcise que le compilateur ne doit pas supprimer les

    assertions cres en Java lors de la compilation (certaines personnesprfrent ne pas propager les assertions en JavaScript pour gagner enperformances et en taille).

    -XshardPrecompile Optimisation qui va de paire avec les workers (permet dviter lesOutOfMemory durant la compilation de nombreuses permutations).

    -XdisableClassMetadata Exprimental : dsactive quelques mthodes dejava.lang.Class methods, notamment la mthodeClass.getName(), trs coteuse en JavaScript.

    Cette option permet de gagner 5 10 % de code JavaScript gnr.-XdisableCastChecking Exprimental : dsactive les vrifications de conversion lexcution

    (acclre les temps dexcution aux dpens de la scurit du code).

    -validateOnly Valide lensemble du code source mais ne le compile pas. Permet devrifier que la configuration des rgles et proprits de liaison diffreest correcte sans gnrer une compilation complte.

    -draftCompile Ralise moins doptimisations mais acclre la compilation.

    -compileReport Active les rapports de compilation.-localWorkers Spcifie le nombre de threads utiliser par permutation (permet de

    gagner en performance lorsque la compilation sexcute sur unemachine multicur).

    -war Le rpertoire contenant les diffrents fichiers de permutation et laracine du site.

    -extra Le rpertoire contenant les fichiers non dploys, appels encoreextra.

    -style Permet de produire du code JavaScript lisible ou crypt.

    http://app/CahiersTitres.pdfhttp://app/CahiersTitres.pdf
  • 8/7/2019 Programmation GWT 2

    20/33

    Sous le capot de GWT

    CHAPITRE12305

    Loption -extra permet de gnrer des fichiers non dploys en production et conte-nant diverses informations. Rpertoire rpcPolicyManifest : un fichier de policy est un fichier de mtadon-

    nes dtaillant lensemble des types RPC utiliss dans un module. Le fichierrpcPolicyManifest prcise pour plusieurs modules les chemins relatifs de leurfichier de policy respectifs.

    Rpertoire symbolMaps : contient une table de correspondances permettant deretrouver une classe partir de son nom obfusqu dans le fichier JavaScript. Cettetable sert essentiellement laffichage de la pile dappels en cas derreur. Ce sujetest couvert en fin de chapitre.

    Notez que loption compileReport gnre galement des artfacts dans le rpertoire

    war par dfaut.En plus des arguments classiques du compilateur, GWT utilise des proprits systmepour certaines oprations avances telles que le paramtrage des traces ou la suppres-sion des messages davertissement. Le tableau suivant illustre ces options systme.

    Figure 123

    Gnration des fichiers avecloption -extra

    Tableau 122 Options systme (certaines sont peu documentes)

    Proprit Description

    Proprits gnralesgwt.devjar Redfinit le rpertoire dinstallation de GWT.

    gwt.nowarn.legacy.tools Supprime le message davertissement indiquant uneversion obsolte des outils.

    gwt.nowarn.metadata Supprime le message davertissement relatif auxanciennes annotations Javadoc.

    gwt.perflog Demande dactiver la traabilit des performances.

  • 8/7/2019 Programmation GWT 2

    21/33

    Programmation GWT 2306

    Proprits lies au compilateur

    gwt.jjs.javaArgs Compilation parallle : redfinit des arguments ausous-processus (exemple : -Xmx, -D, etc.).

    gwt.jjs.javaCommand Compilation parallle : redfinit la commande permet-tant de lancer une nouvelle machine virtuelle (pardfaut : $JAVA_HOME/bin/java).

    gwt.jjs.maxThreads Compilation parallle : le nombre maximal de threadsutiliss par processus.

    gwt.jjs.permutationWorkerFactory Compilation parallle : il existe deux modes pour lan-cer la compilation, un mode multiprocessus avec plu-sieurs JVM, et un mode multi-threads dans la mmeJVM. Ce paramtre permet de prciser le mode sou-hait.

    gwt.jjs.traceMethods Gnre des messages explicites quant loptimisation

    dune mthode.Concerne le shell

    gwt.browser.default Dfinit le navigateur lancer par dfaut lors de lex-cution (supplante la variable systmeGWT_EXTERNAL_BROWSER).

    gwt.nowarn.webapp.classpath Supprime le message davertissement lorsque lappli-cation fait appel des classes situes dans leclasspath systme.

    gwt.dev.classDump Demande au compilateur dcrire toute classe instru-mente lors de la phase de compilation sur disque(utile par exemple pour analyser le contenu des typesJavaScriptObject).

    gwt.dev.classDumpPath Toute classe Java rcrite lors de la phase de compila-tion est gnre dans ce rpertoire.

    gwt.shell.endquick Ne demande pas de confirmation lors de la fermeturedu shell.

    Traabilit et gestion des versions

    gwt.debugLowLevelHttpGet Affiche des informations de dbogage lors des appelsAjax.

    gwt.forceVersionCheckNonNative Sous Windows seulement, utilise la version pure Java.

    gwt.forceVersionCheckURL Permet de passer une URL personnalise pour la ver-sion de GWT.

    Tableau 122 Options systme (certaines sont peu documentes) (suite)

    Proprit Description

    http://app/CahiersTitres.pdfhttp://app/CahiersTitres.pdf
  • 8/7/2019 Programmation GWT 2

    22/33

    Sous le capot de GWT

    CHAPITRE12307

    Acclrer les temps de compilation

    Vu la complexit des optimisations et le mode de fonctionnement du compilateur, cenest pas une surprise si lune des proccupations majeures des dveloppeurs GWTconcernent les temps de compilation. Avec GWT 2 et la possibilit de tester le code partir dun vrai navigateur, cette contrainte ne devrait plus rellement constituer unfacteur de blocage. En effet, dans cette version, la compilation relle nintervient que

    pour valider dfinitivement le rendu visuel dune application.Malgr tout, il existe plusieurs optimisations possibles, dont certaines ont t abor-des dans le chapitre sur la liaison diffre.

    Voici une liste dactions susceptibles de rduire en moyenne de 50 % le temps decompilation, voire 800 % dans certains cas :1 Rduire le nombre de permutations : GWT est paramtr par dfaut pour gn-

    rer 6 permutations (une par navigateur). Si on sait que seuls IE 7 et Firefox 3seront supports, il suffit de dfinir la proprit user.agent de la manire sui-vante dans le fichier de configuration du module :

    Ce paramtrage rduit en moyenne de 50 % les temps de compilation.2 Ajouter loption draftCompile lors de la compilation : en phase de dveloppe-

    ment les gains peuvent aller de 5 30 % en fonction des scnarios.3 Donner une valeur largument localWorkers : GWT 1.5 a introduit la notion

    de worker pour la compilation. Pour une machine bi-cur (Dual Core), une valeurparamtre 2 permet de parallliser la compilation des permutations sur chaquecur. Le gain est en moyenne de 10 %. Ce chiffre samliore progressivementdans le cas dune machine 4 curs (Quad Core).

    JUnit

    gwt.args Permet de passer des arguments au shell Junit.

    com.google.gwt.junit.reportPath Spcifie le chemin de gnration des rapports de ben-chmark.

    Tableau 122 Options systme (certaines sont peu documentes) (suite)

    Proprit Description

    P ti GWT 2

    http://app/CahiersTitres.pdfhttp://app/CahiersTitres.pdf
  • 8/7/2019 Programmation GWT 2

    23/33

    Programmation GWT 2308

    4 Configurer la JVM avec des paramtres adapts : pour une application moyenne,les options suivantes permettent dassurer suffisamment de mmoire, une taille depile cohrente et un espace de stockage temporaire adapt.

    Les linkersComme expos prcdemment, le processus de dploiement de GWT fait intervenirun certain nombre dtapes. La compilation gnre des fichiers de permutationplacs dans un sous-rpertoire du contexte web racine de lapplication. Une fois lapage hte appele, un script de slection est excut ralisant dans la foule le char-gement de la permutation correspondant aux proprits du navigateur.

    Si ce mode de fonctionnement convient dans la majeure partie des cas, il est quelque-fois utile de sinsrer dans le processus de gnration des fichiers pour y apporterquelques modifications. Imaginez par exemple un site GWT dploy sous la formedun portlet ou un gadget GWT proposant des mtadonnes avec un point dentrespcifique. De simples contraintes de dploiement (DMZ, rpertoires spcifiquespar ressources, etc.) requirent parfois la modification des fichiers gnrs par GWT.Dans lexemple suivant, qui reprsente le contrat dun gadget GWT, la mthodedinitialisation nest pas onModuleLoad() mais init() :

    java com.google.gwt.dev.Compiler -Xmx512M -Xss128k -Xverify:none-X:PermSize=32m Module

    @ModulePrefs(title = "Gadget GWT",directory_title = "Mon gadget GWT ",screenshot = "gadget.png",thumbnail = "thumb.png",height = 210)

    public class MyGWTGadget

    extendsGadget

    {public void onModuleLoad() { }// Remplac par la mthode d'initialisation suivanteprotected void init(

    final MyGWTGadgetPreferences prefs) {

    }

    }

    Sous le capot de GWT

    http://app/CahiersTitres.pdfhttp://app/CahiersTitres.pdf
  • 8/7/2019 Programmation GWT 2

    24/33

    Sous le capot de GWT

    CHAPITRE12309

    Voici la squence dappel des diffrentes composantes de la construction GWT. chaque tape correspond un ensemble dartfacts gnrs ou compils (les fichiers oumorceaux de code source).

    Lide sous-jacente aux linkers est de permettre au dveloppeur dinterfrer dans lemcanisme de construction et ddition des diffrents liens pour y apporter un traite-ment spcifique.

    Il faut savoir que GWT propose par dfaut cinq linkers dfinis dans le moduleCore.gwt.xml situ dans le fichier gwt-user.jar. Le SingleScriptLinker : uilis lorsquon souhaite gnrer un seul fichier Java-

    Script pour un module. Cela suppose quil nexiste quune seule permutation. Le XSLinker : utilis lorsque le serveur hbergeant les permutations est diffrentde celui hbergeant la page hte. Ce linker produit des fichiers dextension xscomme -xs.nocache.js.

    Le IFrameLinker : cest le linker principal utilis par GWT, il gnre une IFramecache.

    Le SymbolMapLinker : ce linker se charge de crer un fichier de correspondances

    permettant dafficher des piles derreurs pointant des noms de variables nonobfusques.

    Figure 124

    Fonctionnement des linkers

    Programmation GWT 2

    http://app/CahiersTitres.pdfhttp://app/CahiersTitres.pdf
  • 8/7/2019 Programmation GWT 2

    25/33

    Programmation GWT 2310

    Le SoycReportLinker : les rapports de compilation constituent lhistorique de lacompilation ; ce linker restitue des fichiers de traces contenant des mtriques liesaux optimisations.

    Voici un extrait de fichier de configuration (tir du code source de GWT) illustrantla dclaration dun linker et son ajout dans le projet courant.

    Ces linkers sexcutent dans un ordre dtermin par trois tats : avant(LinkOrder.PRE), pendant (LinkOrder.PRIMARY) et aprs (LinkOrder.POST).

    titre dexemple, le linker standard (IFrameLinker) qualifi dans le fichierCore.gwt.xml"std" est un linker primaire, cest--dire quil sexcute de manireautonome et produit un script de slection chargeant les permutations dans une IFramecache. Sa seule dpendance est celle lie son hritage. IFrameLinker, au mme titreque la plupart des linkers primaires drivent de la classe SelectionScriptLinker qui

    lui offre la gnration du script de slection. Il est bien videmment possible de red-finir tout moment le comportement des linkers prdfinis.

    Voyons maintenant concrtement un exemple de linker personnalis. Crer un linkerrevient :1 Crer une classe drivant de com.google.gwt.core.ext.Linker.2 Ajouter lannotation @LinkOrder pour dterminer si le linker doit sexcuter

    avant, aprs ou en remplacement du linker primaire. Le nombre de linkers nest

    pas limit, seul le primaire est unique.

    ()

    Sous le capot de GWT311

    http://app/CahiersTitres.pdfhttp://app/CahiersTitres.pdf
  • 8/7/2019 Programmation GWT 2

    26/33

    Sous le capot de GWT

    CHAPITRE12311

    3 Dfinir et ajouter le linker personnalis dans le fichier de configuration dumodule (.gwt.xml).

    4 Inclure dans le classpath du compilateur le nouveau linker.Le linker suivant rpertorie dans une chane de caractres lensemble des artfactsgnrs par le compilateur (permutation, images, etc.) suivi de la date de derniremodification. Il ajoute ensuite un nouvel artfact (un nouveau fichier) contenantcette chane. Lobjectif est de montrer ici un linker simple qui extrait des informa-tions du compilateur et cre de nouveaux fichiers en sortie.

    package com.dng.linkers;

    import java.util.Date;

    import com.google.gwt.core.ext.LinkerContext;import com.google.gwt.core.ext.TreeLogger;import com.google.gwt.core.ext.UnableToCompleteException;import com.google.gwt.core.ext.linker.AbstractLinker;import com.google.gwt.core.ext.linker.Artifact;import com.google.gwt.core.ext.linker.ArtifactSet;import com.google.gwt.core.ext.linker.EmittedArtifact;import com.google.gwt.core.ext.linker.LinkerOrder;

    @LinkerOrder(LinkerOrder.Order.POST)public class MyLinker extends AbstractLinker {

    public String getDescription() {return "MyLinker";

    }

    public ArtifactSet link(TreeLogger logger, LinkerContext context,ArtifactSet artifacts)

    throws UnableToCompleteException {String artifactList="";// Rcupre la liste de tous les artfactsArtifactSet toReturn = new ArtifactSet(artifacts);for (Artifact artifact : toReturn) {

    // Et trie seulement les fichiers gnrsif (artifact instanceof EmittedArtifact) {

    EmittedArtifact fic = (EmittedArtifact) artifact;// Stocke dans une chane de caractres le nom du fichier gnrartifactList = fic.getPartialPath() + "," + new

    Date(fic.getLastModified()).toString() + "\n" + artifactList ;}

    }

    Programmation GWT 2312

    http://app/CahiersTitres.pdfhttp://app/CahiersTitres.pdf
  • 8/7/2019 Programmation GWT 2

    27/33

    g312

    Lexcution du code prcdent produit la sortie suivante.

    La mthode link() est appele par le compilateur qui lui transmet le paramtreArtifactSet, une collection de lensemble des artfacts du module. Notez quun artfactnest pas ncessairement un fichier physique gnr dans le rpertoire de destination dumodule. Seules les ressources de type EmittedArtifact sont destines tre gnres.

    // Ajoute la liste prcdente un nouveau fichier recensant// les artfacts

    toReturn.add(emitString(logger, artifactList, "ListFiles.txt"));

    return toReturn;}

    }

    Figure 125

    Linker affichantla liste des artfactsgnrs par le compilateur

    Figure 126

    Les diffrents types dartfacts

    Sous le capot de GWT313

    http://app/CahiersTitres.pdfhttp://app/CahiersTitres.pdf
  • 8/7/2019 Programmation GWT 2

    28/33

    p

    CHAPITRE12313

    Dans le jargon des linkers, il existe plusieurs types dartfacts : la rsultante dune compilation (CompilationResult) contenant en mmoire des

    informations de permutation (flux JavaScript, cl MD5, etc.) ; les fichiers physiques (EmittedArtifact) gnrs dans le rpertoire de sortie du

    module (JavaScript, CSS, etc.) ; lanalyse de compilation (utilise ensuite par les rapports de compilation).

    Il est possible tout moment de sintercaler dans le processus de gnration pourmodifier ces artfacts. Diffrentes mthodes sont fournies dont certaines permettant

    de lire le JavaScript gnr, de le modifier ou simplement dajouter certaines infor-mations.

    Au-del du simple recensement dartfacts, il existe de nombreux scnarios dutilisationdes linkers. On pourrait ainsi imaginer un linker qui se chargerait de tlcharger desfichiers sur un serveur FTP distant en cas de compilation. Ou un autre qui aurait pourobjectif de dplacer les fichiers statiques dans un rpertoire donn (.cache.html) et lesfichiers dynamiques (ventuelles pages JSP) dans un autre rpertoire.

    Autre exemple, dans le cas o une seule permutation est gnre (comme pour unmobile IPhone ou Android), on pourrait imaginer un linker qui optimiserait les permu-tations pour embarquer le script de slection et la permutation au sein du mme fichier.Cela pargnerait une requte HTTP supplmentaire pour charger la permutation.

    Bref, le procd est relativement souple pour permettre tous types de personnalisation.

    La pile derreurs en production

    Java possde un mcanisme nomm la pile derreurs ou StackTrace qui fournit lutilisateur des donnes trs prcieuses sur le contexte dune exception. Ces informa-tions contiennent des informations sur la pile dexcution (quelle mthode a tappele avant lerreur) ou le numro de ligne incrimin et la nature de lexception.Malheureusement, lorsquil sagit dexception dans le monde JavaScript, les choses

    peuvent vite virer au cauchemar tant il existe dimplmentations diffrentes en fonc-tion des navigateurs.

    Ainsi, Firefox fournit une proprit exception.stack contenant le message, le nomde fichier et la ligne. Opera intgre dans le message ces trois informations et requiertune analyse de la chane de caractres pour extraire un format exploitable. Quant auxautres navigateurs, ils ne proposent tout bonnement rien de trs volu dans cedomaine part le type arguments et ses proprit arguments.callee etarguments.caller.callee.

    Programmation GWT 2314

    http://app/CahiersTitres.pdfhttp://app/CahiersTitres.pdf
  • 8/7/2019 Programmation GWT 2

    29/33

    314

    Voici titre dexemple un code JavaScript utilisant err.stack :

    Le rsultat sous IE 8, Firefox 3.5, Opera, Safari et Chrome est sans quivoque etdmontre la difficult dune gestion commune en JavaScript.

    function fonc1() {

    try { {

    var i = null;i.toto();

    }

    catch(err) { {window.alert(err.message + "\n" + err.stack)

    }

    }

    function fonc2() {

    fonc1();

    }

    Gnre exception

    Figure 127

    Les piles derreursnon uniformes

    Sous le capot de GWT315

  • 8/7/2019 Programmation GWT 2

    30/33

    CHAPITRE12315

    Le comportement des exceptions en production est alatoire et surtout peu explicite(cest videmment un doux euphmisme). Pour sen convaincre voici une copie

    dcran dune exception gnre manuellement.

    Vous aurez compris que le mcanisme dobfuscation est le coupable de ces hirogly-phes. En renommant systmatiquement les mthodes et variables des fins dopti-

    misation, GWT perd forcment en expressivit. On perd galement au passage lesnumros de lignes concernes par la pile.

    Tout lintrt de GWT va consister fournir le socle permettant dunifier (via laliaison diffre) la pile dappels et la gestion des erreurs. Ce procd sappelle lmulation de la pile et fait partie des nouveauts de GWT 2.

    Lactivation de cette fonctionnalit seffectue en positionnant vrai la propritcompiler.emulatedStack dj prsente dans le noyau de GWT au travers du modulecom.google.gwt.core.EmulateJsStack.

    Une fois lmulation active, les exceptions deviennent comme par magie beaucoupplus explicites. Seuls les noms de mthodes restent crypts. Voici un code Java levantune exception lors dun appel natif : voyons le rsultat en termes de restitution enmode production dans un navigateur.

    Figure 128

    Une exception gnre enmode obfusqu

    ()

    public void onModuleLoad() {try {

    fonc1();

    } catch (Exception e) {Window.alert(printStackTrace(e));

    Programmation GWT 2316

    http://app/CahiersTitres.pdfhttp://app/CahiersTitres.pdf
  • 8/7/2019 Programmation GWT 2

    31/33

    Lerreur est gnre dans la fonction fonc2() elle-mme appele par fonc1().Except les noms des mthodes, les numros de lignes et les noms des fichiers sourcesont cohrents.

    }}

    private String printStackTrace(Throwable e) {StringBuffer msg = new StringBuffer();msg.append(e.getClass() + ":" + e.getMessage() + "\n");for (StackTraceElement se : e.getStackTrace()) {

    msg.append("at " + se.getClassName() + "."+ se.getMethodName() + "(" + se.getFileName() + ":"+ se.getLineNumber() + ")\n");

    }

    return msg.toString();}

    public void fonc1() {fonc2();

    }

    private native void fonc2() /*-{// L'erreur a lieu ici

    func.toto();}-*/;

    Figure 129

    La pile derreurs aprsmulation par GWT

    Sous le capot de GWT

    CHAPITRE 12317

  • 8/7/2019 Programmation GWT 2

    32/33

    CHAPITRE12

    Il est fort probable qu lavenir GWT propose un mcanisme permettant de traduireune pile dappels obfusque via un appel RPC ou une API spcifique. En attendant,

    le plus simple est dactiver le mode Pretty avec pour rsultat de magnifiques piles.

    Table des symboles

    Nous lavons vu, le mode Pretty est une des solutions laffichage dune pile dappelslisible. En production, il nest pas toujours possible de lactiver car la taille du fichierJavaScript aura tendance grossir exagrment.

    Pour rpondre cette problmatique, GWT gnre un fichier texte contenant lesdiffrents symboles JavaScript gnrs par le compilateur ainsi que leur correspon-dance non crypte. Ce fichier est gnr dans le rpertoire paramtr via loptionextra. Son nom est celui de la permutation suffixe par .symbolMap.

    Il suffit de lire ce fichier pour obtenir le nom lisible dune mthode donne ainsi quesa localisation exacte dans le code source. Voici un exemple de fichier de symboles :

    Figure 1210

    La pile derreurset le mode Pretty

    # { 3 }# { 'user.agent' : 'gecko1_8' }# jsName, jsniIdent, className, memberName, sourceUri, sourceLineow,,boolean[],,Unknown,0pw,,byte[],,Unknown,0qw,,char[],,Unknown,0

    Programmation GWT 2318

    http://app/CahiersTitres.pdfhttp://app/CahiersTitres.pdf
  • 8/7/2019 Programmation GWT 2

    33/33

    terme, vous aurez compris que lide est de fournir des outils qui pourrontdcrypter une pile derreurs, et ce, simplement en sappuyant sur le contenu de latable des symboles.

    L,,com.dng.client.AsyncSample,,file:/C:/java/projects/AsyncSample/src/com/dng/client/AsyncSample.java,14

    S,com.dng.client.AsyncSample::$clinit()V,com.dng.client.AsyncSample,$clinit,file:/C:/java/projects/AsyncSample/src/com/dng/client/AsyncSample.java,14T,com.dng.client.AsyncSample::$onModuleLoad(Lcom/dng/client/AsyncSample;)V,com.dng.client.AsyncSample,$onModuleLoad,file:/C:/java/projects/AsyncSample/src/com/dng/client/AsyncSample.java,16U,,com.dng.client.AsyncSample$1,,file:/C:/java/projects/AsyncSample/src/com/dng/client/AsyncSample.java,18V,com.dng.client.AsyncSample$1::$clinit()V,com.dng.client.AsyncSample$1

    ,$clinit,file:/C:/java/projects/AsyncSample/src/com/dng/client/AsyncSample.java,18W,,com.dng.client.CRMScreen,,file:/C:/java/projects/AsyncSample/src/com/dng/client/CRMScreen.java,6X,com.dng.client.CRMScreen::$clinit()V,com.dng.client.CRMScreen,$clinit,file:/C:/java/projects/AsyncSample/src/com/dng/client/CRMScreen.java,6Y,com.dng.client.CRMScreen::$show(Lcom/dng/client/CRMScreen;)V,com.dng.client.CRMScreen,$show,file:/C:/java/projects/AsyncSample/src/com/dng/client/CRMScreen.java,7

    Z,,com.google.gwt.animation.client.Animation,,jar:file:/C:/gwthack/trunk/build/dist/gwt-0.0.0/gwt-user.jar!/com/google/gwt/animation/client/Animation.java,28cb,com.google.gwt.animation.client.Animation::$$init(Lcom/google/gwt/animation/client/Animation;)V,com.google.gwt.animation.client.Animation,$$init,jar:file:/C:/gwthack/trunk/build/dist/gwt-0.0.0/gwt-ser.jar!/com/google/gwt/animation/client/Animation.java,28