<<

GWT

Créer des applications web interactives avec Web Toolkit (versions 1.7 et 2.0)

Olivier Gérardin Directeur technique de Sfeir Benelux (groupe Sfeir)

Préface de Didier Girard Directeur des opérations et de l'innovation de Sfeir Paris (groupe Sfeir) 978-2-10-054628-2 Préface

JavaScript : je t’aime, moi non plus Depuis que je développe des sites ou des applications web, j’ai toujours recherché la technologie qui me permettrait de développer des sites web avec la meilleure expérience utilisateur. La raison est simple, meilleure est l’expérience utilisateur et plus il y a de chances pour que l’internaute revienne. ’est tellement simple, c’est tellement vrai. Cette quête permanente de la meilleure technologie fait certainement de moi un technophile. Je n’en suis pas moins un technophobe : la technologie ne m’intéresse pas pour ce qu’elle est, mais pour ce qu’elle me permet de créer. Ainsi, chaque mois je teste un grand nombre de « nouveautés qui vont révolutionner le monde du développement logiciel » et j’en rejette autant avec tout le dégoût provoqué par la perte du temps consacré. Pour tester une technologie, mon approche est simple, quinze minutes pour comprendre, une heure pour faire un Hello World et huit heures pour résoudre un problème qui me tient à cœur. C’est ainsi qu’au fil des années, j’ai développé des sites web en Shell, , SSJS, ASP, .NET, Flex et . Année après année, une technologie revenait sur mon banc de test : sa puissance, son universalité, sa simplicité me plaisait. Pourtant, après quelques heures ’utilisation, je n’avais qu’une envie : la jeter par la fenêtre. Cette technologie était JavaScript. Pendant des années mes sites ont donc contenu le minimum syndical de JavaScript et je voyais arriver la vague comme un raz de marée qui allait m’engloutir faute de pouvoir aimer le cœur de cette approche.

GWT : Bon pour l’utilisateur, bon pour le développeur GWT va me sauver. Sur le papier, cette technologie pensée par Google correspond à ce que j’attendais : bonne pour l’utilisateur, bonne pour le développeur. En cinq minutes, j’ai compris son fonctionnement et sa puissance « coder en java, compiler en JavaScript » ; en quinze minutes, j’ai fait mon premier Hello World ; en huit heures j’ai développé une application qui me semblait impossible à réaliser quelques heures auparavant. J’étais conquis. L’accueil par les développeurs Web 2.0 était pourtant mitigé, l’approche adoptée par GWT blessait les puristes ou les influenceurs du Web : JavaScript n’était plus considéré comme un langage pour le Web, mais VI GWT

comme un simple assembleur permettant d’exécuter le Web. L’intensité du rejet par ces puristes était sans doute à l’échelle du potentiel de GWT qui : • propose une bonne expérience utilisateur ; • est facile d’utilisation ; • est compatible avec les meilleurs environnements de développement ; • aide à résoudre des problèmes difficiles de manière simple et efficace ; • est soutenu par une communauté enthousiaste et en expansion rapide ; • facilite la maintenance ; • garantit une bonne performance ; • est fun ; • est gratuit et libre d’utilisation.

Et nous : Invention et Innovation En créant GWT, Google ouvre une nouvelle ère du développement et rend accessible à tous les développeurs la réalisation de sites web de nouvelle génération. Cette invention permet d’améliorer la satisfaction client tout en innovant, c’est pour cela que je l’ai adoptée et que je la conseille à mes clients.

Ce livre Il existait actuellement beaucoup d’ouvrages en anglais sur GWT, il manquait un ouvrage en français qui permette aux nombreux développeurs francophones de découvrir cette technologie et ces concepts dans leur langue. C’est ce que propose Olivier avec talent. Présenter une technologie n’est jamais aisée, les livres sont souvent trop techniques ou pas assez, c’est selon. Ce livre a le bon dosage, il vous permettra à la fois de bien débuter avec la technologie mais aussi d’approfondir les concepts importants afin de développer des applications ayant la qualité requise pour une utilisation en entreprise. Je le conseille donc à toute personne qui veut bien démarrer avec GWT, que ce soit dans le cadre d’une activité de veille technologique, dans le cadre du démarrage d’un projet ou dans le cadre de monitorat. Bonne aventure technologique, Didier Girard http://www.google.com/search?q=Didier+Girard Table des matières

Préface ...... V

Avant-propos ...... XIII

Première partie – Développer avec GWT

Chapitre 1 – De HTML à GWT ...... 3 1.1 AucommencementétaitHTML ...... 3 1.1.1 La notion d’URL ...... 4 1.1.2 La technologie derrière les pages ...... 5 1.2 L’apparition despagesdynamiques...... 5 1.2.1 CGI ...... 6 1.2.2 Server-side Scripting : PHP & Cie ...... 6 1.2.3 Java côté client : les applets ...... 6 1.2.4 Les servlets et JSP ...... 7 1.2.5 Client-side Scripting et JavaScript...... 7 1.2.6 Du vrai client-serveur en JavaScript : XmlHttpRequest et AJAX ...... 9 1.3 L’étapesuivante: GoogleWeb Toolkit ...... 9 1.3.1 Les challenges ...... 9 1.3.2 Les réponses de GWT ...... 10 1.3.3 L’historique de la plate-forme...... 11 VIII GWT

Chapitre 2 – Hello, GWT ...... 13 2.1 L’environnement de développement...... 13 2.1.1 Les plugins GWT ...... 15 2.2 Installation...... 15 2.2.1 Le choix de la plate-forme ...... 15 2.2.2 Installation d’...... 16 2.2.3 Installation de GWT ...... 16 2.2.4 Google Plugin pour Eclipse ...... 17 2.3 Anatomied’unprojetGWT ...... 18 2.3.1 Nommage des packages et structure des dossiers ...... 18 2.3.2 La page HTML hôte ...... 19 2.3.3 Le point d’entrée ...... 20 2.3.4 Le fichier module...... 21 2.4 Hello,GWT...... 22 2.4.1 Création du projet...... 22 2.4.2 Création du module GWT ...... 24 2.4.3 Création du point d’entrée ...... 27 2.4.4 Création de la page HTML hôte...... 28 2.4.5 Lancement de l’application ...... 29

Chapitre 3 – Développer avec GWT ...... 31 3.1 Hosted mode vs web mode ...... 31 3.2 ContraintessurlecodeJava...... 32 3.2.1 Support du langage ...... 32 3.2.2 Émulation des classes du JRE ...... 33 3.3 Lancerenmodehôte...... 35 3.3.1 Le serveur d’applications intégré ...... 36 3.4 Compileretlancerenmodeweb...... 36 3.4.1 Les fichiers générés par le compilateur GWT ...... 37 3.5 Développementavecl’IDE...... 38 3.5.1 Debug et cycle de développement ...... 39 Table des matières IX

Chapitre 4 – Widgets, panels, etc...... 41 4.1 Uneinterface graphiquedynamique...... 41 4.1.1 Les widgets GWT...... 42 4.1.2 GWT et les aspects graphiques ...... 42 4.2 Widgetsetpanels...... 43 4.2.1 Événements et Handlers ...... 43 4.2.2 Widgets simples ...... 44 4.2.3 Panels ...... 60

Chapitre 5 – Communiquer avec le serveur...... 71 5.1 Codeclientvscodeserveur...... 71 5.2 LesprincipesdeGWTRPC...... 72 5.2.1 Classes et interfaces mises en jeu ...... 73 5.3 Lacréationd’unservicepasàpas...... 74 5.3.1 Écriture des interfaces et de l’implémentation ...... 74 5.3.2 Déploiement sur le serveur embarqué ...... 76 5.3.3 La réalisation d’un appel RPC ...... 77 5.4 Exemplecomplet...... 78 5.5 Utilisationd’unserveurexterne ...... 81 5.6 Contraintesdesérialisation...... 82 5.6.1 Types sérialisables déclarés par l’utilisateur ...... 83 5.7 Lesexceptions...... 83

