Inizia con questo articolo una nuova serie dedicata alla programmazione di applicazioni RIA tramite GWT. Oltre alle basi dello sviluppo in GWT, vedremo quali vantaggi si possono trarre dall‘utilizzo di un framework evoluto come Ext-GWT.
Il framework GWT
Il successo attuale del framework Google Web toolkit è probabilmente dovuto al fatto che più di altri strumenti sembra rispondere alle domande della comunità degli sviluppatori Java EE (e non solo): quale è il modo migliore per realizzare una applicazione basata su Ajax senza dover obbligare lo sviluppatore a lavorare con tonnellate di script JavaScript? Esiste un modo per semplificare la produzione di applicazioni RIA che riduca il set di conoscenze necessarie per gestire questo genere di applicazioni? Infine, nella moltitudine di strumenti oggi necessari (dai vari framework simil JSF, come IceFaces o RichFaces, alle librerie JS) è possibile individuarne uno che si avvicini di più al modo di lavorare solo-Java che non obblighi a dover imparare nuovi linguaggi di script o dover domare applicazioni web affinche’ assumano l’aspetto di una moderna applicazione web dalla GUI ricca e asincrona?
Ebbene lo scopo di GWT è proprio quello di rispondere a tutto ciò: offrire al programmatore la possibilità di lavorare direttamente in Java come se stesse realizzando una applicazione stile Swing (ovvero non come una applicazione web ma una standalone) e di trasformare trasparentemente e automaticamente il codice prodotto in una RIA Ajax con tanto di client che lavora in modalità asincrona direttamente dentro il browser.
Realizzare una applicazione GWT risulta particolarmente semplice, se si conosce bene il linguaggio Java (basta Java SE), l’uso della programmazione asincrona multithread (non c’è da preoccuparsi, basta una infarinatura) e se si hanno conoscenze di base sulla realizzazione di applicazioni a interfaccia grafica in Java stile Swing; l’applicativo è scritto tutto in Java e solo dopo la compilazione standard (eseguita dal compilatore javac a riprova che in partenza il codice è tutto e solo codice Java), il compilatore GWT esegue in maniera automatica le necessarie validazioni, convertendo il bytecode Java in script JavaScript quelle parti che dovranno essere eseguite all’interno del browser (come avremo modo di notare non tutta l’applicazione GWT viene eseguita sul client sotto forma di applicazioni Ajax, per cui non tutto il codice viene tradotto in JS).
Fin da quando ho visto in funzione GWT per la prima volta sono rimasto affascinato per il modo con cui i progettisti di Google hanno messo in pratica una idea tanto geniale quanto semplice. Per lungo tempo infatti molti programmatori hanno considerato il JavaScript come uno scomodo vicino di casa con cui aver a che fare ma con cui spesso non era possibile evitare di interagire.
Le motivazioni di questa “avversione” nei confronti di JavaScript sono molte; di seguito alcune delle più popolari:
- È un altro linguaggio da imparare: dopo aver studiato per lungo tempo Java (o altri concorrenti) ci dicono che per fare delle applicazioni web interattive, accattivanti e moderne è necessario passare a quello che in molti considerano il fratello minore e che bisogna usare complicati framework e librerie.
- Anche se esistono librerie e framework che risolvono questo problema, scrivere una applicazione JS di fatto va incontro alle possibili problematiche di cross-compatibilità fra browser (il più delle volte risolte solo grazie alla scrittura di più versioni dello stesso codice).
- Alto numero di framework disponibili: scrivere codice partendo da zero è un compito ormai anacronistico. È preferibile usare uno dei framework disponibili (ce ne sono molti e questo è un bene), la cui scelta spesso non è immediata (e questo sebbene non sia un male, è un fattore da tenere in considerazione perche’ “costa” in termini di tempo e di apprendimento).
- No type check: in JS non viene fatto nessun controllo sui tipi e sulle conversioni. Sebbene questo approccio venga visto da alcuni come una gran comodità, ogni vero programmatore sa che è la fonte di ogni male.
- Gestione delle librerie poco formale: quando il progetto diventa complesso (pensiamo allo sviluppo di un grosso portale) sorgono spesso conflitti fra librerie di script; in tale contesto la mancanza di un meccanismo forte di type check spesso dà luogo a problemi non facilmente identificabili. Manca a tal proposito un sistema potente di classloading presente invece in Java.
Il lavoro dei progettisti dei vari strumenti web attualmente in voga (vedi ZK, IceFaces, RichFaces e lo stesso GWT) è quello di mascherare o di eliminare del tutto la scrittura del codice JavaScript che debba essere eseguito nel browser. Le strade scelte sono più o meno differenti fra loro. GWT ha intrapreso la soluzione del full-Java: nemmeno una riga di codice JS viene vista e non vi è la percezione (se non per come deve essere organizzato un progetto e per come viene svolta la comunicazione asincrona) che si sta realizzando una applicazione metà Java metà Ajax.
Caratteristiche di GWT
A parte gli slogan più o meno trionfalistici che tendono ad amplificare le magiche funzionalità del nuovo strumento di Google, ecco di seguito una serie di punti che possono riassumere le principali caratteristiche del framework:
- Tutto Java SE: le applicazioni GWT sono scritte totalmente in linguaggio Java, seguono le convenzioni di base del linguaggio e non richiedono ne’ conoscenze ne’ il supporto di librerie JavaEE. L’applicazione viene scritta e compilata con un comune IDE (esistono plugin per Eclipse, NetBeans e IntelliJ) o tramite l’SDK fornito direttamente da Google (compilatori, emulatori, server embedded e la possibilità di usare alcuni script di Ant). La programmazione di una applicazione GWT non necessita di conoscenze particolari, anche se è utile conoscere le basi della programmazione asincrona multithread e su come realizzare una GUI tramite panels, layout e container. In tal senso chi ha alle spalle un po’ di esperienza con Swing si troverà avvantaggiato.
- Chiara separazione delle parti: il codice e le risorse sono raggruppate secondo una precisa organizzazione; una applicazione GWT è in definitiva di una application (il risultato finale infatti è un .war deployabile in un comune web container) che contiene una cartella WEB-INF dove sono collocati descrittori e tutte le risorse JS per poter eseguire la parte client (sono tutte parti che sono aggiunte in automatico dall’SDK o dal plugin scelto alla creazione del progetto). La parte interessante è la suddivisione già prevista dalla specifica, fra le classi che andranno sul server (pubblicate al client tramite una servlet) e quelle che invece verranno tradotte in codice JavaScript per essere eseguito all’interno del client. Un progetto GWT è quindi suddiviso in sottoprogetto server e sottoprogetto client. Le due parti seguono due processi di sviluppo e di deploy differenti.
- Comunicazione asincrona GWT-RPC: è forse una delle caratteristiche più interessanti di GWT (insieme alla traduzione automatica da Java a JavaScript) e permette alla parte client Ajax di comunicare con la controparte server side che rimane in esecuzione all’interno del server. Dato che l’applicazione client interagisce con l’utente in maniera asincrona rispetto a tutte le eventuali chiamate verso lo strato server, il framework mette a disposizione un meccanismo di comunicazione client-server che possiamo considerare come la versione object oriented della comunicazione asincrona alla base di una applicazione Ajax. All’interno di una applicazione GWT infatti è possibile utilizzare un meccanismo di invocazione remota simil RMI, ma in cui oltre al modello di invocazione remota a oggetti è presente una efficace e ben progettata semantica asincrona. Il sistema prevede la gestione di notifiche basate su eventi per gestire la risposta asincrona ritornata dal server in modo da aggiornare automaticamente la GUI.
- Presenza di librerie di componenti: il framework viene rilasciato con un set di componenti grafici (widget) tramite i quali è possibile realizzare interfacce grafiche piuttosto accattivanti (anche grazie alla alta interattività tipica di una applicazione Ajax). A dire il vero i widget di base di Google GWT non sono molto sofisticati e versatili, tanto che questa carenza ha dato modo a diversi super-framework di estenderne le funzionalità grafiche (vedi oltre).
- Possibilità di descrivere la struttura della GUI tramite XML: per chi da qualche anno segue il mondo dell’IT si ricorderà che circa 12 anni fa Netscape presentò lo XUL, un dialetto XML con il quale era possibile descrivere la struttura di una GUI senza codificare nemmeno una riga di codice di sviluppo. I tempi non erano maturi per una soluzione di questo tipo tanto che sono dovuti passare altri 12 anni affinche’ qualcuno la riproponesse in maniera concreta e fattiva. Adesso con GWT 2.0 è possibile infatti descrivere la struttura della interfaccia grafica tramite XML senza dover codificare nemmeno una riga di codice Java (e per quanto riguarda la definizione della GUI è codice sempre piuttosto fastidioso).
- Automatic splitting: si tratta di un’altra novità della versione 2.0, grazie alla quale il programmatore può marcare il codice al fine di spezzare il programma complessivo in sottoparti in modo da consentire il download delle parti client side JS da eseguire all’interno del browser limitatamente a quel che serve al momento opportuno. Questa cosa ricorda molto quello che fu proposto a suo tempo come “download intelligente delle applet”, anche se le limitate risorse di banda di allora facevano optare quasi sempre per un download completo in un solo bundle.
- Ulteriori framework che estendono le funzionalità base: come si è avuto modo di accennare, la creazione di GWT ha messo sul mercato un prodotto veramente potente e innovativo. L’obiettivo dei progettisti è stato fin da subito quello di lavorare sugli aspetti “under the hood” in modo da realizzare una piattaforma di base senza troppi “buchi” o carenze. Questo ha inevitabilmente lasciato spazio a prodotti terze parti (pubblicizzati direttamente sul sito del progetto Google) che pur basandosi sulle specifiche estendono il framework base con set di componenti sofisticati e molto potenti. A tal proposito sono degni di nota il progetto GWT-Ext (ormai dimesso) e il quasi omonimo Ext-GWT (detto anche GXT) entrambi basati sulla famosa libreria JS EXT e il più recente SmartGWT. Nel prosieguo di questa serie approfondiremo questi aspetti.
Perche’ GXT
Di recente ho partecipato a una attività di valutazione e software selection per determinare quali fossero gli strumenti migliori per passare poi alla parte implementativa di un progetto GWT. Dopo alcune prove fatte con GWT ci siamo resi conto che la libreria di componenti di base era un po’ troppo rudimentale per poter realizzare una GUI moderna e dinamica. I componenti offerti dal framework base sono infatti graficamente poco attraenti e offrono poche funzionalità avanzate (p.e. non c’è un data binding serio, non ci sono componenti di view-edit sofisticati, manca un motore MVC sofisticato) tanto che la maggior semplicità offerta dal framework base rischiava di tradursi in un maggior lavoro di programmazione per implementare quanto invece offerto gratuitamente dagli altri strumenti. I test fatti hanno lasciato in lizza per la scelta finale due prodotti molto simili e per motivi diversi altrettanto interessanti. Da un lato SmartGWT [SmartGWT] che è il prodotto del genio di Sanjiv Jivan (vedi il relativo blog [SJB]) già riconosciuto e affermato creatore del framework GWT-Ext (dismesso per problemi di licenza con la libreria EXT) e che offre online alcuni interessantissimi esempi da cui prendere spunto. Il nome dell’autore che sta alle spalle del prodotto è certamente garanzia di qualità; al momento in cui avevamo fatto le prove il framework mostrava ancora alcuni problemi di gioventù e la documentazione era di fatto inesistente (se si esclude quella prodotta dall’autore, pochissimi i blog/forum, gli esempi sul sito del prodotto ma nessun testo o tutorial era presente in rete). Sebbene durante la fase di realizzazione del prototipo non abbiamo trovato particolari problemi, la mancanza di documentazione ci ha lasciato perplessi (a dire il vero con il copia incolla dagli esempi di corredo si riesce a fare molto). Inoltre non abbiamo avuto l’impressione che il team di sviluppo fosse strutturato in maniera corposa.
Il prodotto che invece ci ha impressionato favorevolmente è Ext-GWT (brevemente detto GXT) il quale ha alle spalle una azienda che offre supporto sia gratuitamente (il forum è molto attivo) sia a pagamento (la licenza di supporto avanzato non costa molto e il team si è mostrato molto gentile e veloce nel rispondere). Da notare che la versione open di GXT adotta la licenza GPL, per cui ogni prodotto scritto con GXT deve essere rilasciato in GPL (totalmente free). Se si vuole è disponibile la versione a pagamento che non impone alcun obbligo.
I componenti grafici sono molto versatili e indubbiamente molto accattivanti dal punto di vista grafico; in più il prodotto si basa su un interessante e potente meccanismo a eventi stile MVC che consente di creare applicazioni interattive e di creare il flusso applicativo in modo efficace.
La presenza di maggior supporto da parte della casa produttrice, nonche’ di qualche plugin visuale e di una maggior documentazione ci hanno fatto propendere per GXT. Gli esempi che vedremo in questa serie di articoli si basano esattamente su questo prodotto. Per chi fosse interessato a vedere il framework in azione si consiglia di visitare il sito della casa [GXT] e in particolar modo lo showcase con tutti gli esempi in funzione direttamente online.
Figura 1 – Lo showcase presente sul sito di GXT offre una serie di esempi sui componenti grafici molto completo ed efficace.
Breve introduzione a GWT
Per tutti coloro che ne sono a digiuno, prima di addentrarci nella presentazione teorica e pratica di GXT, conviene dare una breve overview di GWT introducendo i concetti base che saranno validi anche per lo sviluppo di applicazioni GXT.
Come si è accennato in precedenza, un progetto GWT è per molti versi del tutto similare a un comune progetto web con tanto di WEB-INF e file web.xml. Alcune piccole caratteristiche lo differenziano da una comune applicazione web: innanzi tutto la presenza ovvia delle librerie GWT che serviranno in fase di esecuzione; poi analizzando fra i compilati sotto WEB-INF/classes (o equivalentemente nella dir dei sorgenti) si trova un file che si chiama .gwt.xml, che forse è la risorsa più importante del progetto: qui infatti sono presenti le definizioni dei vari moduli GWT (ne parleremo più avanti) così come l’entry point GWT (un artefatto specifico della semantica GWT che serve da classe di innesco del programma GWT). Oltre a questo nel .war si trovano vari file CSS e JS necessari per far funzionare correttamente l’applicazione lato client. La precisa definizione e contenuto esatto dipende molto dal tipo di progetto e di framework utilizzato. Negli esempi che vedremo in seguito, analizzeremo GXT; per cui faremo riferimento a tali risorse.
Come si sviluppa in GWT
Un progetto GWT, a parte la particolare struttura delle directory non presenta particolari peculiarità: la creazione di un nuovo progetto potrebbe essere quindi realizzata a mano partendo da un comune progetto web. Per comodità ovviamente conviene avvalersi di uno dei tool disponibili: si può optare per uno dei plugin disponibile per i vari IDE che una volta installati consentono di creare la struttura di un progetto web-GWT partendo da zero (per motivi di spazio non ci dilungheremo nella spiegazione del funzionamento del wizard relativo per cui consigliamo di fare riferimento a uno dei tutorial presenti su web [ECLI]). In alternativa uno strumento molto utile è l’SDK offerto direttamente da Google, all’interno del quale, oltre alle librerie necessarie per sviluppare un progetto e il runtime per lanciare l’applicazione in test, si trova uno script di Ant con il quale si possono fare le operazioni più comuni in modo piuttosto rapido (e per certi versi più agile ed espressivo rispetto a quanto possibile tramite IDE). Nell’SDK il primo comando che si può usare è il tool webAppCreator per la creazione di uno scheletro di progetto tramite la seguente sintassi:
webAppCreator [-overwrite] [-ignore] [-out dir] [-XnoEclipse | -XonlyEclipse] moduleName
Nel nostro caso
./webAppCreator -out mygwt com.mokabyte.gwt.MyGWTProject
In tal modo si crea un progetto di nome MyGWTProject nella directory mygwt, specificando anche il package base (com.mokabyte.gwt). La directory di progetto a questo punto conterrà tutte le cartelle e i file necessari per completare ed eseguire il nostro applicativo. Per default il wizard crea anche i file necessari per importare il progetto in Eclipse.
In particolare si creano la directory src/com/mokabyte/gwt/ che contiene la definizione del modulo GWT (il file MyGWT.gwt.xml) e i relativi sorgenti che sono normalmente suddivisi in almeno due sottocartelle (client e server), dove è prassi inserire il codice relativo alla parte client (che diverrà JS) e server (che verrà eseguito come normale codice Java server side).
La directory war contiene la web application comprese le librerie (in WEB-INF/lib) le risorse statiche e altro ancora.
Particolarmente importante perche’ permette di specificare la stuttura caratteristica del progetto GWT è il file descrittore del modulo il cui nome segue la sintassi .gwt.xml (nell’esempio allegato MyGWT.gwt.xml); al suo interno viene definita la struttura del progetto, il nome del modulo principale (ossia la classe di start) ed eventuali dipendenze con altri moduli (il tag inherit). Vedremo in dettaglio i concetti legati alla definizione e derivazione dei moduli GWT: per adesso ci basti sapere che è qualcosa che ricorda concetto di import di una libreria/classe esterna ma lo adatta allo scenario client side basato su JavaScript. Il concetto alla base di una derivazione di un modulo è piuttosto semplice ma richiede una trattazione particolare di cui parleremo in un prossimo articolo; di seguito è riportato il codice preso dall’esempio allegato (menu in alto a sinistra) all’articolo:
Il progetto GWT non potrebbe funzionare senza la presenza del file HTML che impacchetta tutta l’applicazione; da questo punto di vista lo schema organizzativo ricorda molto da vicino quello delle Applet: anche in questo caso infatti abbiamo una applicazione client che viene impacchettata e scaricata dalla rete per essere eseguita all’interno (o per mezzo) di una pagina HTML. Nel caso delle applicazioni GWT la pagina HTML serve per definire gli import CSS (di default l’applicazione necessita di due style sheets: il default GWT style sheet, standard.css e l’application style sheet; torneremo più avanti su questi aspetti), i file JavaScript, nonche’ la struttura base della applicazione. Interessante la possibilità di definire dei makup places che potranno essere popolati con componenti grafici da dentro il codice Java; ad esempio nella pagina HTML di esempio troviamo il seguente pezzo:
Web Application Starter Project
Please enter your name: | |
Si possono notare la definizione dei “marcatori” nameFieldContainer e sendButtonContainer che possono essere utilizzati da codice Java per posizionare nella pagina HTML i componenti nell’esatto punto:
// Add the nameField and sendButton to the RootPane // Use RootPanel.get() to get the entire body element RootPanel.get("nameFieldContainer").add(nameField); RootPanel.get("sendButtonContainer").add(sendButton);
Di default il wizard di progetto crea anche la cosiddetta GWT entry point class che serve per far funzionare l’applicazione (potremmo definirla la classe di innesco o il main di un programma standalone). Tale file è strutturato nel seguente modo:
package com.mokabtye.gwt.client; public class SchoolmanagerEP implements EntryPoint { public void onModuleLoad() { } }
Si noti la derivazione dalla classe EntryPoint e la presenza del metodo onModuleLoad(): qui si dovranno inserire tutte le operazioni per far partire il programma lato client (di fatto l’applicazione AJAX). Nell’allegato all’articolo è possibile trovare un esempio di implementazione molto semplice così come realizzato dal tool dell’SDK. Nei prossimi articoli vedremo in dettaglio cosa deve essere inserito in tale classe. Per il momento, al fine di farsi un’idea, si può controllare il sorgente di MyGWTProject.java contenuto nell’archivio in allegato.
Il wizard aggiunge anche alcune classi per la gestione della comunicazione remota GWT-RPC nella cui implementazione di default si chiamano GreetingService.java, GreetingServiceAsync.java, GreetingServiceImpl.java; conviene rinominarle in modo opportuno a seconda delle proprie necessità. Infine si noti il file gwt-servlet.jar che contiene il runtime per l’invocazione server side. Vedremo questi aspetti quando parleremo di RPC-GWT.
Eseguire un progetto GWT
Per poter eseguire un progetto GWT è necessario per prima cosa procedere alla compilazione Java standard e poi alla compilazione GWT. La prima parte non presenta particolari degni di nota, mentre la seconda è interessante perche’ porta alla generazione del codice JS tradotto da Java. Il compilatore GWT genera delle permutazioni del codice in modo da produrre codice JavaScript compatibile con praticamente tutti i principali browser disponibili al momento (il processso di conversione è molto lungo, in fase di sviluppo si può evitare dando vita a un solo tipo di prodotto). Il processo di build termina con la generazione del WAR e si può poi passare alla esecuzione di prova della applicazione. L’SDK a tal proposito fornisce una modalità di esecuzione comoda per fare le prove e testare l’applicazione in fase di sviluppo. La versione precedente alla 2.0 offriva una specie di browser all’interno del quale l’applicazione poteva essere eseguita in modalità hosted-mode.
Con l’avvento della versione 2.0 tale modalità è stata abbandonata a favore della devmode che di fatto permette di eseguire l’applicazione direttamente all’interno di un comune browser (anche se per il test è necessario disporre di un plugin). Lo script Ant fornito dal kit di sviluppo consente di lanciare l’applicazione in modalità di sviluppo con il seguente comando:
ant devmode
il cui risultato è l’esecuzione di un web container minimale (usa Jetty) e l’apertura della pagina all’interno del browser.
Conclusione
Questo mese abbiamo introdotto il modello di programmazione di GWT facendo una panoramica sui vari componenti di un progetto GWT e su cosa sia necessario fare per sviluppare una applicazione di questo tipo. Per adesso siamo rimasti a un livello di genericità piuttosto alto, rimandando alle prossime puntate per maggiori approfondimenti. Inizieremo anche a vedere come si sviluppi una applicazion che usa del framework GXT e come i componenti evoluti presenti in questo strumento possano drammaticamente semplificare lo sviluppo di una applicazione web.
Ovviamente è utile che il lettore nel frattempo approfondisca i temi legati a GWT alcuni dei quali qui in parte solo accennati. Per questo rimandiamo alla ottima documentazione che si trova sul sito di Google (vedi [GWT-t1] e [GWT-t2]).
Riferimenti
[GWT-t1] GWT Tutorial: tutorial dalla pagina ufficiale di GWT
http://code.google.com/webtoolkit/doc/latest/tutorial/index.html
[GWT-t2] GWT Tutorial: un tutorial non ufficiale ma molto efficace
http://www.softwaredesign.co.uk/gwt.html
[ECLI] Google plugin
http://code.google.com/eclipse/
[ART] Alcuni utili e importanti suggerimenti
http://developerlife.com/tutorials/?p=124
http://code.google.com/webtoolkit/articles.html
[GXT] Ext GWT: Rich Internet Application Framework for GWT
http://www.extjs.com/products/gxt/
[SJB] Sanjiv Jivan’s Blog
http://www.jroller.com/sjivan/