The GWT Toolkit: crea potenti front-end JavaScript utilizzando Java
Pubblicato: 2022-03-11Il GWT Web Toolkit, precedentemente noto come Google Web Toolkit, è un insieme di strumenti di sviluppo per la creazione e l'ottimizzazione di complesse applicazioni basate su browser utilizzando il linguaggio di programmazione Java.
Ciò che rende GWT non "ancora un altro strumento Java per scrivere app Web" è il fatto che il cuore del toolkit è un compilatore che converte Java in JavaScript (oltre a HTML e CSS), consentendo agli sviluppatori di scrivere applicazioni Web front-end sfruttando tutti i punti di forza di Java.
È persino facile utilizzare un mix di Java e JavaScript, poiché GWT include una solida architettura di interoperabilità per l'interfacciamento con la piattaforma web. Proprio come Java Native Interface (JNI) consente alla Java Virtual Machine (JVM) di chiamare routine specifiche della piattaforma (ad esempio, per accedere a funzionalità hardware specifiche o utilizzare librerie esterne di altri linguaggi), GWT ci consente di scrivere la maggior parte di un applicazione in Java e quindi, se necessario, utilizzare un'API Web specifica o, sfruttare le librerie JavaScript esistenti, per "diventare nativa" e passare a JavaScript.
GWT è nato come prodotto Google ma è passato all'open source alla fine del 2011 ed è oggi rilasciato sotto licenza Apache (versione 2) con il nome GWT Open Source Project . È gestito da un comitato direttivo con rappresentanti di diverse aziende, tra cui Google, RedHat, ArcBees, Vaadin e Sencha, nonché sviluppatori indipendenti della community.
GWT nel passato e nel futuro
Google Web Toolkit è stato rilasciato per la prima volta nel 2006. È stato creato come strumento per aiutare gli ingegneri di Google a sviluppare le loro complesse applicazioni basate su browser, come AdWords, Google Wallet e Google Voli, e, più recentemente, viene utilizzato nel cuore di Applicazioni Fogli Google e Posta in arrivo.
Nel 2006, i browser (e gli interpreti JavaScript) erano tutt'altro che standardizzati. Il codice front-end era lento, buggato e difficile da usare in modo affidabile. C'era una mancanza quasi totale di librerie e framework di alta qualità per lo sviluppo web. Ad esempio, jQuery non esisteva nemmeno fino a quest'anno. Quindi, per poter sviluppare applicazioni web su larga scala, gli ingegneri di Google hanno deciso di sfruttare gli strumenti e le competenze esistenti. Java era il linguaggio più adatto alle loro esigenze, essendo ben noto e perfettamente integrato negli IDE, come Eclipse, e così il Google Web Toolkit iniziò la sua vita.
L'obiettivo era più o meno nascondere le differenze tra i browser e incapsulare i trucchi necessari per scrivere JavaScript efficiente all'interno di un compilatore Java, lasciando gli sviluppatori liberi dalla tirannia dei tecnicismi dei browser.
Naturalmente, nell'ultimo decennio, il web è cambiato; i browser sono diventati più veloci e sono convergenti sugli standard di implementazione e sono stati sviluppati molti fantastici framework e librerie front-end, tra cui jQuery, Angular, Polymer e React. Quindi la prima domanda che potresti porre naturalmente è: "GWT è ancora utile?"
In una parola: Sì .
Nel contesto dello sviluppo web moderno, il targeting dei browser è inevitabile e JavaScript è diventato la lingua franca delle applicazioni front-end. Ma ovviamente, strumenti e linguaggi diversi sono più adatti a compiti diversi. GWT, insieme a una manciata di progetti simili, mira a indirizzare i browser senza limitare gli sviluppatori all'utilizzo di JavaScript.
Lo sviluppo e l'impiego di strumenti di "compilazione per il web" come GWT saranno, nel prossimo futuro, facilitati dal cosiddetto gruppo WebAssembly del World Wide Web Consortium. Non c'è solo un vasto spazio per strumenti che compilano in JavaScript, ma questo approccio può soddisfare una reale esigenza in contesti che vanno dall'offload di parte del calcolo ai browser, al riutilizzo di codice e librerie esistenti, alla condivisione di codice tra back-end e front-end , utilizzando le competenze e i flussi di lavoro esistenti e sfruttando le caratteristiche di linguaggi diversi (ad esempio, la tipizzazione statica nel caso di GWT).
Il progetto GWT dovrebbe rilasciare presto la versione 2.8 e la versione 3.0 è in fase di sviluppo, con grandi miglioramenti in cantiere:
- interoperabilità reinventata con JavaScript
- compilatore migliorato (quasi completamente riscritto).
- supporto Java all'avanguardia (ad es. lambda)
In realtà, la maggior parte delle funzionalità di GWT 3.0 sono già disponibili nel repository Git pubblico. Basta controllare il tronco, qui e compilare GWT seguendo la documentazione qui.
La Comunità GWT
Da quando GWT è diventato open source nel 2011, la community ha assunto un ruolo fondamentale nell'evoluzione del progetto.
Tutto lo sviluppo avviene sul repository Git ospitato su gwt.googlesource.com e tutte le revisioni del codice vengono eseguite su gwt-review.googlesource.com. In queste pagine, chiunque sia interessato allo sviluppo del Toolkit può contribuire e vedere a cosa sta lavorando la community. Negli ultimi anni, la percentuale di nuove patch da parte di non Googler è aumentata da circa il 5% nel 2012 a circa il 25% nell'ultimo anno, a conferma del crescente coinvolgimento.
Quest'anno, la comunità si è riunita per alcuni grandi incontri negli Stati Uniti e in Europa. GWT.create, organizzato da Vaadin, si è tenuto sia a Monaco, in Germania, che a Mountain View, in California, a gennaio, e ha contato più di 600 partecipanti provenienti da dozzine di paesi. L'11 novembre, a Firenze, in Italia, si terrà la seconda edizione di GWTcon, una conferenza GWT guidata dalla comunità che sto aiutando a organizzare.
Per cosa è adatto GWT?
Un sondaggio annuale sul toolkit GWT, rilasciato da Vaadin, discute l'evoluzione dello sviluppo di GWT, come si sentono gli sviluppatori riguardo al toolkit, il buono, il cattivo e così via. Questo sondaggio ci consente anche di capire per cosa viene utilizzato il Toolkit, come sta cambiando la comunità di utenti e le aspettative che gli sviluppatori hanno per il futuro del toolkit.
Il rapporto Future of GWT per il 2015 può essere trovato qui e chiarisce che GWT è molto popolare per la creazione di applicazioni Web su larga scala. Ad esempio, a pagina 14, si afferma: "La maggior parte delle applicazioni sono applicazioni aziendali che contengono molti dati e vengono utilizzate per molte ore al giorno".
Come previsto, è facile concludere che l'ambiente naturale per GWT è il campo delle applicazioni web su larga scala, dove la manutenibilità del codice è importante e grandi team traggono vantaggio dalla struttura del linguaggio Java.
D'altra parte, guardando i benchmark per il codice generato da GWT (ad esempio, nel keynote della conferenza GWT.create dello scorso anno, alle pagine 7, 8 e 11) è facile vedere che, in termini di prestazioni e dimensione del codice, il JavaScript compilato è straordinariamente fantastico. Se utilizzato correttamente, le prestazioni ottenute sono paragonabili al miglior JavaScript scritto a mano. Di conseguenza, è effettivamente possibile utilizzare GWT per trasferire le librerie Java sul Web.
Questo illumina un altro scenario ideale per GWT. L'ecosistema Java è pieno di librerie di alta qualità che non hanno una controparte pronta per l'uso in JavaScript. Il compilatore GWT può essere utilizzato per adattare tali librerie per il web. In altre parole, GWT ci consente di combinare le librerie disponibili sia in Java che in JavaScript ed eseguirle nel browser.
Questo approccio può essere visto nello sviluppo di PicShare, dove mostriamo come diverse librerie Java non generalmente considerate per il web (NyARToolkit per esempio) possono essere trasferite sul browser usando GWT e combinate con API web, tra cui WebRTC e WebGL, per ottenere uno strumento di Realtà Aumentata completamente web-based. Sono stato orgoglioso di presentare PicShare alla conferenza GWT.create 2015 lo scorso gennaio.
Sotto il cofano: trasformare Java in JavaScript
Il GWT Toolkit è un insieme di strumenti moderatamente complesso, ma chiunque può iniziare a usarlo in un batter d'occhio, grazie a un'integrazione sorprendentemente facile da usare con Eclipse.
Creare una semplice applicazione con GWT è relativamente facile per chiunque abbia un background in progetti di sviluppo Java. Ma per capire cosa sta “succedendo davvero”, vale la pena analizzare i componenti principali del toolkit:
- Transpiler da Java a JavaScript
- Ambiente runtime Java emulato
- Livello di interoperabilità
Il compilatore di ottimizzazione di GWT
Una descrizione approfondita di come funziona il compilatore diventa molto tecnica abbastanza presto, e non abbiamo bisogno di scavare così in profondità, ma vale la pena guardare alcuni dei concetti generali.