Deuxième partie – Aller plus loin avec GWT

Chapitre 6 – Internationalisation ...... 89 6.1 Les possibilités d’internationalisation de GWT...... 89 6.1.1 Importer le module I18N ...... 90 6.2 Internationalisation « statique » ...... 90 6.2.1 L’interface Constants ...... 91 6.2.2 Gestion des locales multiples ...... 96 6.2.3 Annotations...... 102 6.2.4 L’interface ConstantsWithLookup ...... 103 X GWT

6.2.5 L’interface ...... 104 6.3 Leformatagedesdatesetnombres...... 105 6.3.1 NumberFormat ...... 105 6.3.2 DateTimeFormat ...... 106

Chapitre 7 – Mécanismes avancés du compilateur ...... 107 7.1 JSNI(JavaScript Native Interface)...... 108 7.1.1 Le principe ...... 108 7.1.2 Écrire une méthode JSNI ...... 108 7.1.3 Accéder à des objets Java depuis JSNI ...... 108 7.1.4 Règles de passage de paramètres ...... 110 7.1.5 Traitement des exceptions ...... 110 7.2 Deferred Binding ...... 110 7.2.1 Principes...... 110 7.2.2 Mise en oeuvre du Deferred Binding ...... 112

Chapitre 8 – Le mécanisme d’historique de GWT...... 115 8.1 Leproblème...... 115 8.2 L’approchedeGWT...... 116 8.2.1 URL et fragment...... 116 8.2.2 Encoder l’état de l’application ...... 116 8.2.3 Mise en oeuvre ...... 117 8.3 Unexemple...... 117 8.3.1 Créer une entrée dans l’historique ...... 117 8.3.2 Réagir à un événement historique ...... 118 8.4 LewidgetHyperlink...... 119

Chapitre 9 – Envoyer des requêtes HTTP...... 121 9.1 Au-delàdeGWTRPC...... 121 9.2 RequêtesHTTPenGWT...... 122 9.2.1 Réalisation d’un appel HTTP ...... 122 9.3 ManipulationdeXML...... 124 9.3.1 Le DOM XML ...... 124 9.3.2 Parsing d’un document XML ...... 124 Table des matières XI

9.3.3 Création d’un document XML ...... 125 9.4 ManipulationdeJSON...... 126 9.5 Accèsàdes web services JSON ...... 128 9.6 Proxyserveur...... 131

Chapitre 10 – Créer ses propres widgets...... 133 10.1 Sous-classerun widget existant...... 134 10.2 Utiliserlaclasse Composite...... 134 10.3 Implémenter complètement un widget en Java...... 135 10.4 Implémenter tout ou partie d’un widget en JavaScript...... 136

Chapitre 11 – Bibliothèques tierces ...... 139 11.1 Bibliothèquesdecomposants...... 139 11.1.1 GWT-ext ...... 139 11.1.2 Ext-GWT ...... 145 11.1.3 SmartGWT...... 149 11.1.4 Autres composants ...... 149 11.2 Bibliothèquesutilitaires...... 152 11.2.1 Gwittir ...... 152 11.2.2 GWT Server Library ...... 152 11.2.3 Google API ...... 152

Chapitre 12 – GWT 2.0 ...... 159 12.1 Obtenirla dernièreversion deGWT...... 160 12.1.1 Prérequis ...... 160 12.1.2 Génération de GWT ...... 161 12.2 OOPHM...... 161 12.2.1 Utilisation ...... 164 12.3 Code splitting &SOYC...... 166 12.3.1 Insérer un split point...... 166 12.3.2 Story Of Your Compile (SOYC) ...... 168 12.3.3 Optimiser avec le code splitting ...... 172 XII GWT

12.4 UiBinder...... 174 12.4.1 Utilisation ...... 174 12.4.2 Un exemple ...... 176 12.5 ClientBundle...... 178

Annexes ...... 179 Liste des classes de la bibliothèque d’émulation JRE (chapitre 3)...... 181 Exemple de FlexTable avec cellule baladeuse (chapitre 4) ...... 184 Exemple d’appel à un service RPC (chapitre 5) ...... 186 Exemple de mise en œuvre du mécanisme d’historique (chapitre 8) ...... 188 Appel à un service web JSON (chapitre 9) ...... 191 Exemple d’utilisation de l’API Google (chapitre 11) ...... 194 Exemple d’utilisation d’UiBinder pour créer un widget composite (chapitre 12) ...... 197

Webographie ...... 199

Index ...... 201 Avant•propos

Le , ou GWT, est apparu en 2006 un peu comme un OVNI sur la scène du développement d’applications dites RIA (Rich Internet Applications) ou « Web 2.0 ». En effet, il ne rentrait dans aucune des catégories d’outils existant alors pour faciliter le développement de ce genre d’applications. Était-ce un framework web de plus ? Non... Une énième bibliothèque de composants JavaScript ? Non... Une nouvelle plate-forme nécessitant encore un plugin pour fonctionner dans le navigateur ? Non plus... GWT est fondé sur un concept tellement original qu’il n’a pas convaincu grand monde à l’époque : développer et mettre au point en pur Java, et traduire en JavaScript au moment de déployer l’application sur le Web. Les avantages : on développe dans un langage familier et avec un typage fort (Java), dans un environnement familier (son IDE préféré – Eclipse, NetBeans, peu importe), avec des concepts familiers (boutons, panels, listeners, MVC, etc.) ; par conséquent la courbe d’apprentissage pour des développeurs Java est très rapide. D’autre part, toute la complexité de l’adaptation aux différents navigateurs est entièrement assumée par le traducteur Java-JavaScript, et le cauchemar de la prise en compte des différentes variantes de JavaScript entre Firefox, IE, , n’est plus qu’un souvenir. GWT est la traduction technique de la vision qu’a Google des technologies du Web 2.0 : « The browser is the platform » (le navigateur est la plate-forme). GWT n’impose pas de nouveau runtime (pas de plugin nécessaire), il profite de l’infrastructure et des outils en place, et s’intègre parfaitement dans les architectures et avec les technologies existantes. Il offre une transition idéale entre le développement classique et le développement d’applications RIA, avec un investissement humain et technique minimal. La promesse semble trop belle pour être vraie, et pourtant... difficile de lui trouver des défauts : si les premières versions souffraient de quelques problèmes, GWT n’a cessé de progresser, et depuis la version 1.4, on peut considérer qu’il est totalement fiable et efficace, et l’a prouvé sur de nombreux projets. La licence initiale, jugée restrictive par certains, a été remplacée par la licence Apache 2.0, considérée comme une des plus libérales de l’Open Source, ce qui garantit la pérennité du produit. Le XIV GWT

groupe de discussion consacré à GWT compte plus de 20 000 membres, preuve de la vitalité de la plate-forme. J’ai personnellement découvert GWT en 2006, et l’approche m’a immédiatement séduite car elle me permettait enfin de réconcilier la création d’applications AJAX avec l’univers Java qui est le mien depuis de nombreuses années. Cela signifiait surtout qu’il serait désormais possible de mener à bien un projet de ce type en se passant (enfin) d’un « expert JavaScript », ce magicien qui connaît par cœur les subtilités (et les bugs) des différentes implémentations dans les navigateurs, et les astuces qui permettent de les contourner... Si l’approche de GWT m’a séduite, j’avoue avoir eu des doutes sur son applicabi- lité : comment émuler fidèlement la bibliothèque Java du Java Runtime Environment (JRE) ? Comment gérer la généricité ? Comment tester le code ? Les différences entre le langage interprété qu’est JavaScript et le langage compilé qu’est Java ne seront-elles pas rédhibitoires ? Et qu’en sera-t-il des performances ? Cependant, comme à son habitude, Google a fait taire mes doutes en apportant des réponses techniques adéquates, efficaces et innovantes, et c’est sans doute ce qui a fait de GWT un produit réellement utilisable, et pas seulement un concept original. À ce jour, cela fait deux ans que je participe à des projets mettant en œuvre GWT, et sur chacun d’eux il a fait la preuve de sa maturité de la meilleure manière : en se faisant oublier... une fois la configuration en place, il devient un rouage de la mécanique, et permet de se concentrer sur les problématiques propres à l’application. L’intérêt des développeurs pour GWT est fort, mais malheureusement la littérature francophone sur le sujet est rare. J’espère donc au travers de ce livre vous donner toutes les clés qui vous permettront de vous mettre à GWT.

