SlideShare a Scribd company logo
1 of 42
Download to read offline
Migrate Large GWT Applications
MIGRATE LARGE GWT
APPLICATIONS
Harald Pehl, GWTCon 2017
LESSONS LEARNED
Migrate Large GWT Applications
About Me
Senior Software Engineer at Red Hat
Component Lead of the WildFly Management Console
Working with GWT since 2008
http://hpehl.info
https://github.com/hpehl
@haraldpehl
Migrate Large GWT Applications
HAL - WildFly Management Console
Migrate Large GWT Applications
History
First commit
Feb 8 2011
2.9.14.Final
5.723 commits / 179 releases
Today200k LoC
Migrate Large GWT Applications
Current Version
UI
GWT Stock Widgets
Cell Widgets
No Widget Library
Stack
GWT 2.8
GWTP / GIN
Some Code Generation
⇨ Lots of Repeating Code ⇦
Migrate Large GWT Applications
New Version
UI
No Widgets
PatternFly
3rd Party Libraries
Stack
Latest GWT Version
GWTP / GIN
Lots of Code Generation
⇨ Cleaner Architecture ⇦
Migrate Large GWT Applications
Architecture
SPI
CodeGeneration
Resources
DMR
UI / Ballroom
Core
Metadata
Application
GWTP GuavaRxGWT SLF4J
Migrate Large GWT Applications
Comparison
200k
112k
LoC Full Build
08:11
05:44
GWT Compile
06:51
02:46
Migrate Large GWT Applications
Demo
http://localhost:9090/
Migrate Large GWT Applications
User Interface
Migrate Large GWT Applications
MBUI
Elemento
3rd Party Libs
PatternFly
Migrate Large GWT Applications
PatternFly
UI Framework for Enterprise Web Applications
Pattern Library
● Communication
● Content Views
● Data Visualization
● Forms & Control, Navigation & Widgets
Common Styles, Colors & Icons
Migrate Large GWT Applications
Migrate Large GWT Applications
Elemento
Type Safe Builders and Event Handlers
HTML Templates w/ Expression Support
Helper Methods
Migrate Large GWT Applications
HTMLDivElement div = div().css(progressContainewr)
.add(div().css(progressDescription)
.title(label)
.textContent(label))
.add(div().css(progressCss)
.add(valueBar = div().css(progressBar)
.title(Names.NOT_AVAILABLE)
.attr(ROLE, PROGRESSBAR)
.aria(VALUE_MIN, "0")
.add(valueElement = span().asElement())
.asElement())
.add(remainingBar = div().css(progressBar, progressBarRemaining)
.title(Names.NOT_AVAILABLE)
.add(remainingElement = span().css(srOnly).asElement())
.asElement()))
.asElement();
Migrate Large GWT Applications
public class Breadcrumb implements IsElement<HTMLElement> {
private final HTMLElement root;
public Breadcrumb() {
root = ol().css(breadcrumb).asElement();
}
public void clear() {
Elements.removeChildrenFrom(root);
}
public Breadcrumb append(String segment, SegmentHandler handler) {
root.appendChild(li()
.add(a().css(clickable)
.textContent(segment)
.on(click, e -> handler.onClick()))
.asElement());
return this;
}
@Override
public HTMLElement asElement() {
return root;
}
}
Migrate Large GWT Applications
XML schema for common UI building blocks
Navigation Tables
HTML Forms
CRUD Operations
Annotation Processor
MBUI
Migrate Large GWT Applications
<sub-item id="ejb-thread-pool-item" title="Thread Pool">
<metadata address="/{selected.profile}/subsystem=ejb3/thread-pool=*">
<h1>Thread Pool</h1>
<p>${metadata.getDescription().getDescription()}</p>
<table id="ejb-thread-pool-table" title="Thread Pool" form-ref="ejb-thread-pool-form">
<actions>
<action handler-ref="add-resource"/>
<action handler-ref="remove-resource" scope="selected"
name-resolver="${table.selectedRow().getName()}"/>
</actions>
<columns>
<column name="name" value="${row.getName()}"/>
</columns>
</table>
<form id="ejb-thread-pool-form" title="Thread Pool" auto-save="true" reset="true"
name-resolver="${form.getModel().getName()}"/>
</metadata>
</sub-item>
Migrate Large GWT Applications
@MbuiView
public abstract class EjbView
extends MbuiViewImpl<EjbPresenter>
implements EjbPresenter.MyView {
public static EjbView create(MbuiContext mbuiContext) {
return new Mbui_EjbView(mbuiContext);
}
@MbuiElement("ejb-thread-pool-table") Table<NamedNode> threadPoolTable;
@MbuiElement("ejb-thread-pool-form") Form<NamedNode> threadPoolForm;
EjbView(MbuiContext mbuiContext) {
super(mbuiContext);
}
}
Migrate Large GWT Applications
http://localhost:9090/#ejb3-configuration
Migrate Large GWT Applications
3rd Party Libraries
"dependencies": {
"ace-builds": "^1.2.6",
"datatables.net": "~1.10.13",
"datatables.net-buttons": "~1.2.2",
"datatables.net-keytable": "^2.1.3",
"datatables.net-select": "~1.2.0",
"font-awesome": "~4.7.0",
"js-cookie": "~2.1.3",
"javascript-auto-complete": "1.0.4",
"jquery": "~2.2.4",
"jstree": "~3.3.3",
"patternfly": "~3.26.1",
"tagmanager": "~3.0.2",
"zeroclipboard": "^2.2.0"
}
Migrate Large GWT Applications
@JsType(isNative = true)
public abstract class Modal {
@JsFunction @FunctionalInterface
public interface ModalHandler {
void handle();
}
@JsType(isNative = true, namespace = GLOBAL, name = OBJECT)
public static class ModalOptions {
public boolean keyboard;
@JsOverlay
public static ModalOptions create(boolean closeOnEsc) {
ModalOptions options = new ModalOptions();
options.keyboard = closeOnEsc;
return options;
}
}
@JsMethod(namespace = GLOBAL)
public native static Modal $(@NonNls String selector);
public native void modal(ModalOptions modalOptions);
public native void on(@NonNls String event, ModalHandler handler);
}
Migrate Large GWT Applications
Model View Presenter
Migrate Large GWT Applications
MVP
GWTP
● DI through GIN
● Simple and powerful history management
● Support for nested presenters
● Lifecycle events using GWT eventbus
● Lazy instantiation for presenters and views
● Effortless and efficient code splitting
Widget ↔ Elemental2 Adapter
Migrate Large GWT Applications
Escape From Callback Hell
Migrate Large GWT Applications
RxGWT
GWT specific bindings for RxJava
Turn callbacks into “Rx types”
Developed and maintained by @ibaca
Documentation
● http://reactivex.io/
● https://github.com/ReactiveX/RxJava
● https://github.com/intendia-oss/rxgwt
Migrate Large GWT Applications
interface FooService extends RemoteService {
void prepare();
void main();
void cleanup();
}
interface FooServiceAsync {
void prepare(AsyncCallback<Void> async);
void main(AsyncCallback<Void> async);
void cleanup(AsyncCallback<Void> async);
}
Migrate Large GWT Applications
public class ExecuteInOrder implements EntryPoint {
@Override
public void onModuleLoad() {
FooServiceAsync service = GWT.create(FooService.class);
service.prepare(new AsyncCallback<Void>() {
public void onFailure(Throwable throwable) {
console.log("Failed: " + throwable.getMessage());
}
public void onSuccess(Void aVoid) {
service.main(new AsyncCallback<Void>() {
public void onFailure(Throwable throwable) {
console.log("Failed: " + throwable.getMessage())
}
public void onSuccess(Void aVoid) {
service.cleanup(new AsyncCallback<Void>() {
public void onFailure(Throwable throwable) {
console.log("Failed: " + throwable.getMessage())
}
public void onSuccess(Void aVoid) {
console.log("Finished")
}
});
}
});
}
});
}
}
Migrate Large GWT Applications
public class ExecuteInOrder implements EntryPoint {
@Override
public void onModuleLoad() {
FooServiceAsync service = GWT.create(FooService.class);
Completable prepare = Completable.fromEmitter(em -> service.prepare(callback(em)));
Completable main = Completable.fromEmitter(em -> service.main(callback(em)));
Completable cleanup = Completable.fromEmitter(em -> service.cleanup(callback(em)));
Completable.concat(prepare, main, cleanup)
.doOnError(throwable -> console.log("Failed: " + throwable.getMessage()))
.doOnCompleted(() -> console.log("Finished"))
.subscribe();
}
AsyncCallback<Void> callback(CompletableEmitter emitter) {
return new AsyncCallback<Void>() {
@Override
public void onFailure(Throwable throwable) { emitter.onError(throwable); }
@Override
public void onSuccess(Void aVoid) { emitter.onCompleted(); }
};
}
}
Migrate Large GWT Applications
public class RxDemo implements EntryPoint {
@Override
public void onModuleLoad() {
Observable.interval(1, SECONDS)
.take(10)
.flatMapSingle(this::xhr)
.forEach(timestamp -> console.log(timestamp));
}
Single<String> xhr(long id) {
String url = "http://server.test-cors.org/server?enable=true&id=" + id;
return Single.fromEmitter(emitter -> {
XMLHttpRequest xhr = new XMLHttpRequest();
xhr.open("GET", url);
xhr.onload = event -> emitter.onSuccess(new Date().toLocaleTimeString());
xhr.send();
});
}
}
Migrate Large GWT Applications
Annotation Processing
Migrate Large GWT Applications
Annotation Processing
Registries
Composite GIN
MBUI
EsDoc
Migrate Large GWT Applications
package org.jboss.hal.processor;
@AutoService(Processor.class)
public class NameTokenProcessor extends AbstractProcessor {
private final Set<TokenInfo> tokenInfos;
public NameTokenProcessor() {
super(NameTokenProcessor.class, TEMPLATES);
tokenInfos = new HashSet<>();
}
@Override
protected boolean onProcess(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
for (Element e : roundEnv.getElementsAnnotatedWith(NameToken.class)) {
TypeElement tokenElement = (TypeElement) e;
NameToken nameToken = tokenElement.getAnnotation(NameToken.class);
TokenInfo tokenInfo = new TokenInfo(nameToken.value()[0]);
tokenInfos.add(tokenInfo);
...
}
return false;
}
}
Migrate Large GWT Applications
<#-- @ftlvariable name="generatedWith" type="java.lang.String" -->
<#-- @ftlvariable name="packageName" type="java.lang.String" -->
<#-- @ftlvariable name="className" type="java.lang.String" -->
<#-- @ftlvariable name="tokenInfos"
type="java.util.Set<org.jboss.hal.processor.NameTokenProcessor.TokenInfo>" -->
package ${packageName};
import ...
/*
* WARNING! This class is generated. Do not modify.
*/
@Generated("${generatedWith}")
public class ${className} implements org.jboss.hal.meta.token.NameTokens {
private final Set<String> tokens;
public ${className}() {
this.tokens = new HashSet<>();
<#list tokenInfos as tokenInfo>
this.tokens.add("${tokenInfo.token}");
</#list>
}
@Override
public Set<String> getTokens() { return tokens; }
}
Migrate Large GWT Applications
Annotation Processing
Freemarker Templates
Use 3rd party libraries
● https://github.com/google/auto/tree/master/common
● https://github.com/google/auto/tree/master/service
Test your annotation processor!
● https://github.com/google/compile-testing
Migrate Large GWT Applications
public class FormTest {
@Test
public void simpleForm() {
Compilation compilation = javac()
.withOptions("-proc:only")
.withProcessors(new MbuiViewProcessor())
.compile(JavaFileObjects.forResource("SimpleForm.java"));
assertThat(compilation)
.generatedSourceFile("Mbui_SimpleForm")
.hasSourceEquivalentTo(
JavaFileObjects.forResource("Mbui_SimpleForm.java"));
}
}
Migrate Large GWT Applications
Build Process
Migrate Large GWT Applications
Build & Run
Maven First
3rd Party Libraries: Frontend Maven Plugin
● NPM
● Bower
● Grunt
Build: Maven Plugin for GWT by Thomas Broyer
Run: Browser Dev Tools
Migrate Large GWT Applications
Open Issues
Migrate Large GWT Applications
Open Issues
GIN
Code Splitting
JSNI
GWT.create()
ClientBundle / i18n
Migrate Large GWT Applications
Links
https://github.com/hal/hal.next/
https://github.com/hal/elemento
http://www.patternfly.org/
http://wildfly.org/
Migrate Large GWT Applications
Thanks!
Questions?

