la face cachée de gwt
DESCRIPTION
La face cachée de GWT. Sami Jaber Webmaster du site DotNetGuru.org (DNG) Architecte Valtech Toulouse. Developpez.com Tv4it.com Sfeir, SmartTrade. Programme. Introduction Les différentes phases du compilateur GWT Le modèle RPC Conclusion. Introduction. - PowerPoint PPT PresentationTRANSCRIPT
© 2007 – DNG
La face cachée de GWT
Sami JaberWebmaster du site DotNetGuru.org (DNG)Architecte Valtech ToulouseDeveloppez.com
Tv4it.comSfeir, SmartTrade
3
Introduction
GWT se décompose en deux grandes briques• Le Framework de composants • Le compilateur Java vers Javascript
Le compilateur GWT incarne les racines du Framework
Peu ou pas d’articles traitent de cette face cachée de GWT
Les performances de GWT découlent directement du fonctionnement du compilateur
5
Le compilateur
GWTCompiler com.myApplication.MyApplication-out c:\website\com.my….
ApplicationJava
SiteHTML/JavaScript
6
Les phases de compilation
Chargement du module (méta-données, règles)Préparation des règles de permutation Pour chaque permutation, compilation Java vers JavaScriptGénération des fichiers
7
Chargement des modules
Le chargeur de module (ModuleDefLoader) effectue un parcours récursif de l’arbre des modulesExtrait les informations des schémas
• Binding• Generators• Extends, Properties, …
8
Les permutations
Chargement du module (méta-données, règles)Préparation des règles de permutation Pour chaque permutation, compilation Java vers JavaScriptGénération des fichiers
9
Principe général
Un seul codeJava
Télécharge uniquement la version nécessaireau navigateur client
… puis le met en cacheindéfiniment
10
La compilation
Chargement du module (méta-données, règles)Préparation des règles de permutation Pour chaque permutation, compilation Java vers JavaScriptGénération des fichiers
11
Qu’est-ce qu’un AST ?
GWT s’appuie intensivement sur les AST (Abstract Syntax Tree)
Un arbre syntaxique est une représentation arborescente d’un code source (généralement) compilé
• Expressions• Blocks• Types
ExpExp
IfStmtIfStmt
StmtStmt
StmtStmt
IdUseIdUse
AssignStmtAssignStmt
ExpExp
BlockBlock
12
Compilateur : Eclipse JDT
IfStmt :: “if” Exp “then” Stmt
Class ASTNode{protected ASTNode[] children;
}
class IfStmt extends ASTNode{final protected Token token_if, Exp exp, Token token_then, Stmt stmt;IfStmt(Token token_if, Exp exp, Token token_then, Stmt stmt){
// parse tree construction this.token_if = token_if;this.exp = exp;this.token_then = token_then;this.stmt = stmt;// IR tree constructionchildren[0] = exp;children[1] = stmt;
}}
13
Fusion des arbres AST
AST JDT JavaAST GWT (JProgram)
JSNI
JavaDoc
IType
IField
JClassType
GWT s’appuie sur Eclipse JDT pour compiler les classes et sur TypeOracle son parseur maison pour les sources
ICompilationUnit
15
Optimisations du compilateur
Pruner• Supprime les classes, les champs et les méthodes inutilisées
Method and class finalizer• Finalise les méthodes et les champs
MakeCallsStatic• Réécrit le code non-polymorphique en appel statique
TypeTightener• Le compilateur infère les types les plus spécifiques pour éviter
d’utiliser des types abstraits
MethodCallTightener• Réalise la même opération que TypeTighener, mais pour les appels
de méthodes (appels polymorphiques transformés en appels spécifiques)
DeadCodeElimination• Elimination de code mort (jamais appelé)
MethodInliner
1
2
3
4
5
6
7
16
S T A T I Q U E !
L’optimisation induite par le compilateur peut réduire potentiellement par 10 la taille du code JavaScriptPossible uniquement grâce au fait que le chargement dynamique est impossible
• Pas d’eval() JavaScript ou de newInstance() Java
Même dans un contexte purement JavaScript (non AJAX), le compilateur GWT a du sens !La théorie des compilateurs appliquée à JavaScript (il fallait oser !)
17
Le modèle de communication
Toute communication avec la couche serveur s’opère via le protocole RPC
• Le service s’appuie sur l’API JEE Servlet
Les appels sont asynchrones (classe AsyncCallback) Le code serveur n’est pas converti en Javascript
• Possibilité d’utiliser le JDK 1.5 et toutes les classes du Framework Java
Les types sont sérializés automatiquement par GWT
• suivant un format spécifique RPC
18
Le Framework RPC
Le développeur implémente 3 classes
ServiceDefTargetServiceDefTarget(Interface)(Interface)
ServiceDefTargetServiceDefTarget(Interface)(Interface)
RemoteServiceRemoteService(Interface)(Interface)
RemoteServiceRemoteService(Interface)(Interface)
RemoteServiceServletRemoteServiceServlet(class)(class)
RemoteServiceServletRemoteServiceServlet(class)(class)
MyServiceAsyncMyServiceAsync(Interface)(Interface)
MyServiceAsyncMyServiceAsync(Interface)(Interface)
MyServiceMyService(Interface)(Interface)MyServiceMyService(Interface)(Interface)
MyServiceImplMyServiceImpl(class)(class)
MyServiceImplMyServiceImpl(class)(class)
MyServiceProxyMyServiceProxy(class)(class)
MyServiceProxyMyServiceProxy(class)(class)
Classes importées du Framework
Classes à implémenter
Générées automatiquement
implémente
hérite hérite
relation
implémente
Client Serveur
19
Le service RPC côté serveur
L’implémentation du service
package com.mycompany.project.server;import java.util.Date;import com.google.gwt.user.server.rpc.RemoteServiceServlet;import com.mycompany.project.client.MyOrderService;import com.mycompany.project.client.Person;
public class MyOrderServiceImpl extends RemoteServiceServlet implements MyOrderService {
public String getOrderByName(String name) {return name;
}public Person getPersonByID(int id) {
Person p = new Person();p.setAge(new Date());p.setName("Martin");p.setId(1);p.setSalary(100);return p;
}}
Interface de Service Remote
HttpServlet
JavaBeanSerializable
public class Person implements java.io.Serializable { private int id; private float salary; private String name; private Date age; // setters/getters}
20
Le service RPC côté client
Définir l’interface de service
package com.mycompany.project.client;import com.google.gwt.user.client.rpc.RemoteService;
public interface MyOrderService extends RemoteService { public String getOrderByName(String name); public Person getPersonByID(int id);}
L’interface asynchrone cliente est générée par les outils
MyOrderServiceAsync orderService = (MyOrderServiceAsync) GWT.create(MyOrderService.class);
// Converti le proxy en ServiceDefTarget pour lui assigner l’URLServiceDefTarget endpoint = (ServiceDefTarget) orderService;String moduleRelativeURL = GWT.getModuleBaseURL() + "MyOrderService";endpoint.setServiceEntryPoint(moduleRelativeURL);
Instancie le bon serviceet récupère un proxy Asynchrone
21
Quelques remarques
GWT 1.4 a sensiblement revu son architecture RPC pour la rendre plus extensible Possibilité d’utiliser tout type de moteur d’injection POJO compatible :
• Spring• Guice, EJB 3, RMI, Corba …
Attention à la sérialisation des types• GWT donne l’impression que le couplage client et serveur
est faible : c’est une illusion !!• Oubliez côté client les protocoles tels que Soap ou RMI…• Le client reste en JavaScript et JavaScript même masqué
par Java reste du bon vieux JavaScript interprété• RPC is the way to go
22
10 raisons d’investir dans GWT
CommunautéMarge de progressionProductivitéRichesse fonctionnelle (AJAX)Pérennisation des compétences (JAVA)Extensibilité Intégration avec l’existantStandards ouverts (XML, JSon, J2EE)Open SourceSimplicité
• attention : « simple » pas « simpliste »
23
Quelques liens
Sites• GWT Groups• http://www.onGWT.com• http://www.gwtpowered.com
Livres• GWT en Action
Formations• 3 jours sur GWT 1.4
Me contacter : [email protected] (formation, conseil, séminaires, mariages, baptême...)