À qui s’adresse ce livre ? Ce livre s’adresse principalement aux développeurs Java ayant un minimum d’ex- périence et qui veulent découvrir et mettre en œuvre Google Web Toolkit. Une connaissance de base du langage Java est requise, ainsi que des principales technologies du Web : HTTP, HTML et CSS, JavaScript. Pour les aspects client-serveur, une connaissance des principes de JEE (Java Enter- prise Edition) est souhaitable, même si nous essayerons d’en rappeler les principales notions lorsque nous y aurons affaire. Avant•propos XV

Comment est structuré ce livre ? Ce livre est découpé en deux parties : • La première partie expose les bases qui permettent de comprendre GWT et de réaliser une application complète : – en situant GWT dans son contexte et en expliquant ses ambitions et le cheminement qui a conduit à son apparition (chap. 1) ; – en montrant comment mettre en place l’environnement logiciel nécessaire et créer un premier projet GWT (chap. 2). Vous y apprendrez également la façon de développer et déboguer avec GWT (chap. 3) ; – en présentant les éléments de construction d’une application GWT, aussi bien graphiques (widgets, chap. 4) qu’architecturaux (communication avec le serveur, chap. 5). • La deuxième partie explorera des concepts avancés qui ne sont pas forcément nécessaires dans toutes les applications GWT, mais qui peuvent répondre à une problématique spécifique : – les possibilités d’internationalisation de GWT (chap. 6) ; – les possibilités avancées du compilateur : JSNI pour incorporer du code JavaScript dans des méthodes Java, et le deferred binding pour générer des versions de code optimisées pour chaque environnement (chap.7); – la gestion de l’historique du navigateur (chap. 8) ; – les possibilités d’envoi direct de requêtes HTTP (chap. 9). On y verra aussi comment manipuler XML et JSON avec GWT ; – les différentes manières de créer ses propres composants graphiques (chap. 10) ; – l’utilisation de bibliothèques tierces avec GWT, que ce soit pour enrichir la palette de composants d’interface utilisateur ou pour fournir d’autres fonctionnalités (chap. 11) ; – enfin, le chapitre 12 qui fera un tour d’horizon des nouveautés de GWT 2.0.

Si la première partie est plutôt linéaire, la seconde peut être consultée indépen- damment et servir de référence.

Remerciements Ce livre n’aurait pas été possible sans la patience de mon épouse, qui a supporté les nombreuses heures durant lesquelles j’étais plongé dans la rédaction de cet ouvrage. Merci également à Didier Girard pour avoir eu l’amabilité de rédiger la préface, pour m’avoir mis en contact avec l’éditeur et pour ses conseils toujours précieux.

PREMIÈRE PARTIE

Développer avec GWT

1 De HTML à GWT

Objectif Dans ce chapitre, nous verrons comment le Web « original » a été conçu, quelles technologies sont apparues pour le rendre plus dynamique et permettre l’émergence d’applications web. Nous verrons quels inconvénients ces technologies possèdent, et comment GWT propose une solution élégante à la création d’applications web dynamiques.

1.1 AU COMMENCEMENT ÉTAIT HTML

Le Web est un concept tellement familier que nous le manipulons quotidiennement pour la plupart d’entre nous. Mais le Web d’aujourd’hui est passablement différent du Web tel qu’il a été imaginé par ses concepteurs, et tel qu’il a vu le jour. Le Web, ou World Wide Web comme on l’appelait encore il n’y a pas si longtemps, est un concept inséparable de celui d’hypertexte. Pour schématiser, l’hypertexte, c’est du contenu (au sens large : texte, images, médias), augmenté de liens qui permettent de passer d’une ancre (l’origine du lien) à la cible du lien (un autre document). L’hypertexte a été implémenté de plusieurs manières, indépendamment du WWW, notamment dans des systèmes propriétaires et fermés. Tous les documents liés se trouvaient alors dans une base unique, permettant de créer des systèmes documentaires plus riches qu’une collection de simples documents, mais limités à leur propre domaine. La véritable révolution est née de la combinaison d’un langage de description de page (HTML pour Hypertext Markup Language), d’un protocole de transfert approprié aux contenus hypertextes (HTTP pour Hypertext Transfer Protocol), et d’un réseau de données à l’échelle mondiale, l’Internet. Il devenait alors possible de créer des pages 4 Chapitre 1. De HTML à GWT

avec un contenu « riche » (texte et images), incluant des liens vers n’importe quelle autre page, du même site ou d’un autre site quelque part sur la planète.

L’invention du Web L’histoire retiendra que le Web a été conceptualisé au début des années 1990 au CERN à Genève, par Tim Berners•Lee, un physicien anglais, et Robert Cailliau, un informaticien belge. Dès 1990, s’appuyant sur les concepts hypertextes existants, ils envisagent de construire une « toile » reliant des nœuds constitués de pages hypertextes, accessibles au travers de « browsers » sur un réseau. Le concept se concrétise en 1992 avec l’apparition des premiers sites web, et se popularise dès 1993 avec la disponibilité du premier browser graphique, Mosaic, qui remplace avantageusement Lynx, son prédécesseur, un browser uniquement textuel. Dès lors, le nombre de sites et de pages web ne cessera d’augmenter. http://news.netcraft.com/archives/web_server_survey.html

1.1.1 La notion d’URL

Un concept essentiel à la réussite du Web est la notion d’URL, Uniform Resource Locator. Dans le WWW, une URL est une chaîne de caractères formalisée qui est la façon normalisée de désigner une ressource accessible via le Web (en général une page HTML, mais ce n’est pas obligatoire). Une URL est constituée de plusieurs parties, dont certaines sont optionnelles et d’autres non. Dans sa forme la plus commune, une URL se présente de la manière suivante :

http://code.google.com:80/webtoolkit/overview.html On reconnaît les parties suivantes :

• http est le schema qui désigne le protocole à utiliser. À noter que sa valeur conditionne aussi le format du reste de l’URL ; on se limitera ici à la description des URL de type « http » ; • code.google.com est le hostname, c’est-à-dire la désignation de la machine qui héberge la ressource ; • 80 est le port IP à utiliser pour la connexion ; • le reste de l’URL constitue le chemin d’accès à la ressource sur le serveur.

Additionnellement, on peut encore trouver à la suite du chemin :

• une query string commençant par un point d’interrogation ? et spécifiant la valeur de certains paramètres de la ressource, par exemple des critères de recherche : http://www.google.com/search?q=gwt ; • un indicateur de fragment, commençant par un symbole dièse #, qui désigne une sous-partie de la ressource. Dans les pages HTML, cet indicateur est utilisé pour désigner un signet, c’est-à-dire un marqueur dans la page (début de section par exemple). 1.2 L’apparition des pages dynamiques 5

L’URL joue un rôle essentiel dans le WWW car : • elle permet la création de liens hypertextes : la cible de tout lien est désignée par son URL ; • elle permet l’inclusion de ressources (par exemple des images dans une page HTML) en les désignant par leur URL.

Contrairement à un système fermé où la cible d’un lien appartient forcément au système au même titre que la source, le WWW permet de désigner n’importe quelle ressource, quel qu’en soit le propriétaire, au travers de cette chaîne de caractères qu’est l’URL.