More Related Content

What's hot

[Srijan Wednesday Webinar] Rails 5: What's in It for Me?
[Srijan Wednesday Webinar] Rails 5: What's in It for Me?[Srijan Wednesday Webinar] Rails 5: What's in It for Me?
[Srijan Wednesday Webinar] Rails 5: What's in It for Me?Srijan Technologies
 
How to build to do app using vue composition api and vuex 4 with typescript
How to build to do app using vue composition api and vuex 4 with typescriptHow to build to do app using vue composition api and vuex 4 with typescript
How to build to do app using vue composition api and vuex 4 with typescriptKaty Slemon
 
Integrating React.js with PHP projects
Integrating React.js with PHP projectsIntegrating React.js with PHP projects
Integrating React.js with PHP projectsIgnacio Martín
 
"Full Stack frameworks or a story about how to reconcile Front (good) and Bac...
"Full Stack frameworks or a story about how to reconcile Front (good) and Bac..."Full Stack frameworks or a story about how to reconcile Front (good) and Bac...
"Full Stack frameworks or a story about how to reconcile Front (good) and Bac...Fwdays
 
ReactJs presentation
ReactJs presentationReactJs presentation
ReactJs presentationnishasowdri
 
Java9 Beyond Modularity - Java 9 más allá de la modularidad
Java9 Beyond Modularity - Java 9 más allá de la modularidadJava9 Beyond Modularity - Java 9 más allá de la modularidad
Java9 Beyond Modularity - Java 9 más allá de la modularidadDavid Gómez García
 