La prima cosa da capire è che GWT compila Java in JavaScript tramite traduzione a livello di codice sorgente. Cioè, il sorgente Java viene tradotto ( traspilato è il termine tecnico) in JavaScript. Ciò è in contrasto con l'avere una sorta di Java Virtual Machine scritta in JavaScript, che esegue il bytecode Java. (Questo è effettivamente possibile, ed è l'approccio utilizzato da Doppio, ma non è come funziona GWT.)
Invece, il codice Java è suddiviso in un albero sintattico astratto (AST) che rappresenta gli elementi sintattici del codice. Viene quindi mappato su un Javascript AST equivalente (e ottimizzato), che viene infine riconvertito nel codice JavaScript effettivo.
Soppesare i pro ei contro della traspirazione è tutt'altro che l'oggetto di questo post, ma vorrei osservare che con questo metodo, GWT può sfruttare direttamente i servizi di garbage collection dell'interprete JavaScript, insieme a qualsiasi altra funzionalità nativa del browser.
Ci sono alcune parti difficili, ovviamente. Ad esempio, JavaScript ha un solo tipo numerico, che non può contenere il tipo intero long
a 64 bit di Java, quindi i tipi long
richiedono un trattamento speciale da parte del compilatore. Inoltre, la tipizzazione statica Java non ha un significato diretto in JavaScript, quindi è necessario prestare particolare attenzione per mantenere, ad esempio, le operazioni di typecasting equivalenti dopo la traspilazione.
D'altra parte, un vantaggio facilmente apprezzabile della traspirazione è che GWT può eseguire ottimizzazioni (sia per dimensioni che per prestazioni) a livello Java e JavaScript. Il codice JavaScript standard risultante può anche essere ulteriormente elaborato nella pipeline di distribuzione. Ad esempio, una pratica comune che è stata ora integrata nella distribuzione GWT standard prevede l'ottimizzazione dell'output JavaScript da parte del transpiler utilizzando il compilatore di chiusura JavaScript-JavaScript altamente specializzato (un altro dono degli dei di Google).
La descrizione più approfondita del compilatore GWT di cui sono a conoscenza può essere trovata in questa presentazione e nel discorso originale da cui deriva. Qui puoi trovare dettagli su altre interessanti funzionalità del processo di compilazione, come la capacità di GWT di eseguire la divisione del codice, generando più file di script separati da caricare indipendentemente dal browser.
Il JRE emulato
Il compilatore Java-to-JavaScript sarebbe poco più di una novità se non fosse integrato da un'implementazione di Java Runtime Environment (JRE), che fornisce le librerie principali su cui si basano quasi tutte le applicazioni Java. In parole povere, lavorare in Java senza, ad esempio, Collections o metodi String, sarebbe frustrante e, naturalmente, il porting di queste librerie è un lavoro titanico. GWT riempie questo buco con il cosiddetto Emulated JRE.
Emulated JRE non è affatto una re-implementazione completa di Java JRE, ma è piuttosto una sorta di selezione di classi e metodi che possono essere utili (e utilizzabili) lato client. Le funzionalità che sono in Java JRE ma che non troverai all'interno di Emulated JRE rientrano in tre categorie:
Cose che non possono essere trasferite lato client. Ad esempio,
java.lang.Thread
ojava.io.File
non possono essere implementati in un browser con la stessa semantica di Java. La pagina del browser è a thread singolo e non ha accesso diretto al filesystem.Cose che potrebbero essere implementate ma che "costerebbero troppo" in termini di dimensioni del codice, prestazioni o dipendenze e che quindi la comunità preferisce non avere all'interno di GWT. Incluso in questa categoria, ad esempio, c'è la riflessione Java (
java.lang.reflect
) che richiederebbe al transpiler di conservare le informazioni sulla classe per ogni tipo e ciò provocherebbe un aumento delle dimensioni del JavaScript compilato.Cose a cui nessuno era interessato e quindi non sono state implementate.
Se succede che Emulated JRE non soddisfa le tue esigenze (ad esempio, hai bisogno di una classe che non viene fornita), GWT ti consente di scrivere la tua implementazione. Questo potente meccanismo, disponibile tramite il tag <super-source>
, consente di aggirare i problemi durante l'adattamento di nuove librerie esterne che utilizzano parti del JRE non emulate.
Potrebbe essere eccessivamente complesso, o addirittura impossibile, fornire un'implementazione completa di alcune parti di JRE, quindi per attività specifiche le tue implementazioni potrebbero non seguire rigorosamente la semantica di JRE di Java, anche se funzionano nel tuo caso specifico. In effetti, se stai pensando di restituire le tue classi al progetto, ricorda che è di fondamentale importanza per il JRE emulato che ogni classe inclusa segua la stessa semantica del JRE Java originale. Ciò garantisce che chiunque possa ricompilare il codice Java in JavaScript e confida nel fatto che otterrà i risultati attesi. Assicurati sempre che il tuo codice sia stato testato a fondo prima di restituirlo alla community.
Livello di interoperabilità
Per essere uno strumento efficace per la produzione di applicazioni web reali, GWT deve consentire agli sviluppatori di interagire facilmente con la piattaforma sottostante. Cioè, il browser e il DOM.
Sin dall'inizio, GWT è stato creato per supportare tale interazione tramite JavaScript Native Interface (JSNI), che rende l'accesso alle API nel browser un gioco da ragazzi. Ad esempio, utilizzando le funzionalità di sintassi uniche del compilatore GWT, puoi scrivere il seguente codice Java:
public static native void nativeMethod(T1 a1, T2 a2, ...) /*-{ //place your JavaScript code here }-*/;
e sei libero di implementare il corpo del metodo in JavaScript. Puoi persino racchiudere oggetti JavaScript in un JavaScriptObject (JSO) e renderlo accessibile nel tuo codice Java.
Un esempio di dove questo livello entra in gioco può essere trovato nel contesto della composizione dell'interfaccia utente. Mainstream Java ha sempre utilizzato il toolkit Widgets standard per creare elementi dell'interfaccia utente, sfruttando l'interfaccia nativa Java per accedere alle finestre del sistema operativo sottostante e ai sistemi di input. Il livello di interoperabilità di GWT fa la stessa cosa, in modo che i widget tradizionali funzionino perfettamente all'interno del browser. L'unica differenza è che, in questo caso, il sistema sottostante è il browser e il DOM.
Tuttavia, i framework front-end nativi sono rapidamente migliorati negli ultimi anni e oggigiorno offrono vantaggi significativi rispetto ai widget di GWT. Poiché questi framework sono cresciuti in termini di sofisticazione, i tentativi di implementarli in JSNI hanno messo in luce carenze nell'architettura del livello di interoperabilità. A partire dalla versione 2.7, GWT ha introdotto JsInterop, un nuovo approccio basato su annotazioni Java, che consente di integrare rapidamente e facilmente le classi GWT con JavaScript. Non è più necessario scrivere metodi JSNI o classi JSO. Invece, puoi semplicemente usare annotazioni come @JSType
o @JSProperty
, permettendoti di lavorare con classi JavaScript native come se fossero Java.
La specifica completa di JsInterop è ancora in corso e gli ultimi aggiornamenti possono essere provati solo compilando il sorgente dal repository GWT. Ma è già chiaro che questa è la nuova direzione che consentirà a GWT di stare al passo con le piattaforme web in evoluzione.
Un progetto in corso che sfrutta JsInterop è il gwt-polymer-elements recentemente rilasciato, che rende tutti gli elementi Iron and Paper di Polymer disponibili per GWT. Ciò che è interessante in questa libreria è che gli sviluppatori non hanno bisogno di generare manualmente l'API Java. Il progetto utilizza gwt-api-generator per generare la maggior parte delle interfacce direttamente analizzando la libreria Polymer e le annotazioni JSDoc. In questo modo è facile mantenere aggiornati gli attacchi.
Parole finali
Con i miglioramenti apportati al compilatore, al livello di interoperabilità e alle prestazioni e alle dimensioni del codice generato negli ultimi due anni, è chiaro che GWT non è solo "un altro strumento di sviluppo web", ma è sulla buona strada per diventare un importante toolkit di riferimento per lo sviluppo di applicazioni Web complesse su larga scala e potrebbe anche essere una scelta eccellente per rendere fantastiche app più semplici.
Uso GWT quotidianamente nel mio lavoro di sviluppatore e consulente, ma soprattutto amo GWT perché mi consente di superare i limiti delle capacità del browser e mostrare che le moderne applicazioni Web possono essere potenti quanto le applicazioni desktop.
La community del progetto GWT è davvero attiva e vengono continuamente proposte nuove librerie, progetti e applicazioni basate su GWT. A Firenze, il GWTcon2015 guidato dalla comunità si riunirà l'11 novembre. Se ti trovi nella regione, spero che verrai a incontrare alcuni degli sviluppatori principali e conoscere tutte le opportunità per far parte dell'evoluzione di questo fantastico toolkit.