1.1.2 La technologie derrière les pages Grâce au WWW et à la notion d’URL, il est donc aisé de saisir une « adresse web » sous forme d’une URL dans un navigateur, et d’accéder à la page correspondante. Que se passe-t-il exactement quand nous tapons une adresse dans un navigateur pour accéder à un site web ? L’URL est alors « déréférencée », c’est-à-dire interprétée et utilisée pour obtenir son contenu. La séquence des événements est la suivante : 1. L’URL est parsée et ses composants isolés. 2. Si le hostname est indiqué par son nom, une requête DNS est faite pour obtenir l’adresse IP correspondante. 3. Une connexion TCP est établie vers cette machine, sur le port spécifié (ou un port par défaut qui dépend du protocole, 80 pour HTTP). 4. Une requête HTTP est construite et envoyée au serveur via la connexion ouverte. Cette requête peut contenir un certain nombre d’informations, mais elle contient en particulier le chemin relatif du document accédé (dans notre exemple, /webtoolkit/overview.html). 5. Le serveur répond en renvoyant une réponse HTTP. Si tout est correct, la réponse contient le document demandé, ainsi que d’autres informations, en particulier un type MIME qui indique le type du document. 6. En fonction du type MIME de la réponse, le navigateur interprétera le contenu différemment : par exemple s’il s’agit de HTML, il va parser et afficher le document ; s’il s’agit d’un fichier PDF, il proposera de l’ouvrir ou de le sauvegarder, etc.

1.2 L’APPARITION DES PAGES DYNAMIQUES

Si ce système fonctionne de façon satisfaisante, il s’agit alors de pages statiques, c’est-à-dire de pages HTML stockées sous forme de fichiers, et servies telles quelles au client. Le besoin apparaît de générer la réponse à une requête HTTP dynamiquement, par l’exécution de code côté serveur, plutôt que par le simple contenu d’un fichier HTML immuable. 6 Chapitre 1. De HTML à GWT

1.2.1 CGI

La norme CGI (Common Gateway Interface) résulte d’une idée simple : le résultat de l’appel à une URL est fourni par l’exécution d’une commande du système d’exploitation. La norme spécifie que les paramètres de la requête (la query string) sont passés à la commande sous forme d’une variable d’environnement ; la sortie standard de la commande est capturée et constitue le résultat qui sera renvoyé au client. C’est la configuration du serveur web qui détermine quelles sont les commandes qui sont ainsi exécutables ; en général un sous-répertoire nommé cgi-bin est désigné et toutes les URL qui pointent vers ce chemin sont considérées comme désignant une commande CGI à exécuter plutôt que comme un fichier dont le contenu doit être renvoyé. Si CGI permet effectivement de générer des pages dynamiques et a été pendant des années le fondement du Web dynamique, il souffre de plusieurs problèmes dont le principal est une inefficacité liée à son principe même : chaque requête déclenche l’exécution d’une commande au niveau de l’OS, et donc le lancement d’un processus. Or la création d’un processus est une opération assez coûteuse en termes de ressources et de temps, et CGI s’est avéré peu adapté lorsqu’il s’agit de monter en charge.

1.2.2 Server•side Scripting : PHP & Cie

Dans le sillage de CGI, d’autres technologies pour rendre dynamique tout ou partie de la page HTML sont apparues, faisant appel à des mécanismes de scripting côté serveur. On retiendra celui qui a le mieux réussi : PHP. PHP propose d’inclure à l’intérieur même de la page HTML des balises spéciales qui sont destinées à être décodées par le serveur. Entre ces balises, du code PHP, un langage interprété et qui est devenu au fil des ans très riche en termes de bibliothèques intégrées. Le serveur web, en général au travers d’un module dédié, reconnaît la présence de code PHP dans une page et l’exécute. Le code PHP peut à son tour produire du HTML dynamique qui sera inclus dans la page retournée au client. Cette technologie a beaucoup d’avantages, notamment la versatilité et la relative simplicité du langage PHP, et la possibilité pour un utilisateur de mettre en ligne lui-même des pages PHP sans compromettre la sécurité. C’est ce qui a fait son succès jusqu’à aujourd’hui. Cependant, PHP reste interprété et donc relativement peu efficace.

1.2.3 Java côté client : les applets

Lorsque le langage Java a été introduit par Sun, sa première application a été la possibilité d’insérer des mini-applications à l’intérieur même d’une page HTML : les applets. Ces mini-applications pouvaient disposer de toute la puissance et la richesse de Java, fournir une interface graphique évoluée avec les composants AWT (et plus tard ), ou bien dessiner directement en mode bitmap. 1.2 L’apparition des pages dynamiques 7

Est-ce que l’interactivité, le dynamisme et la richesse des interfaces web seraient finalement apportés par les applets Java ? Malheureusement, les applets ont rapidement et injustement été rangées dans la catégorie « gadgets animés qu’on peut mettre dans un coin d’une page web ». Les raisons de ce semi-échec sont multiples : • le support de Java dans les navigateurs n’était pas universel à l’époque, et était souvent associé à un temps de démarrage important ; • l’implémentation de Java fournie par Microsoft présentait des différences importantes avec celle de Sun qui rendaient difficile la création d’une applet fonctionnant à la fois avec la JVM () de Sun et celle de Microsoft ; • l’interaction entre l’applet et le reste de la page est la plupart du temps inexistante, car très complexe à mettre en place.

1.2.4 Les servlets et JSP

Pour répondre au problème de scalabilité des pages dynamiques, que CGI et PHP ne résolvent pas de façon satisfaisante, Sun a imaginé le concept de servlet. Une servlet est un composant logiciel (une classe Java) qui est écrit spécifiquement pour répondre à une requête HTTP. La norme spécifie très précisément comment s’effectue l’invocation des servlets, la transmission des paramètres à la requête et en retour du résultat renvoyé par la servlet. L’énorme avantage en comparaison de CGI est que chaque requête est traitée dans un fil d’exécution (thread), ce qui épargne le coût de la création systématique d’un processus. Le serveur contrôle strictement le nombre de threads présents et la distribution des requêtes aux threads au travers d’un dispatcher. Les pages JSP (Java Server Pages) sont intimement reliées aux servlets — bien qu’elles se présentent sous une apparence semblable à une page PHP, c’est-à-dire du HTML dans lequel des balises spéciales introduisent des parties dynamiques —, puisqu’elles sont en fait compilées sous forme de servlet à leur première utilisation. On pourrait dire que servlets et JSP sont donc deux visages de la même technologie, ou plus exactement que JSP est une autre façon d’écrire des servlets. Cependant, dans la mesure où les documents renvoyés par les servlets/pages JSP restent des pages HTML complètes, l’interactivité n’est que peu améliorée en regard des pages servies par CGI ou PHP, puisque la moindre action de l’utilisateur qui nécessite une requête au serveur doit passer par une action de submit HTML et le rechargement complet de la page. Tout au plus a-t-on optimisé le temps de réponse du serveur.

1.2.5 Client•side Scripting et JavaScript

Pour franchir un pas dans l’interactivité, il fallait une technologie capable d’exécuter du code côté client, pour pouvoir réagir aux événements qui se produisent dans le navigateur (frappe d’une touche, changement du focus, clic sur un bouton, etc.). Ainsi 8 Chapitre 1. De HTML à GWT

est apparue la balise HTML

Dans l’exemple ci-dessus, la ligne importante est la ligne en gras ; elle charge le script JavaScript de bootstrap qui va initialiser toute la mécanique GWT. monappli désigne le nom du module GWT qui contient la description de l’application (nous y reviendrons plus loin). Comme vous le voyez, le contenu de la page peut rester totalement vierge ; dans ce cas, c’est le code JavaScript qui créera tous les éléments visuels d’interaction via le DOM. Cependant, GWT peut aussi s’intégrer facilement dans une page HTML existante : il suffit pour cela d’y ajouter l’élément

Titre statique

URL:
Résultat :

Ici une partie de la page est construite par le HTML présent dans le fichier, le reste sera généré par le code GWT. Le cas échéant, si aucun des éléments n’est identifié, on peut toujours accéder à la « racine » de la page HTML et s’y « greffer » grâce à la méthode RootPanel.get().

2.3.3 Le point d’entrée

Tout comme une application Java classique, une application GWT possède un « point d’entrée ».