React Lifecycle and Reconciliation
React Lifecycle and ReconciliationReact Lifecycle and Reconciliation
React Lifecycle and ReconciliationZhihao Li
 
SenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark Brocato
SenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark BrocatoSenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark Brocato
SenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark BrocatoSencha
 
React JS and why it's awesome
React JS and why it's awesomeReact JS and why it's awesome
React JS and why it's awesomeAndrew Hull
 
The Road To Reactive with RxJava JEEConf 2016
The Road To Reactive with RxJava JEEConf 2016The Road To Reactive with RxJava JEEConf 2016
The Road To Reactive with RxJava JEEConf 2016Frank Lyaruu
 
SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin
SenchaCon 2016: Modernizing the Ext JS Class System - Don GriffinSenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin
SenchaCon 2016: Modernizing the Ext JS Class System - Don GriffinSencha
 
JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)
JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)
JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)Stephen Chin
 
Getting started with ReactJS
Getting started with ReactJSGetting started with ReactJS
Getting started with ReactJSKrishna Sunuwar
 
React Native One Day
React Native One DayReact Native One Day
React Native One DayTroy Miles
 
Building React Applications with Redux
Building React Applications with ReduxBuilding React Applications with Redux
Building React Applications with ReduxFITC
 

What's hot (20)

[Srijan Wednesday Webinar] Rails 5: What's in It for Me?
[Srijan Wednesday Webinar] Rails 5: What's in It for Me?[Srijan Wednesday Webinar] Rails 5: What's in It for Me?
[Srijan Wednesday Webinar] Rails 5: What's in It for Me?
 
How to build to do app using vue composition api and vuex 4 with typescript
How to build to do app using vue composition api and vuex 4 with typescriptHow to build to do app using vue composition api and vuex 4 with typescript
How to build to do app using vue composition api and vuex 4 with typescript
 
Integrating React.js with PHP projects
Integrating React.js with PHP projectsIntegrating React.js with PHP projects
Integrating React.js with PHP projects
 
