Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
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 Conso...
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 / GI...
Migrate Large GWT Applications
New Version
UI
No Widgets
PatternFly
3rd Party Libraries
Stack
Latest GWT Version
GWTP / GI...
Migrate Large GWT Applications
Architecture
SPI
CodeGeneration
Resources
DMR
UI / Ballroom
Core
Metadata
Application
GWTP ...
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
● C...
Migrate Large GWT Applications
Migrate Large GWT Applications
Elemento
Type Safe Builders and Event Handlers
HTML Templates w/ Expression Support
Helper ...
Migrate Large GWT Applications
HTMLDivElement div = div().css(progressContainewr)
.add(div().css(progressDescription)
.tit...
Migrate Large GWT Applications
public class Breadcrumb implements IsElement<HTMLElement> {
private final HTMLElement root;...
Migrate Large GWT Applications
XML schema for common UI building blocks
Navigation Tables
HTML Forms
CRUD Operations
Annot...
Migrate Large GWT Applications
<sub-item id="ejb-thread-pool-item" title="Thread Pool">
<metadata address="/{selected.prof...
Migrate Large GWT Applications
@MbuiView
public abstract class EjbView
extends MbuiViewImpl<EjbPresenter>
implements EjbPr...
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",...
Migrate Large GWT Applications
@JsType(isNative = true)
public abstract class Modal {
@JsFunction @FunctionalInterface
pub...
Migrate Large GWT Applications
Model View Presenter
Migrate Large GWT Applications
MVP
GWTP
● DI through GIN
● Simple and powerful history management
● Support for nested pre...
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 maintai...
Migrate Large GWT Applications
interface FooService extends RemoteService {
void prepare();
void main();
void cleanup();
}...
Migrate Large GWT Applications
public class ExecuteInOrder implements EntryPoint {
@Override
public void onModuleLoad() {
...
Migrate Large GWT Applications
public class ExecuteInOrder implements EntryPoint {
@Override
public void onModuleLoad() {
...
Migrate Large GWT Applications
public class RxDemo implements EntryPoint {
@Override
public void onModuleLoad() {
Observab...
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 NameTokenProces...
Migrate Large GWT Applications
<#-- @ftlvariable name="generatedWith" type="java.lang.String" -->
<#-- @ftlvariable name="...
Migrate Large GWT Applications
Annotation Processing
Freemarker Templates
Use 3rd party libraries
● https://github.com/goo...
Migrate Large GWT Applications
public class FormTest {
@Test
public void simpleForm() {
Compilation compilation = javac()
...
Migrate Large GWT Applications
Build Process
Migrate Large GWT Applications
Build & Run
Maven First
3rd Party Libraries: Frontend Maven Plugin
● NPM
● Bower
● Grunt
Bu...
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.patternfl...
Migrate Large GWT Applications
Thanks!
Questions?
Upcoming SlideShare
Loading in …5
×

of

"Migrate large gwt applications - Lessons Learned" By Harald Pehl Slide 1 "Migrate large gwt applications - Lessons Learned" By Harald Pehl Slide 2 "Migrate large gwt applications - Lessons Learned" By Harald Pehl Slide 3 "Migrate large gwt applications - Lessons Learned" By Harald Pehl Slide 4 "Migrate large gwt applications - Lessons Learned" By Harald Pehl Slide 5 "Migrate large gwt applications - Lessons Learned" By Harald Pehl Slide 6 "Migrate large gwt applications - Lessons Learned" By Harald Pehl Slide 7 "Migrate large gwt applications - Lessons Learned" By Harald Pehl Slide 8 "Migrate large gwt applications - Lessons Learned" By Harald Pehl Slide 9 "Migrate large gwt applications - Lessons Learned" By Harald Pehl Slide 10 "Migrate large gwt applications - Lessons Learned" By Harald Pehl Slide 11 "Migrate large gwt applications - Lessons Learned" By Harald Pehl Slide 12 "Migrate large gwt applications - Lessons Learned" By Harald Pehl Slide 13 "Migrate large gwt applications - Lessons Learned" By Harald Pehl Slide 14 "Migrate large gwt applications - Lessons Learned" By Harald Pehl Slide 15 "Migrate large gwt applications - Lessons Learned" By Harald Pehl Slide 16 "Migrate large gwt applications - Lessons Learned" By Harald Pehl Slide 17 "Migrate large gwt applications - Lessons Learned" By Harald Pehl Slide 18 "Migrate large gwt applications - Lessons Learned" By Harald Pehl Slide 19 "Migrate large gwt applications - Lessons Learned" By Harald Pehl Slide 20 "Migrate large gwt applications - Lessons Learned" By Harald Pehl Slide 21 "Migrate large gwt applications - Lessons Learned" By Harald Pehl Slide 22 "Migrate large gwt applications - Lessons Learned" By Harald Pehl Slide 23 "Migrate large gwt applications - Lessons Learned" By Harald Pehl Slide 24 "Migrate large gwt applications - Lessons Learned" By Harald Pehl Slide 25 "Migrate large gwt applications - Lessons Learned" By Harald Pehl Slide 26 "Migrate large gwt applications - Lessons Learned" By Harald Pehl Slide 27 "Migrate large gwt applications - Lessons Learned" By Harald Pehl Slide 28 "Migrate large gwt applications - Lessons Learned" By Harald Pehl Slide 29 "Migrate large gwt applications - Lessons Learned" By Harald Pehl Slide 30 "Migrate large gwt applications - Lessons Learned" By Harald Pehl Slide 31 "Migrate large gwt applications - Lessons Learned" By Harald Pehl Slide 32 "Migrate large gwt applications - Lessons Learned" By Harald Pehl Slide 33 "Migrate large gwt applications - Lessons Learned" By Harald Pehl Slide 34 "Migrate large gwt applications - Lessons Learned" By Harald Pehl Slide 35 "Migrate large gwt applications - Lessons Learned" By Harald Pehl Slide 36 "Migrate large gwt applications - Lessons Learned" By Harald Pehl Slide 37 "Migrate large gwt applications - Lessons Learned" By Harald Pehl Slide 38 "Migrate large gwt applications - Lessons Learned" By Harald Pehl Slide 39 "Migrate large gwt applications - Lessons Learned" By Harald Pehl Slide 40 "Migrate large gwt applications - Lessons Learned" By Harald Pehl Slide 41 "Migrate large gwt applications - Lessons Learned" By Harald Pehl Slide 42
Upcoming SlideShare
What to Upload to SlideShare
Next
Download to read offline and view in fullscreen.

2 Likes

Share

Download to read offline

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

Download to read offline

"Migrate large gwt applications - Lessons Learned"
By Harald Pehl #RedHat
#GWTcon2017 Firenze - September 28-29th 2017

Related Books

Free with a 30 day trial from Scribd

See all

Related Audiobooks

Free with a 30 day trial from Scribd

See all

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

  1. 1. Migrate Large GWT Applications MIGRATE LARGE GWT APPLICATIONS Harald Pehl, GWTCon 2017 LESSONS LEARNED
  2. 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. 3. Migrate Large GWT Applications HAL - WildFly Management Console
  4. 4. Migrate Large GWT Applications History First commit Feb 8 2011 2.9.14.Final 5.723 commits / 179 releases Today200k LoC
  5. 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. 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. 7. Migrate Large GWT Applications Architecture SPI CodeGeneration Resources DMR UI / Ballroom Core Metadata Application GWTP GuavaRxGWT SLF4J
  8. 8. Migrate Large GWT Applications Comparison 200k 112k LoC Full Build 08:11 05:44 GWT Compile 06:51 02:46
  9. 9. Migrate Large GWT Applications Demo http://localhost:9090/
  10. 10. Migrate Large GWT Applications User Interface
  11. 11. Migrate Large GWT Applications MBUI Elemento 3rd Party Libs PatternFly
  12. 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. 13. Migrate Large GWT Applications
  14. 14. Migrate Large GWT Applications Elemento Type Safe Builders and Event Handlers HTML Templates w/ Expression Support Helper Methods
  15. 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. 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. 17. Migrate Large GWT Applications XML schema for common UI building blocks Navigation Tables HTML Forms CRUD Operations Annotation Processor MBUI
  18. 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. 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. 20. Migrate Large GWT Applications http://localhost:9090/#ejb3-configuration
  21. 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. 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. 23. Migrate Large GWT Applications Model View Presenter
  24. 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. 25. Migrate Large GWT Applications Escape From Callback Hell
  26. 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. 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. 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. 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. 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. 31. Migrate Large GWT Applications Annotation Processing
  32. 32. Migrate Large GWT Applications Annotation Processing Registries Composite GIN MBUI EsDoc
  33. 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. 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. 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. 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. 37. Migrate Large GWT Applications Build Process
  38. 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. 39. Migrate Large GWT Applications Open Issues
  40. 40. Migrate Large GWT Applications Open Issues GIN Code Splitting JSNI GWT.create() ClientBundle / i18n
  41. 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. 42. Migrate Large GWT Applications Thanks! Questions?
  • JaimeCampagna

    Nov. 27, 2021
  • roadlabs

    Apr. 5, 2019

"Migrate large gwt applications - Lessons Learned" By Harald Pehl #RedHat #GWTcon2017 Firenze - September 28-29th 2017

Views

Total views

1,785

On Slideshare

0

From embeds

0

Number of embeds

2

Actions

Downloads

19

Shares

0

Comments

0

Likes

2

×