Dans le cas d’une application Java classique, il s’agit d’une méthode public static main(String args[]) dans une classe quelconque, que vous passez en paramètre à la commande java pour démarrer l’application. Dans le cas de GWT, il s’agit d’une méthode avec le profil public void onModule- Load(). Contrairement à la méthode main décrite ci-dessus, onModuleLoad() n’est pas static. En fait, la classe qui contient le point d’entrée doit implémenter l’interface com.google.gwt.core.client.EntryPoint, qui contient la seule méthode onModule- Load(). Cela signifie qu’avant d’appeler onModuleLoad(), la classe doit être instanciée par GWT ; à cet effet elle doit exposer un constructeur public sans arguments. 2.3 Anatomie d’un projet GWT 21

Une autre différence importante avec une application classique : il est possible avec GWT de définir plusieurs points d’entrée. Ceux-ci seront déclarés dans la configuration du module GWT, et lors de l’initialisation de GWT, chacune des classes déclarées comme point d’entrée sera instanciée et sa méthode onModuleLoad() appelée.

2.3.4 Le fichier module

Jusqu’à présent, nous avons considéré une application GWT comme monolithique ; mais que se passe-t-il si on veut composer une application de plusieurs parties indépendantes et réutilisables ? C’est pour cette raison qu’existe la notion de module. Selon les propres termes de Google, un module est « l’unité de configuration » GWT. Cela signifie qu’un module comprend tout ce qui est nécessaire pour compiler, exécuter, déployer, réutiliser votre projet GWT. Le module est défini au travers d’un fichier XML, dans lequel on trouvera en particulier : • la liste des classes contenant un point d’entrée à instancier; • les modules « hérités » selon la terminologie GWT ; il s’agit en vérité des modules utilisés par votre module (par exemple des bibliothèques de composants externes). À noter que les différents « thèmes » graphiques, c’est-à-dire l’ha- billage de base des composants, sont considérés comme des modules externes ; • le source path, c’est-à-dire la liste des packages qui doivent être convertis en JavaScript lors de la compilation GWT. Les sous-packages d’un package du source path sont automatiquement inclus dans le source path ; par exemple si on désigne com.sfeir.gwt.client, les éventuels packages com.sfeir.gwt.client.xxxxx seront aussi inclus dans le source path. Par défaut, le source path comprend le sous-package nommé client immédiatement en dessous de l’endroit où se trouve le fichier XML du module.

Remarques À propos du point d’entrée : Si le module GWT est destiné à être utilisé par d’autres modules, il est parfaitement licite de ne définir aucun point d’entrée. En revanche, tout module référencé directement dans une page HTML (au travers de la balise SCRIPT) doit contenir au moins un point d’entrée. À propos du source path : Grâce à cette technique, il est parfaitement possible de « partager » certaines classes entre la partie « client » d’une application GWT (convertie en JavaScript) et le reste du code, notamment la partie serveur. Néanmoins, il faut garder à l’esprit les contraintes qui pèsent sur le code convertible (voir § 3.2 Contraintes sur le code Java).

Le fichier de module a un suffixe .gwt.xml. Il peut se trouver n’importe où dans le classpath du projet, mais il est conseillé de le placer dans le package racine de votre projet. 22 Chapitre 2. Hello, GWT

Voici un exemple de fichier module tel que généré par GWT :

L’attribut rename-to de l’élément module est important, car il permet de définir un « alias » au nom logique du module, qui est utilisé en particulier comme dossier de base pour tous les fichiers générés par la compilation JavaScript. En l’absence de rename-to, le nom du module est le nom du package dans lequel il se trouve suivi de son nom (sans .gwt.xml) ; par exemple, si le module se trouve dans le fichier GwtSkeleton.gwt.xml, situé dans le package oge.gwt.skel, le nom logique du module est oge.gwt.skel.GwtSkeleton. Avec l’attribut rename-to de notre exemple, le nom logique du module devient gwtskel.

2.4 HELLO, GWT

Nous allons maintenant assembler les éléments vus ci-avant (page hôte, module, point d’entrée) et construire un premier projet GWT minimaliste, au moyen d’Eclipse et de Google Plugin.

2.4.1 Création du projet

Dans Eclipse, créez un nouveau projet : Menu File > New... > Projet. Une liste de types de projets vous est proposée ; choisissez Dynamic Web Project puis cliquer sur Next (figure 2.1).

Donnez un nom au projet (« GwtChap24Hello » par exemple), et laissez les autres paramètres à leur valeur par défaut. Cliquez sur Next (figure 2.2). 2.4 Hello, GWT 23

Figure 2.1 — Choix du type de projet

Figure 2.2 — Options de création 24 Chapitre 2. Hello, GWT

Dans l’écran suivant, spécifiez « war » comme valeur pour Content Directory. Ceci est important pour que les réglages d’Eclipse correspondent à ceux de GWT. Cliquez sur Finish (figure 2.3).

Figure 2.3 — Options du module web

2.4.2 Création du module GWT

Le projet est maintenant créé, il reste à activer le Google Plugin pour ce projet. Pour cela, faites un clic droit sur le projet puis sélectionnez Google > Web Toolkit Settings. Dans la fenêtre qui s’ouvre, cochez la case Use Google Web Toolkit, et sélectionnez la version à utiliser. Cliquez sur OK (figure 2.4). Créez un package racine pour le projet : clic droit sur le projet puis sélectionnez New > Package. Nommez-le par exemple oge.gwt.chap24.hello, puis cliquez sur Finish (figure 2.5). On va maintenant créer un module GWT : clic droit sur le projet, puis sélectionnez New > Other... 2.4 Hello, GWT 25

Figure 2.4 — Propriétés GWT du projet

Figure 2.5 — Création d’un nouveau package 26 Chapitre 2. Hello, GWT

Dans la fenêtre qui s’ouvre, choisissez Google Web Toolkit > Module puis cliquez sur Next (figure 2.6).

Figure 2.6 — Création d’un nouveau module GWT

Dans l’écran suivant (New GWT Module): • cliquez sur Browse en face de Package et sélectionnez la package que vous avez créé ci-avant ; • dans Module Name, donnez un nom à votre module, par exemple HelloGwt (figure 2.7) ; • cliquez sur Finish ; le fichier module HelloGwt.gwt.xml est créé et ouvert. Vous pouvez noter que le sous-package client a été créé automatiquement.

Figure 2.7 — Options de création du nouveau module 2.4 Hello, GWT 27

2.4.3 Création du point d’entrée

On doit créer au minimum une classe avec un point d’entrée pour initialiser l’applica- tion. Pour cela, faites un clic droit sur le projet et New > Other... Dans la fenêtre qui s’ouvre, choisissez Google Web Toolkit > Entry Point class puis cliquez sur Next (figure 2.8).

Figure 2.8 — Création d’un point d’entrée

Dans l’écran suivant, donnez un nom à la classe : HelloGwt et laissez les autres paramètres par défaut. Cliquez sur Finish (figure 2.9).

Figure 2.9 — Options de création du point d’entrée 28 Chapitre 2. Hello, GWT

Vous pouvez noter qu’une ligne référençant le point d’entrée a été ajoutée dans le fichier module. Pour vérifier que le point d’entrée est bien invoqué, ajoutez la ligne suivante dans la méthode onModuleLoad() de la classe qui vient d’être créée :

RootPanel.get().add(new Label("Ca marche !"));

2.4.4 Création de la page HTML hôte

Reste à créer la page HTML hôte : clic droit et New > Google Web Toolkit > HTML Page puis Next (figure 2.10).

Figure 2.10 — Création d’une page HTML hôte pour GWT

Donnez un nom à la page : Hello.html. Laissez les autres paramètres par défaut et cliquez sur Finish (figure 2.11).

Figure 2.11 — Options de création de la page 2.4 Hello, GWT 29

2.4.5 Lancement de l’application

Voilà, tout est en place... Pour lancer l’application, il suffit de faire un clic droit puis de sélectionner Run As > Web Application ; si tout est correct, l’application se lance en hosted mode, ce mode spécial qui permet d’exécuter le code Java GWT sans le transformer en JavaScript (nous y reviendrons dans le chapitre suivant). Vous devriez voir la fenêtre « shell » du mode hôte présentée en figure 2.12, et la fenêtre « navigateur » qui affichera la page hôte et au final notre label, en figure 2.13.