"Full Stack frameworks or a story about how to reconcile Front (good) and Bac...
"Full Stack frameworks or a story about how to reconcile Front (good) and Bac..."Full Stack frameworks or a story about how to reconcile Front (good) and Bac...
"Full Stack frameworks or a story about how to reconcile Front (good) and Bac...
 
Vue next
Vue nextVue next
Vue next
 
ReactJs presentation
ReactJs presentationReactJs presentation
ReactJs presentation
 
React и redux
React и reduxReact и redux
React и redux
 
Java9 Beyond Modularity - Java 9 más allá de la modularidad
Java9 Beyond Modularity - Java 9 más allá de la modularidadJava9 Beyond Modularity - Java 9 más allá de la modularidad
Java9 Beyond Modularity - Java 9 más allá de la modularidad
 
React Lifecycle and Reconciliation
React Lifecycle and ReconciliationReact Lifecycle and Reconciliation
React Lifecycle and Reconciliation
 
SenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark Brocato
SenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark BrocatoSenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark Brocato
SenchaCon 2016: Ext JS + React: A Match Made in UX Heaven - Mark Brocato
 
React JS and why it's awesome
React JS and why it's awesomeReact JS and why it's awesome
React JS and why it's awesome
 
Intro to ReactJS
Intro to ReactJSIntro to ReactJS
Intro to ReactJS
 
The Road To Reactive with RxJava JEEConf 2016
The Road To Reactive with RxJava JEEConf 2016The Road To Reactive with RxJava JEEConf 2016
The Road To Reactive with RxJava JEEConf 2016
 
SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin
SenchaCon 2016: Modernizing the Ext JS Class System - Don GriffinSenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin
SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin
 
JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)
JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)
JavaFX 2 and Scala - Like Milk and Cookies (33rd Degrees)
 
Getting started with ReactJS
Getting started with ReactJSGetting started with ReactJS
Getting started with ReactJS
 
React Native One Day
React Native One DayReact Native One Day
React Native One Day
 
Building React Applications with Redux
Building React Applications with ReduxBuilding React Applications with Redux
Building React Applications with Redux
 
React & redux
React & reduxReact & redux
React & redux
 
ReactJS for Beginners
ReactJS for BeginnersReactJS for Beginners
ReactJS for Beginners
 

Similar to "Migrate large gwt applications - Lessons Learned" By Harald Pehl

Enterprise Guice 20090217 Bejug
Enterprise Guice 20090217 BejugEnterprise Guice 20090217 Bejug
Enterprise Guice 20090217 Bejugrobbiev
 
Backbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCBackbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCpootsbook
 
Java Web Programming on Google Cloud Platform [3/3] : Google Web Toolkit
Java Web Programming on Google Cloud Platform [3/3] : Google Web ToolkitJava Web Programming on Google Cloud Platform [3/3] : Google Web Toolkit
Java Web Programming on Google Cloud Platform [3/3] : Google Web ToolkitIMC Institute
 
Architecting your GWT applications with GWT-Platform - Lesson 02
Architecting your GWT applications with GWT-Platform - Lesson 02Architecting your GWT applications with GWT-Platform - Lesson 02
Architecting your GWT applications with GWT-Platform - Lesson 02rhemsolutions
 
What's new and noteworthy in Java EE 8?
What's new and noteworthy in Java EE 8?What's new and noteworthy in Java EE 8?
What's new and noteworthy in Java EE 8?gedoplan
 
Build powerfull and smart web applications with Symfony2
Build powerfull and smart web applications with Symfony2Build powerfull and smart web applications with Symfony2
Build powerfull and smart web applications with Symfony2Hugo Hamon
 
Google Web Toolkits
Google Web ToolkitsGoogle Web Toolkits
Google Web ToolkitsYiguang Hu
 
Hazelcast and MongoDB at Cloud CMS
Hazelcast and MongoDB at Cloud CMSHazelcast and MongoDB at Cloud CMS
Hazelcast and MongoDB at Cloud CMSuzquiano
 
比XML更好用的Java Annotation
比XML更好用的Java Annotation比XML更好用的Java Annotation
比XML更好用的Java Annotationjavatwo2011
 
Net conf BG xamarin lecture
Net conf BG xamarin lectureNet conf BG xamarin lecture
Net conf BG xamarin lectureTsvyatko Konov
 
A GWT Application with MVP Pattern Deploying to CloudFoundry using Spring Roo
A GWT Application with MVP Pattern Deploying to CloudFoundry using  Spring Roo A GWT Application with MVP Pattern Deploying to CloudFoundry using  Spring Roo
A GWT Application with MVP Pattern Deploying to CloudFoundry using Spring Roo Ali Parmaksiz
 
softshake 2014 - Java EE
softshake 2014 - Java EEsoftshake 2014 - Java EE
softshake 2014 - Java EEAlexis Hassler
 

Similar to "Migrate large gwt applications - Lessons Learned" By Harald Pehl (20)

Arquitecturas de microservicios - Medianet Software
Arquitecturas de microservicios   -  Medianet SoftwareArquitecturas de microservicios   -  Medianet Software
Arquitecturas de microservicios - Medianet Software
 
Enterprise Guice 20090217 Bejug
Enterprise Guice 20090217 BejugEnterprise Guice 20090217 Bejug
Enterprise Guice 20090217 Bejug
 
Backbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCBackbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVC
 
Html5 For Jjugccc2009fall
Html5 For Jjugccc2009fallHtml5 For Jjugccc2009fall
Html5 For Jjugccc2009fall
 