Figure 2.12 — Fenêtre shell du hosted mode

Figure 2.13 — Fenêtre navigateur

Certes cette première application GWT ne fait pas grand chose d’utile, mais l’infrastructure est en place pour commencer à coder...

3 Développer avec GWT

Objectif Le développement avec GWT est sensiblement différent du développement Java standard, de par la nature de l’environnement ciblé (navigateur web). Dans ce chapitre, nous allons voir quelles sont les différences avec le développement Java standard et comment GWT permet au développeur de travailler au quotidien.

3.1 HOSTED MODE VS WEB MODE

À la fin du chapitre précédent, nous avons lancé notre application minimaliste au travers d’une configuration de lancement (launch configuration) créée pour nous automatiquement par le Google Plugin. Nous avons vu que cette application s’est exécutée dans une fenêtre intitulée « Google Web Toolkit hosted mode ». En réalité, le « mode hébergé » (hosted mode) est une des deux façons d’exécuter une application GWT : dans ce mode, c’est le code Java compilé (bytecode) qui s’exécute directement dans une JVM (Java Virtual Machine, machine virtuelle Java) comme pour une application classique. Cependant, il ne s’agit pas d’une application classique puisqu’elle est destinée au final à être utilisée dans un navigateur web ; le principe même est que toute son interface utilisateur repose sur la création et la manipulation de la page HTML au travers de l’API DOM. Comment alors cette application peut-elle s’exécuter directement en Java ? Le hosted mode embarque en fait un moteur de rendu HTML comme celui qu’on trouve dans les navigateurs web, à ceci près qu’il est spécialement modifié pour pouvoir exécuter nativement le code Java compilé, là où un navigateur classique ne comprend 32 Chapitre 3. Développer avec GWT

que le JavaScript. Dans la version Windows de GWT, ce moteur est celui d’Internet Explorer ; dans la version Mac, il s’agit de WebKit, le moteur de base de Safari, et dans la version Linux, une version modifiée de Mozilla. L’exécution d’une application GWT en hosted mode a un énorme avantage : comme il s’agit de pur Java, il est possible de positionner des points d’arrêt (breakpoints) là où on le désire, de démarrer l’application en mode debug, de faire de l’exécution en pas à pas, d’examiner le contenu des variables, etc. Toutes choses que quiconque s’est essayé à la programmation JavaScript directe appréciera... À noter que si votre application comprend une partie serveur (ce qui sera très probablement le cas), ceci s’applique aussi au code serveur, pour peu que le serveur soit aussi du code Java qui puisse tourner en mode debug. La plupart des IDE Java fournissent une bonne intégration avec les serveurs d’application et facilitent cet usage. Autre intérêt non négligeable : après une modification du code, un simple clicsur le bouton Refresh du navigateur hosted mode recharge l’application avec les modifications. Ceci autorise des cycles codage/test courts, car la compilation en JavaScript n’est pas, elle, des plus rapides. Le postulat central de GWT, c’est que si votre application fonctionne comme attendu en mode hôte, alors après sa compilation en JavaScript elle se comportera exactement de la même manière dans les navigateurs supportés (et à quelques excep- tions près, c’est généralement le cas). Par conséquent, en tant que programmeur GWT vous passerez probablement la plupart de votre temps à exécuter votre application en mode hôte, et ne la compilerez en JavaScript que de temps en temps pour vérifier que tout fonctionne comme prévu sur la plate-forme finale.

3.2 CONTRAINTES SUR LE CODE JAVA

Le principe même de GWT, c’est-à-dire le fait que le code que vous écrivez ne sera pas le code final qui sera exécuté dans le navigateur, mais qu’il devra passer par une étape de transformation en JavaScript et ne tournera pas dans une JVM mais dans un interpréteur JavaScript, impose certaines contraintes et limitations lors du développement. Ces contraintes portent sur le langage lui-même, ainsi que sur les classes du Java Runtime Environment (JRE, environnement d’exécution Java) qui sont utilisables.

3.2.1 Support du langage

Lorsque vous développez le code client d’une application GWT, l’ensemble des possibilités du langage Java est disponible, y compris l’utilisation des génériques, des annotations et plus généralement des nouveautés apportées par Java 5. Cependant, il faut garder à l’esprit que la cible est JavaScript, et certaines carac- téristiques de Java ne disposent pas d’équivalent en JavaScript. Parmi les principales différences qui sont les plus susceptibles de nécessiter une attention particulière, on peut citer les suivantes. 3.2 Contraintes sur le code Java 33

-thread : Le modèle d’exécution de JavaScript est mono-thread (un seul fil d’exécution), et donc votre application le sera aussi. Le mot-clé synchronized est accepté par le compilateur GWT, mais n’a aucun effet. De même, il est impossible de démarrer un nouveau thread via la classe Thread. Cette limitation aura des conséquences importantes sur la façon d’accéder à des services distants (RPC). • Pas de réflexion : Java permet de charger une classe dynamiquement à l’exécution, par exemple grâce à Class.forName(), et l’instancier grâce à Class.newInstance() ; cette possibilité n’existe pas en JavaScript, car la totalité des classes utilisées doit être connue par le compilateur GWT au moment de la compilation. Attention, car cela peut sembler fonctionner très bien en mode hôte, et ce n’est que lors de l’exécution en mode web que cela produira une erreur. De même, il est impossible dans le code client d’énumérer les propriétés ou méthodes d’une classe. • Gestion des exceptions : Le support des exceptions est similaire à celui de Java, avec toutefois quelques différences notables. En particulier, certaines exceptions non contrôlées (unchecked) comme NullPointerException, StackO- verflowException ou OutOfMemoryException ne sont jamais levées dans le code JavaScript ; à la place une exception générique JavaScriptException est levée. Les valeurs qui pourraient être nulles doivent donc être testées explicitement (comme ça devrait être toujours le cas en bon Java...). D’autre part, l’exception levée en JavaScript est relativement pauvre en informations; getStackTrace() par exemple ne retourne malheureusement rien de très exploitable, ce qui peut s’avérer gênant dans le cas où une exception se produit dans la version JavaScript de votre code mais pas dans sa version Java... heureusement ce cas est rarissime. • Support partiel de long : le type long n’est pas supporté en JavaScript ; cependant cela n’est pas un problème dans le code qui est compilé en JavaScript, car le compilateur GWT gère cela de façon totalement transparente (grâce à une paire d’int) ; il faut toutefois en être conscient lorsqu’il s’agit de communiquer avec du JavaScript natif via JSNI. • Pas de support de finalize : JavaScript ne supporte pas la finalisation durant le passage du ramasse-miettes (garbage collector) ; par conséquent, la méthode finalize n’est jamais exécutée.

3.2.2 Émulation des classes du JRE Le code Java qu’on peut écrire utilise en permanence, qu’on en soit conscient ou non, des classes et des méthodes qui font partie de la bibliothèque de base du JRE. Ces classes sont celles qui permettent de manipuler les objets natifs tels que String ou Integer, mais aussi les exceptions, les collections, etc. Pour pouvoir exécuter en JavaScript l’équivalent de ce que votre code Java effectue avec ces classes, le code JavaScript doit pouvoir accéder à un équivalent de la bibliothèque de base du JRE ; c’est le rôle que remplit la bibliothèque d’émulation JRE de GWT. Cette bibliothèque consiste en un ensemble de classes JavaScript, qui reproduit (« émule ») de façon aussi précise que possible le comportement de leurs équivalents du JRE, dans les limites que permet JavaScript. 34 Chapitre 3. Développer avec GWT

Sont compris dans cette bibliothèque :

• la quasi totalité du package java.lang, qui comprend l’essentiel des classes de base de Java, ainsi que java.lang.annotation ; • une grande partie du package java.util, y compris les collections ; • quelques classes des packages java.io et java.sql. Il n’est toutefois pas question d’écrire des fichiers ou d’accéder à une base SQL, mais simplement de faciliter la compatibilité.

Classes émulées La table accessible en annexe 1 contient la liste des classes présentes dans la biblio- thèque d’émulation JRE de GWT. Attention, dans certains cas, seul un sous-ensemble des méthodes de la classe est implémenté. La liste complète des méthodes peut être consultée sur la page : http://code.google.com/webtoolkit/doc/1.6/RefJreEmulation.html

Autres différences Il existe d’autres domaines pour lesquels l’émulation de GWT diffère du Java standard : • le support des expressions régulières (regexp) est légèrement différent entre Java et JavaScript ; GWT ne cherche pas à reproduire pas en JavaScript le comporte- ment des expressions régulières Java, mais s’appuie sur l’implémentation native de JavaScript. Ceci s’applique notamment aux méthodes String.replaceAll() et String.split(). Il convient donc lorsqu’on appelle ces méthodes de s’assurer qu’on utilise des expressions régulières qui ont la même sémantique en Java et en JavaScript ; • la notion de sérialisation en Java s’appuie fortement sur la réflexion qui, on l’a vu, n’est pas disponible en JavaScript. La sérialisation Java n’est donc pas utilisable dans le code client ; cependant, un mécanisme similaire existe dans le but d’invoquer des méthodes distantes via RPC (voir le chapitre 5 à ce sujet).

Classes utilitaires Pour certaines classes du JRE dont l’émulation aurait été trop coûteuse, GWT fournit un équivalent « light » qui offre une fonctionnalité similaire mais simplifiée :

• com.google.gwt.i18n.client.DateTimeFormat supporte un sous-ensemble de la fonctionnalité de java.util.DateTimeFormat ; • com.google.gwt.i18n.client.NumberFormat supporte un sous-ensemble de la fonctionnalité de java.util.NumberFormat ; • com.google.gwt.user.client.Timer fournit une fonctionnalité similaire à java.util.Timer, adaptée à l’environnement mono-thread.

L’utilisation des classes DateTimeFormat et NumberFormat est détaillée au § 6.3 Le formatage des dates et nombres. 3.3 Lancer en mode hôte 35

3.3 LANCER EN MODE HÔTE

Le hosted mode est implémenté dans la classe com.google.gwt.dev.HostedMode, qui se trouve dans le fichier gwt-dev-mac.jar (ou gwt-dev-windows.jar ou gwt-dev- linux.jar, selon votre plate-forme de développement). Pour démarrer une application GWT en mode hôte, il suffit d’exécuter une commande de la forme :

java -XstartOnFirstThread com.google.gwt.dev.HostedMode -startupUrl HelloGwt.html HelloGwt.gwt.xml

HelloGwt.gwt.xml désigne le module principal de votre application, qui contient toutes les informations nécessaires à l’exécution. Le paramètre startupUrl quant à lui désigne une page web à ouvrir au démarrage, normalement la page hôte de votre application. Bien sûr, pour que cette commande fonctionne, le classpath doit inclure le JAR gwt-dev-xxx.jar, ainsi que tout le code client, en particulier le fichier de module. Heureusement, il existe des façons plus simples de lancer une application en mode hôte. Comme nous l’avons vu dans le chapitre précédent, le Google Plugin ajoute à Eclipse un type de run configuration (configuration d’exécution) qui permet de démarrer une application GWT très facilement depuis Eclipse.

Figure 3.1 — Configurations d’exécution GWT dans Eclipse

En outre, lorsque vous générez un squelette d’application au travers du même plugin, la configuration d’exécution est créée automatiquement pour vous. De même au travers de l’outil en ligne de commande webAppCreator inclus dans GWT, qui génère en prime un fichier build.xml destiné à Ant, ce fichier comprend une cible (target) nommée « hosted » qui démarre l’application en hosted mode. 36 Chapitre 3. Développer avec GWT

3.3.1 Le serveur d’applications intégré Même s’il est parfaitement possible de créer une application GWT « stand-alone », la plupart des applications GWT auront besoin tôt ou tard de communiquer avec un serveur pour réaliser certaines opérations. Pour cette raison, le mode hôte de GWT embarque un serveur d’applications qui permet de tester facilement à la fois le code client (qui tourne dans le navigateur) et le code serveur (qui tourne en principe dans un serveur web) en un seul environnement, ce qui est très commode. Depuis la version 1.6, le serveur embarqué est Jetty, qui succède à Tomcat dans les versions précédentes. Jetty est un serveur web et un moteur de servlets adapté aux configurations embarquées grâce à son faible besoin en mémoire, et offrant des performances comparables. Dans la pratique, peu de différences sont perceptibles, car les deux implémentent la spécification « Java Servlets 2.5 ». Nous reviendrons sur le développement de code serveur dans le chapitre 5. Notez toutefois que sur des projets conséquents, il arrive fréquemment que la partie serveur d’un projet ne puisse pas fonctionner dans le serveur embarqué avec le hosted mode ; ceci arrive en particulier dès qu’on a besoin de faire appel à des fonctionnalités avancés spécifiques à un serveur d’applications, typiquement lorsqu’on met en jeu des mécanismes transactionnels ou des Entity JavaBeans (EJB). Dans ce cas, il suffit de décocher l’option Run built-in server dans l’onglet principal de la configuration d’exécution GWT, ou bien de passer l’option -noserver sur la ligne de commande qui démarre le mode hôte ; ainsi le serveur intégré ne démarrera pas.

3.4 COMPILER ET LANCER EN MODE WEB

Lorsque vous voulez tester une application GWT comme si elle était déployée, c’est-à- dire sous forme de JavaScript dans un navigateur classique, il faut passer par l’étape de « compilation GWT », dont le but est de générer le code JavaScript correspondant au code Java que vous avez écrit. Cette opération est parfois nécessaire lorsque vous voulez contrôler les perfor- mances de votre application dans un navigateur natif ; en effet, en hosted mode votre application est exécutée sous forme d’un mélange de code Java natif (votre propre code, les bibliothèques GWT et les éventuelles bibliothèques tierces) et de JavaScript (par exemple, les bibliothèques JavaScript intégrées directement dans la page HTML). Cet environnement étant très différent de l’environnement cible (JavaScript seulement), il peut exister des différences de performance importantes entre les deux, dans un sens comme dans l’autre. En général, on constate que le code orienté « interface utilisateur » est sensiblement plus performant en web mode qu’en hosted mode, mais cela peut varier dans un sens comme dans l’autre. Une option simple pour tester l’application en mode web est de cliquer sur le bouton Compile/Browse du navigateur du mode hôte ; ceci a pour effet de déclencher la compilation JavaScript, et lorsque celle-ci est terminée, ouvre la page hôte dans le navigateur par défaut de votre système. Cette possibilité est intéressante car elle ne nécessite aucun paramétrage, mais elle a comme inconvénient de ne pas pouvoir être 3.4 Compiler et lancer en mode web 37

intégrée dans une chaîne de construction automatisée, et de bloquer le mode hôte durant tout le temps de la compilation. Heureusement, d’autres options sont offertes.

Figure 3.2 — Bouton Compile/Browse du navigateur du mode hôte

Le compilateur GWT est implémenté dans la classe com.google.gwt.dev.Compiler, qu’on peut appeler depuis une ligne de commande de la façon suivante :

java com.google.gwt.dev.Compiler Hello.gwt.xml

Si le projet a été généré par l’outil webAppCreator, une cible ant spécifique nommée gwtc (qui est également la cible par défaut) est incluse dans le fichier build.xml généré, de sorte que l’appel à la commande :

ant gwtc

ou tout simplement :

ant

va déclencher la compilation GWT.

3.4.1 Les fichiers générés par le compilateur GWT