Gwt and Xtend
Gwt and XtendGwt and Xtend
Gwt and Xtend
 
Java Web Programming on Google Cloud Platform [3/3] : Google Web Toolkit
Java Web Programming on Google Cloud Platform [3/3] : Google Web ToolkitJava Web Programming on Google Cloud Platform [3/3] : Google Web Toolkit
Java Web Programming on Google Cloud Platform [3/3] : Google Web Toolkit
 
Play!ng with scala
Play!ng with scalaPlay!ng with scala
Play!ng with scala
 
Server Side Swift: Vapor
Server Side Swift: VaporServer Side Swift: Vapor
Server Side Swift: Vapor
 
Google Web Toolkit
Google Web ToolkitGoogle Web Toolkit
Google Web Toolkit
 
Architecting your GWT applications with GWT-Platform - Lesson 02
Architecting your GWT applications with GWT-Platform - Lesson 02Architecting your GWT applications with GWT-Platform - Lesson 02
Architecting your GWT applications with GWT-Platform - Lesson 02
 
What's new and noteworthy in Java EE 8?
What's new and noteworthy in Java EE 8?What's new and noteworthy in Java EE 8?
What's new and noteworthy in Java EE 8?
 
Build powerfull and smart web applications with Symfony2
Build powerfull and smart web applications with Symfony2Build powerfull and smart web applications with Symfony2
Build powerfull and smart web applications with Symfony2
 
Google Web Toolkits
Google Web ToolkitsGoogle Web Toolkits
Google Web Toolkits
 
Hazelcast and MongoDB at Cloud CMS
Hazelcast and MongoDB at Cloud CMSHazelcast and MongoDB at Cloud CMS
Hazelcast and MongoDB at Cloud CMS
 
Beoynd Vaadin 7
Beoynd Vaadin 7Beoynd Vaadin 7
Beoynd Vaadin 7
 
比XML更好用的Java Annotation
比XML更好用的Java Annotation比XML更好用的Java Annotation
比XML更好用的Java Annotation
 
5.node js
5.node js5.node js
5.node js
 
Net conf BG xamarin lecture
Net conf BG xamarin lectureNet conf BG xamarin lecture
Net conf BG xamarin lecture
 
A GWT Application with MVP Pattern Deploying to CloudFoundry using Spring Roo
A GWT Application with MVP Pattern Deploying to CloudFoundry using  Spring Roo A GWT Application with MVP Pattern Deploying to CloudFoundry using  Spring Roo
A GWT Application with MVP Pattern Deploying to CloudFoundry using Spring Roo
 
softshake 2014 - Java EE
softshake 2014 - Java EEsoftshake 2014 - Java EE
softshake 2014 - Java EE
 

More from GWTcon

"Jclays, A global solution for application design and automatic GWT code gene...
"Jclays, A global solution for application design and automatic GWT code gene..."Jclays, A global solution for application design and automatic GWT code gene...
"Jclays, A global solution for application design and automatic GWT code gene...GWTcon
 
In defense of GWT-RPC By Colin Alworth
In defense of GWT-RPC By Colin AlworthIn defense of GWT-RPC By Colin Alworth
In defense of GWT-RPC By Colin AlworthGWTcon
 
DIY: Split GWT Applications using TURDUCKEN approach By Alberto Mancini
DIY: Split GWT Applications using TURDUCKEN approach By Alberto ManciniDIY: Split GWT Applications using TURDUCKEN approach By Alberto Mancini
DIY: Split GWT Applications using TURDUCKEN approach By Alberto ManciniGWTcon
 
Unirex Lean tools By Dario Carotenuto
Unirex Lean tools By Dario CarotenutoUnirex Lean tools By Dario Carotenuto
Unirex Lean tools By Dario CarotenutoGWTcon
 
The future of GWT 2.x - By Colin Alworth
The future of GWT 2.x - By Colin AlworthThe future of GWT 2.x - By Colin Alworth
The future of GWT 2.x - By Colin AlworthGWTcon
 
UI Framework Development using GWT and HTML Canvas - By Iarosla Kobyliukh
UI Framework Development using GWT and HTML Canvas - By Iarosla KobyliukhUI Framework Development using GWT and HTML Canvas - By Iarosla Kobyliukh
UI Framework Development using GWT and HTML Canvas - By Iarosla KobyliukhGWTcon
 
Best Practices - By Lofi Dewanto
Best Practices - By Lofi DewantoBest Practices - By Lofi Dewanto
Best Practices - By Lofi DewantoGWTcon
 
GWT Development for Handheld Devices
GWT Development for Handheld DevicesGWT Development for Handheld Devices
GWT Development for Handheld DevicesGWTcon
 
GWT vs CSS3
GWT vs CSS3GWT vs CSS3
GWT vs CSS3GWTcon
 
WebTram: una WebApp GWT per l'editing di dati cartografici e topologici di un...
WebTram: una WebApp GWT per l'editing di dati cartografici e topologici di un...WebTram: una WebApp GWT per l'editing di dati cartografici e topologici di un...
WebTram: una WebApp GWT per l'editing di dati cartografici e topologici di un...GWTcon
 
GWT Web Socket and data serialization
GWT Web Socket and data serializationGWT Web Socket and data serialization
GWT Web Socket and data serializationGWTcon
 
GWTcon 2014 - Apertura
GWTcon 2014 - AperturaGWTcon 2014 - Apertura
GWTcon 2014 - AperturaGWTcon
 
GWT videocall: power-up your mobile & web app with WebRTC
GWT videocall:  power-up your mobile & web app with WebRTCGWT videocall:  power-up your mobile & web app with WebRTC
GWT videocall: power-up your mobile & web app with WebRTCGWTcon
 

More from GWTcon (13)

"Jclays, A global solution for application design and automatic GWT code gene...
"Jclays, A global solution for application design and automatic GWT code gene..."Jclays, A global solution for application design and automatic GWT code gene...
"Jclays, A global solution for application design and automatic GWT code gene...
 
In defense of GWT-RPC By Colin Alworth
In defense of GWT-RPC By Colin AlworthIn defense of GWT-RPC By Colin Alworth
In defense of GWT-RPC By Colin Alworth
 
DIY: Split GWT Applications using TURDUCKEN approach By Alberto Mancini
DIY: Split GWT Applications using TURDUCKEN approach By Alberto ManciniDIY: Split GWT Applications using TURDUCKEN approach By Alberto Mancini
DIY: Split GWT Applications using TURDUCKEN approach By Alberto Mancini
 
Unirex Lean tools By Dario Carotenuto
Unirex Lean tools By Dario CarotenutoUnirex Lean tools By Dario Carotenuto
Unirex Lean tools By Dario Carotenuto
 
The future of GWT 2.x - By Colin Alworth
The future of GWT 2.x - By Colin AlworthThe future of GWT 2.x - By Colin Alworth
The future of GWT 2.x - By Colin Alworth
 
UI Framework Development using GWT and HTML Canvas - By Iarosla Kobyliukh
UI Framework Development using GWT and HTML Canvas - By Iarosla KobyliukhUI Framework Development using GWT and HTML Canvas - By Iarosla Kobyliukh
UI Framework Development using GWT and HTML Canvas - By Iarosla Kobyliukh
 
Best Practices - By Lofi Dewanto
Best Practices - By Lofi DewantoBest Practices - By Lofi Dewanto
Best Practices - By Lofi Dewanto
 
GWT Development for Handheld Devices
GWT Development for Handheld DevicesGWT Development for Handheld Devices
GWT Development for Handheld Devices
 
GWT vs CSS3
GWT vs CSS3GWT vs CSS3
GWT vs CSS3
 
WebTram: una WebApp GWT per l'editing di dati cartografici e topologici di un...
WebTram: una WebApp GWT per l'editing di dati cartografici e topologici di un...WebTram: una WebApp GWT per l'editing di dati cartografici e topologici di un...
WebTram: una WebApp GWT per l'editing di dati cartografici e topologici di un...
 
GWT Web Socket and data serialization
GWT Web Socket and data serializationGWT Web Socket and data serialization
GWT Web Socket and data serialization
 
GWTcon 2014 - Apertura
GWTcon 2014 - AperturaGWTcon 2014 - Apertura
GWTcon 2014 - Apertura
 
GWT videocall: power-up your mobile & web app with WebRTC
GWT videocall:  power-up your mobile & web app with WebRTCGWT videocall:  power-up your mobile & web app with WebRTC
GWT videocall: power-up your mobile & web app with WebRTC
 

Recently uploaded

Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersNicole Novielli
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rick Flair
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersRaghuram Pandurangan
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsNathaniel Shimoni
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
What is Artificial Intelligence?????????
What is Artificial Intelligence?????????What is Artificial Intelligence?????????
What is Artificial Intelligence?????????blackmambaettijean
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...AliaaTarek5
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 

Recently uploaded (20)

Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software Developers
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information Developers
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directions
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
What is Artificial Intelligence?????????
What is Artificial Intelligence?????????What is Artificial Intelligence?????????
What is Artificial Intelligence?????????
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 