Pour exprimer les choses très simplement, le but du compilateur GWT est de générer une application JavaScript équivalente à votre application Java. Il va donc examiner votre code source et générer un ensemble de fichiers aux noms cryptiques qui contiennent le code JavaScript et d’autres ressources nécessaires au fonctionnement de l’application en mode web. La compilation GWT n’est pas une opération simple ; en effet le compilateur doit prendre en compte les différentes plates-formes cibles pour générer du code qui fonctionne à l’identique sur toutes celles-ci. Plutôt que de générer un seul code 38 Chapitre 3. Développer avec GWT

JavaScript et d’y inclure des tests pour s’adapter au navigateur, les développeurs de GWT ont pris le parti de générer une variante de code JavaScript par plate-forme cible. Le fichier qui est référencé dans la page HTML hôte ne sert qu’à détecter la plate-forme courante, et passer la main au code JavaScript spécifique à celle-ci. Cette approche est nettement plus performante car elle réduit le volume du code à télécharger, et rend inutile tout test de plate-forme ultérieur. En contrepartie, la phase de compilation est plus longue puisqu’il faut générer autant de variantes que de plates-formes supportées (cinq pour GWT 1.6/1.7).

Le compilateur GWT crée (normalement sous le dossier war) un sous-dossier par module, portant le nom du module. Dans chacun de ces dossiers, on retrouvera un certain nombre de fichiers aux noms peu évocateurs, par exemple :

testapp/14A43CD7E24B0A0136C2B8B20D6DF3C0.cache.png

testapp/29F4EA1240F157649C12466F01F46F60.gwt.rpc

testapp/346766FA9D2CAEC39CC4D21F46562F34.cache.html ...

testapp/FCF795F77D04980E723A4DFA05A7926B.cache.html

testapp/FDFBC219465FCAB905EA55951EE425FA.cache.html

testapp/clear.cache.gif

testapp/hosted.html

testapp/testapp.nocache.js Ces fichiers contiennent les différentes variantes de code généré pour chacune des plates-formes cibles. Le seul fichier qui nous intéresse véritablement ici est le fichier testapp.nocache.js (où testapp est le nom de votre module), qui contient le bootstrap, c’est-à-dire le minimum de code qui va déterminer la plate-forme courante et charger les fichiers adéquats. C’est ce fichier que vous devrez référencer dans la page HTML hôte de votre application (voir § 2.3.2 La page HTML hôte).

3.5 DÉVELOPPEMENT AVEC L’IDE

Lorsque vous développez avec GWT, il y a fort à parier (nous l’espérons !) que vous travaillerez depuis un IDE tel Eclipse. Dans ce cas, comment se passe l’intégration de votre projet GWT dans l’IDE ? Tout d’abord, pour l’IDE, un projet GWT est un projet Java comme un autre : il est constitué de code source Java qui sera compilé en bytecode, et de ressources qui seront copiées telles quelles. Dans les IDE modernes (y compris Eclipse), la compilation est incrémentale et se produit au fur et à mesure que vous sauvegardez le code source ; il n’est pas utile de déclencher manuellement une compilation. Par conséquent, votre projet est toujours prêt à être lancé en hosted mode, pour peu que vous ayez défini une configuration d’exécution appropriée. 3.5 Développement avec l’IDE 39

3.5.1 Debug et cycle de développement

Comme toute application Java, une application GWT peut également être démarrée en mode debug. C’est ici que GWT montre tout son intérêt, puisque vous pouvez utiliser votre IDE favori (Eclipse, IntelliJ, Netbeans ou autres) pour positionner des points d’arrêt dans le code Java, et utiliser toutes les fonctionnalités du débogueur intégré que vous utiliseriez pour une application Java : inspecter le contenu des variables, avancer en pas à pas, etc. Il est loin d’être aussi aisé de faire la même chose en JavaScript. Une fois votre application démarrée en hosted mode, vous serez naturellement amené à modifier (et donc recompiler) votre code. En principe, si l’application a été lancée en mode debug par l’IDE, ce dernier tentera de recharger la nouvelle version des classes dans la JVM en cours d’exécution (hotswap). Dans une application Java classique, cela fonctionne dans un certain nombre de cas, avec certaines limitations (pas de modification du profil de la classe par exemple) ; en pratique dans une application GWT cela ne fonctionne pas à cause des spécificités du hosted mode. Faut-il en conclure qu’après chaque modification du code, il faut relancer complètement le hosted mode ? Heureusement non, les concepteurs de GWT ont prévu ce cas : la fenêtre principale du hosted mode est pourvue d’un bouton Reload qui a pour effet de recharger l’application, sans pour autant redémarrer le hosted mode.

Figure 3.3 — Bouton Reload du navigateur du mode hôte

La plupart du temps, il est donc commode de laisser les fenêtres du hosted mode ouvertes en parallèle à l’IDE ; lorsque des modifications sont à tester, on bascule vers le hosted mode et on recharge l’application via le bouton Reload. 40 Chapitre 3. Développer avec GWT

Figure 3.4 — Résumé du cycle de développement

Attention toutefois à certains points : • Si votre application possède une partie serveur déployée sur un serveur web hors du hosted mode et que vous intervenez sur le code de cette partie serveur, il faudra redéployer vos modifications sur le serveur web. Exception : si le serveur est démarré en mode debug depuis l’IDE et que vos modifications sont compatibles avec le hotswap de la JVM, elles seront prises en compte sans redéploiement. • Si votre application accède à des ressources générées lors de la compilation GWT, il pourra s’avérer nécessaire de relancer la compilation GWT. • Après un certain temps d’utilisation, on constate que le hosted mode devient de plus en plus lent. Fuite mémoire ? En tout cas, un simple redémarrage remet les choses en ordre. 4 Widgets, panels, etc.

Objectif Un des aspects les plus attractifs de GWT est la possibilité de construire une interface graphique dynamique à base de composants de type « widgets » qu’on trouve dans des toolkits comparables comme Swing. Nous allons voir dans ce chapitre quels composants offre GWT et comment les combiner dans des panels.

4.1 UNE INTERFACE GRAPHIQUE DYNAMIQUE

Même si on ne peut pas le résumer à cela, la caractéristique le plus souvent mise en avant de GWT est la possibilité de construire une interface homme-machine (IHM, ou Graphical GUI) dynamique. Qu’est-ce qu’une interface dynamique ? Pour simplifier, on peut dire que c’est une interface : • polymorphe, c’est-à-dire qui présente à l’utilisateur des aspects variables (par exemple, un nœud d’un arbre peut être développé ou réduit) ; • réactive, c’est-à-dire qui produit un feedback instantané aux actions de l’utilisa- teur (par exemple, montrer par un indicateur que le champ en cours de saisie n’est pas valide). 42 Chapitre 4. Widgets, panels, etc.

Comme nous l’avons évoqué au début de ce livre, les interfaces web « tradition- nelles » sont loin d’être dynamiques, pour deux raisons principales : • la pauvreté des composants de base : même s’ils se sont enrichis au cours du temps, la base des applications web a longtemps été le formulaire avec ses champs texte et un bouton submit. Même avec des composants additionnels comme la case à cocher ou la liste déroulante, les possibilités restent limitées ; • l’impossibilité de fournir un feedback tant qu’une requête n’a pas été soumise au serveur. Outre le délai que cela induit, la page doit être rechargée en entier.

La combinaison de JavaScript (pour l’aspect réactif) avec DOM/DHTML et CSS (pour l’aspect polymorphe) a finalement offert les mécanismes nécessaires à la création de véritables interfaces dynamiques au sein d’une page web ; GWT offre une abstraction de ces mécanismes derrière une architecture de composants similaires à ce qu’offrent les toolkits d’IHM classiques tel Swing ou SWT.

4.1.1 Les widgets GWT

Comme pour les toolkits classiques, une IHM construite avec GWT consiste en un assemblage de composants, appelés « widgets » dans la terminologie officielle. Cependant, à la différence d’un toolkit classique, les widgets GWT sont rendus à l’écran au travers de HTML généré dynamiquement, au lieu de graphismes dessinés. Un des partis pris de GWT est d’utiliser les composants HTML natifs à chaque fois que c’est possible ; par exemple le widget TextBox sera rendu par un élément HTML , Button par un