"Migrate large gwt applications - Lessons Learned" By Harald Pehl

  • 1. Migrate Large GWT Applications MIGRATE LARGE GWT APPLICATIONS Harald Pehl, GWTCon 2017 LESSONS LEARNED
  • 2. Migrate Large GWT Applications About Me Senior Software Engineer at Red Hat Component Lead of the WildFly Management Console Working with GWT since 2008 http://hpehl.info https://github.com/hpehl @haraldpehl
  • 3. Migrate Large GWT Applications HAL - WildFly Management Console
  • 4. Migrate Large GWT Applications History First commit Feb 8 2011 2.9.14.Final 5.723 commits / 179 releases Today200k LoC
  • 5. Migrate Large GWT Applications Current Version UI GWT Stock Widgets Cell Widgets No Widget Library Stack GWT 2.8 GWTP / GIN Some Code Generation ⇨ Lots of Repeating Code ⇦
  • 6. Migrate Large GWT Applications New Version UI No Widgets PatternFly 3rd Party Libraries Stack Latest GWT Version GWTP / GIN Lots of Code Generation ⇨ Cleaner Architecture ⇦
  • 7. Migrate Large GWT Applications Architecture SPI CodeGeneration Resources DMR UI / Ballroom Core Metadata Application GWTP GuavaRxGWT SLF4J
  • 8. Migrate Large GWT Applications Comparison 200k 112k LoC Full Build 08:11 05:44 GWT Compile 06:51 02:46
  • 9. Migrate Large GWT Applications Demo http://localhost:9090/
  • 10. Migrate Large GWT Applications User Interface
  • 11. Migrate Large GWT Applications MBUI Elemento 3rd Party Libs PatternFly
  • 12. Migrate Large GWT Applications PatternFly UI Framework for Enterprise Web Applications Pattern Library ● Communication ● Content Views ● Data Visualization ● Forms & Control, Navigation & Widgets Common Styles, Colors & Icons
  • 13. Migrate Large GWT Applications
  • 14. Migrate Large GWT Applications Elemento Type Safe Builders and Event Handlers HTML Templates w/ Expression Support Helper Methods
  • 15. Migrate Large GWT Applications HTMLDivElement div = div().css(progressContainewr) .add(div().css(progressDescription) .title(label) .textContent(label)) .add(div().css(progressCss) .add(valueBar = div().css(progressBar) .title(Names.NOT_AVAILABLE) .attr(ROLE, PROGRESSBAR) .aria(VALUE_MIN, "0") .add(valueElement = span().asElement()) .asElement()) .add(remainingBar = div().css(progressBar, progressBarRemaining) .title(Names.NOT_AVAILABLE) .add(remainingElement = span().css(srOnly).asElement()) .asElement())) .asElement();
  • 16. Migrate Large GWT Applications public class Breadcrumb implements IsElement<HTMLElement> { private final HTMLElement root; public Breadcrumb() { root = ol().css(breadcrumb).asElement(); } public void clear() { Elements.removeChildrenFrom(root); } public Breadcrumb append(String segment, SegmentHandler handler) { root.appendChild(li() .add(a().css(clickable) .textContent(segment) .on(click, e -> handler.onClick())) .asElement()); return this; } @Override public HTMLElement asElement() { return root; } }
  • 17. Migrate Large GWT Applications XML schema for common UI building blocks Navigation Tables HTML Forms CRUD Operations Annotation Processor MBUI
  • 18. Migrate Large GWT Applications <sub-item id="ejb-thread-pool-item" title="Thread Pool"> <metadata address="/{selected.profile}/subsystem=ejb3/thread-pool=*"> <h1>Thread Pool</h1> <p>${metadata.getDescription().getDescription()}</p> <table id="ejb-thread-pool-table" title="Thread Pool" form-ref="ejb-thread-pool-form"> <actions> <action handler-ref="add-resource"/> <action handler-ref="remove-resource" scope="selected" name-resolver="${table.selectedRow().getName()}"/> </actions> <columns> <column name="name" value="${row.getName()}"/> </columns> </table> <form id="ejb-thread-pool-form" title="Thread Pool" auto-save="true" reset="true" name-resolver="${form.getModel().getName()}"/> </metadata> </sub-item>
  • 19. Migrate Large GWT Applications @MbuiView public abstract class EjbView extends MbuiViewImpl<EjbPresenter> implements EjbPresenter.MyView { public static EjbView create(MbuiContext mbuiContext) { return new Mbui_EjbView(mbuiContext); } @MbuiElement("ejb-thread-pool-table") Table<NamedNode> threadPoolTable; @MbuiElement("ejb-thread-pool-form") Form<NamedNode> threadPoolForm; EjbView(MbuiContext mbuiContext) { super(mbuiContext); } }
  • 20. Migrate Large GWT Applications http://localhost:9090/#ejb3-configuration
  • 21. Migrate Large GWT Applications 3rd Party Libraries "dependencies": { "ace-builds": "^1.2.6", "datatables.net": "~1.10.13", "datatables.net-buttons": "~1.2.2", "datatables.net-keytable": "^2.1.3", "datatables.net-select": "~1.2.0", "font-awesome": "~4.7.0", "js-cookie": "~2.1.3", "javascript-auto-complete": "1.0.4", "jquery": "~2.2.4", "jstree": "~3.3.3", "patternfly": "~3.26.1", "tagmanager": "~3.0.2", "zeroclipboard": "^2.2.0" }
  • 22. Migrate Large GWT Applications @JsType(isNative = true) public abstract class Modal { @JsFunction @FunctionalInterface public interface ModalHandler { void handle(); } @JsType(isNative = true, namespace = GLOBAL, name = OBJECT) public static class ModalOptions { public boolean keyboard; @JsOverlay public static ModalOptions create(boolean closeOnEsc) { ModalOptions options = new ModalOptions(); options.keyboard = closeOnEsc; return options; } } @JsMethod(namespace = GLOBAL) public native static Modal $(@NonNls String selector); public native void modal(ModalOptions modalOptions); public native void on(@NonNls String event, ModalHandler handler); }
  • 23. Migrate Large GWT Applications Model View Presenter
  • 24. Migrate Large GWT Applications MVP GWTP ● DI through GIN ● Simple and powerful history management ● Support for nested presenters ● Lifecycle events using GWT eventbus ● Lazy instantiation for presenters and views ● Effortless and efficient code splitting Widget ↔ Elemental2 Adapter
  • 25. Migrate Large GWT Applications Escape From Callback Hell
  • 26. Migrate Large GWT Applications RxGWT GWT specific bindings for RxJava Turn callbacks into “Rx types” Developed and maintained by @ibaca Documentation ● http://reactivex.io/ ● https://github.com/ReactiveX/RxJava ● https://github.com/intendia-oss/rxgwt
  • 27. Migrate Large GWT Applications interface FooService extends RemoteService { void prepare(); void main(); void cleanup(); } interface FooServiceAsync { void prepare(AsyncCallback<Void> async); void main(AsyncCallback<Void> async); void cleanup(AsyncCallback<Void> async); }
  • 28. Migrate Large GWT Applications public class ExecuteInOrder implements EntryPoint { @Override public void onModuleLoad() { FooServiceAsync service = GWT.create(FooService.class); service.prepare(new AsyncCallback<Void>() { public void onFailure(Throwable throwable) { console.log("Failed: " + throwable.getMessage()); } public void onSuccess(Void aVoid) { service.main(new AsyncCallback<Void>() { public void onFailure(Throwable throwable) { console.log("Failed: " + throwable.getMessage()) } public void onSuccess(Void aVoid) { service.cleanup(new AsyncCallback<Void>() { public void onFailure(Throwable throwable) { console.log("Failed: " + throwable.getMessage()) } public void onSuccess(Void aVoid) { console.log("Finished") } }); } }); } }); } }
  • 29. Migrate Large GWT Applications public class ExecuteInOrder implements EntryPoint { @Override public void onModuleLoad() { FooServiceAsync service = GWT.create(FooService.class); Completable prepare = Completable.fromEmitter(em -> service.prepare(callback(em))); Completable main = Completable.fromEmitter(em -> service.main(callback(em))); Completable cleanup = Completable.fromEmitter(em -> service.cleanup(callback(em))); Completable.concat(prepare, main, cleanup) .doOnError(throwable -> console.log("Failed: " + throwable.getMessage())) .doOnCompleted(() -> console.log("Finished")) .subscribe(); } AsyncCallback<Void> callback(CompletableEmitter emitter) { return new AsyncCallback<Void>() { @Override public void onFailure(Throwable throwable) { emitter.onError(throwable); } @Override public void onSuccess(Void aVoid) { emitter.onCompleted(); } }; } }
  • 30. Migrate Large GWT Applications public class RxDemo implements EntryPoint { @Override public void onModuleLoad() { Observable.interval(1, SECONDS) .take(10) .flatMapSingle(this::xhr) .forEach(timestamp -> console.log(timestamp)); } Single<String> xhr(long id) { String url = "http://server.test-cors.org/server?enable=true&id=" + id; return Single.fromEmitter(emitter -> { XMLHttpRequest xhr = new XMLHttpRequest(); xhr.open("GET", url); xhr.onload = event -> emitter.onSuccess(new Date().toLocaleTimeString()); xhr.send(); }); } }
  • 31. Migrate Large GWT Applications Annotation Processing
  • 32. Migrate Large GWT Applications Annotation Processing Registries Composite GIN MBUI EsDoc
  • 33. Migrate Large GWT Applications package org.jboss.hal.processor; @AutoService(Processor.class) public class NameTokenProcessor extends AbstractProcessor { private final Set<TokenInfo> tokenInfos; public NameTokenProcessor() { super(NameTokenProcessor.class, TEMPLATES); tokenInfos = new HashSet<>(); } @Override protected boolean onProcess(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { for (Element e : roundEnv.getElementsAnnotatedWith(NameToken.class)) { TypeElement tokenElement = (TypeElement) e; NameToken nameToken = tokenElement.getAnnotation(NameToken.class); TokenInfo tokenInfo = new TokenInfo(nameToken.value()[0]); tokenInfos.add(tokenInfo); ... } return false; } }
  • 34. Migrate Large GWT Applications <#-- @ftlvariable name="generatedWith" type="java.lang.String" --> <#-- @ftlvariable name="packageName" type="java.lang.String" --> <#-- @ftlvariable name="className" type="java.lang.String" --> <#-- @ftlvariable name="tokenInfos" type="java.util.Set<org.jboss.hal.processor.NameTokenProcessor.TokenInfo>" --> package ${packageName}; import ... /* * WARNING! This class is generated. Do not modify. */ @Generated("${generatedWith}") public class ${className} implements org.jboss.hal.meta.token.NameTokens { private final Set<String> tokens; public ${className}() { this.tokens = new HashSet<>(); <#list tokenInfos as tokenInfo> this.tokens.add("${tokenInfo.token}"); </#list> } @Override public Set<String> getTokens() { return tokens; } }
  • 35. Migrate Large GWT Applications Annotation Processing Freemarker Templates Use 3rd party libraries ● https://github.com/google/auto/tree/master/common ● https://github.com/google/auto/tree/master/service Test your annotation processor! ● https://github.com/google/compile-testing
  • 36. Migrate Large GWT Applications public class FormTest { @Test public void simpleForm() { Compilation compilation = javac() .withOptions("-proc:only") .withProcessors(new MbuiViewProcessor()) .compile(JavaFileObjects.forResource("SimpleForm.java")); assertThat(compilation) .generatedSourceFile("Mbui_SimpleForm") .hasSourceEquivalentTo( JavaFileObjects.forResource("Mbui_SimpleForm.java")); } }
  • 37. Migrate Large GWT Applications Build Process
  • 38. Migrate Large GWT Applications Build & Run Maven First 3rd Party Libraries: Frontend Maven Plugin ● NPM ● Bower ● Grunt Build: Maven Plugin for GWT by Thomas Broyer Run: Browser Dev Tools
  • 39. Migrate Large GWT Applications Open Issues
  • 40. Migrate Large GWT Applications Open Issues GIN Code Splitting JSNI GWT.create() ClientBundle / i18n
  • 41. Migrate Large GWT Applications Links https://github.com/hal/hal.next/ https://github.com/hal/elemento http://www.patternfly.org/ http://wildfly.org/
  • 42. Migrate Large GWT Applications Thanks! Questions?