SlideShare uma empresa Scribd logo
1 de 81
Secrets of the GWT
           David Chandler
           Google Web Toolkit Team
           Atlanta, GA USA
           drfibonacci@google.com




Monday, March 14, 2011               1
Agenda
                   Why rich Web apps with GWT?

                   GWT Quickstart

                   Developer tools

                   GWT performance for your users

                   Building with GWT 2.12




Monday, March 14, 2011                              2
GWT in 10 sec


                         Asynchronous
                         JavaScript
                         And
                         XML++



Monday, March 14, 2011                  3
GWT in 30 sec




Monday, March 14, 2011      4
Browser-Proof Your JS Code


                                 IE



                               Firefo
                                     x


                                   i
                              Safar e
                                   m
                              Chro


                                Opera




                          5
Monday, March 14, 2011                   5
No plugins required
                                           Silverlight
                         VML   Flash




                                       6
Monday, March 14, 2011                                   6
Can you find the bug?




                         Hint: JavaScript is a dynamic language



                                             7
Monday, March 14, 2011                                            7
Catch errors at compile time




                         Java is a static language

                                       8
Monday, March 14, 2011                               8
Completion, refactoring...




                           9
Monday, March 14, 2011                   9
Eating our own dogfood




                         += AdSense, Maps, Docs, Groups...
                                         10
Monday, March 14, 2011                                       10
Rich ecosystem
            www.gwtmarketplace.com




Monday, March 14, 2011               11
More ecosystem
                   Util: GIN, gwt-dnd, gwt-fx, gwt-comet, ...
                   Widgets: EXT-GWT, Smart-GWT, ...
                   Frameworks: Vaadin!




Monday, March 14, 2011                                          12
4+ years in review

                  May 2006   GWT 1.0 Launch at JavaOne

                         …   …

                  Aug 2008   GWT 1.5 Java 5 language support

                  Apr 2009   GWT 1.7 Dedicated IE8 support

               Fall 2009     GWT 2.0 UIBinder (XML template), runAsync()


                  Oct 2010   GWT 2.1 MVP, RequestFactory, Spring Roo



                                             13
Monday, March 14, 2011                                                     13
GWT Quickstart
              > svn checkout https://google-web-toolkit.googlecode.com/
              svn/trunk/samples/expenses expenses
              > cd expenses/src/main/webapp
              > mvn -f ../../../pom.xml gwt:run (dev mode)
              (note: most projects can use mvn gwt:run in the dir containing pom.xml--this
              one is special because it loads test data from a .txt file in src/main/webapp)

              1.Browse to http://127.0.0.1:8888/LoadExpensesDB.html?
              gwt.codesvr=127.0.0.1:9997
              2.Click Generate Data button
              3.Browse to Expenses.html to run the app

              To create an Eclipse project:
              1.Install Sonatype m2eclipse and m2extras
              2.File | Import | Existing maven project, select expenses/
              pom.xml

Monday, March 14, 2011                                                                         14
GWT delivers...
                         Productivity for developers

                          -   Language, IDEs, tools,
                              libraries

                          -   People, ecosystem

                         Performance for users

                          -   'Perfect' caching

                          -   Whole program optimization



                                         15
Monday, March 14, 2011                                     15
Developing with GWT
                         Develop

                          -   Google Plugin for Eclipse, GWT Designer, STS / Roo

                         Debug

                          -   In Eclipse with dev mode browser plugin

                         Optimize

                          -   SpeedTracer for GWT, App Engine, Spring Insight

                         Deploy

                          -   Standard WAR or one-button push to App Engine

Monday, March 14, 2011                                                             16
Google Plugin for Eclipse




Monday, March 14, 2011                  17
Google Plugin for Eclipse
                   Easiest way to get latest GWT, GAE SDKs

                   Debug / Run / Optimize / Deploy

                   Wizards (new module, entry point, ClientBundle,
                   UiBinder)

                   Quick fixes (auto-create RPC Async interface)

                   Run As | GWT JUnit Test

                   Maven integration via m2eclipse plugin


Monday, March 14, 2011                                               18
GWT Designer Java, ui.xml




Monday, March 14, 2011                  19
GWT Designer & UiBinder




Monday, March 14, 2011                20
GWT Designer CSS Editor




Monday, March 14, 2011                21
Development cycle


                         Write            Hit
                         Code           Refresh


                                 Quick
                                 Test



                                   22
Monday, March 14, 2011                            22
How dev mode works


                         A real browser




                           Web Server     Code Server



                     Java Virtual Machine

                                                         Duke, the Java mascot
                                          Copyright © Sun Microsystems Inc., all rights reserved.




                                                                           23
Monday, March 14, 2011                                                                              23
Debug in dev mode




                         24
Monday, March 14, 2011          24
Compile for Production
                            Source files:

                         Code, CSS, Images,
                           Resources, …
                                                         GWT
                                                        Compiler



                                                   Your app running here.
                                                   No plugins.




                                              25
Monday, March 14, 2011                                                      25
Optimize with Speed Tracer




Monday, March 14, 2011                   26
Launch SpeedTracer
             From Chrome...




             Or from Eclipse...


Monday, March 14, 2011            27
Server traces GAE, tcServer




Monday, March 14, 2011                    28
One click deploy to GAE




Monday, March 14, 2011                29
Performance for your users
                           Latency
                                       • Perfect Caching
                          Number of
                         connections
                                       • ClientBundle

                         Bandwidth
                                       • data: URLs & MHTML
                                        packaging

                           Browser
                         Performance
                                       • Developer guided code
                                        splitting

                                       • Compiler optimizations


                                                    30
Monday, March 14, 2011                                            30
Perfect caching


                                                                }
                   index.html
                   … ………… ………… ………… … … ………  ……………… … … … … …   HTTP
                   … …… <script src='foo.nocache.js' … > …………   If-Modifed-Since


                   foo.nocache.js




                                                                }
                   ……… … ………… ………  … …… A83B1C.cache.html … …


                   A83B1C.cache.html
                   … … ………   ………… … … ……… ……………   …    ……………
                   ……  … … ……     …  …… … …… … … ……… ………… ……        FOREVER
                   …… ……… … …… …… … … …… … F7312.cache.txt …
                   … 6C5BA.cache.png  …… ……  …… …  ………… … ……        Cacheable
                   … …   ……… ……… ……… … ……… … …… … …………… …………
                   ……… ……… … …………   ………………… …… … … … …… … ……


                         6C5BA.cache.png   F7312.cache.txt




                                                      31
Monday, March 14, 2011                                                             31
Image sprites for free

                                              20,558 bytes


                         11 separate images




                                                                6,824 bytes


                         1 bundled image



                                                   ∑ Separate      Bundled




                                              32
Monday, March 14, 2011                                                        32
Without ClientBundle




                          33
Monday, March 14, 2011             33
Deferred binding


                                            Firefox   Webkit (Safari) Opera    IE
                         Typical portable   2876 ms   1276 ms        2053 ms   4078 ms
                         setInnerText()
                         textContent=... -            908 ms         1386 ms   -
                         innerText=...      2477 ms   918 ms         1520 ms   2469 ms
                         DOM manipulation 7148 ms     1997 ms        4836 ms   14800 ms


                         Improvement        14%       29%            32%       39%




                                                                34
Monday, March 14, 2011                                                                    34
GWT compiler optimization

             “The fastest code is that which does not run.”


                              Joel Webber

                            GWT co-creator




Monday, March 14, 2011                                        35
GWT compiler optimization
                   Does all the stuff you’d do by hand in a tight JS app

                         -   Shrinking (obfuscation)

                         -   Modularization (pay only for what you use)

                         -   Dead code removal

                         -   Method inlining

                   …but automated and even tighter

                   Developer-guided code splitting (runAsync)




Monday, March 14, 2011                                                     36
What’s new in 2.2?
                   Integration with Spring / Roo

                   SafeHTML wrappers

                   GPE: Maven support, integration GWT Designer

                   Application framework

                         -   RequestFactory

                         -   Activities and Places

                   Cell Widgets and Editor framework


Monday, March 14, 2011                                            37
Four flavors of RPC
            1. RequestBuilder + JSONParser (see RESTY-GWT)

            2. RequestBuilder + XMLParser

            3. GWT-RPC (easiest)

            4. RequestFactory (new in 2.1)




Monday, March 14, 2011                                       38
GWT-RPC
              @RemoteServiceRelativePath("greet")
              public interface GreetingService extends RemoteService {
              	 String greetServer(String name) throws IllegalArgumentException;
              }



              public interface GreetingServiceAsync {
              	 void greetServer(String input, AsyncCallback<String> callback)
              	 	 	 throws IllegalArgumentException;
              }



              public class GreetingServiceImpl extends RemoteServiceServlet implements
              	 	 GreetingService
              {
              	 public String greetServer(String input) throws IllegalArgumentException {
              	 ...
                 }
              }




Monday, March 14, 2011                                                                      39
Simple, powerful GWT-RPC
                   Send / receive Plain Old Java Objects (POJO)

                         -   Easy: interface, async, & implementation

                         -   Versioned to help keep client & server in sync

                         -   Even smaller than JSON

                         -   Supports polymorphism

                         -   No JavaScript hijacking risk (JSON attack)

                         -   Easy to find all calls to given service in IDE




Monday, March 14, 2011                                                        40
GWT 2.1 RequestFactory
                   Newer alternative to GWT-RPC

                   Designed for data-oriented services

                         -   Higher level of abstraction than GWT-RPC

                         -   Foundation for future caching / batching

                   Even faster than GWT-RPC

                         -   JSON-based == very fast (no serialization /
                             deserialization required)

                         -   Tracks changes on the client and sends only diffs


Monday, March 14, 2011                                                           41
RequestFactory
                   The entity / DTO problem

                   EntityProxy / ValueProxy

                   Service stub interfaces extend RequestContext

                   AppRequestFactory extends RequestFactory

                   GWT.create(MyAppRequestFactory.class)




Monday, March 14, 2011                                             42
EntityProxy
              @Entity
              public class ItemList extends DatastoreObject
              {
              	 private String name;
              	 private Key<AppUser> owner;
              	 private ListType listType;
              	 @Embedded
              	 private List<ListItem> items; // value type
                 ...
              }

              @ProxyFor(ItemList.class)
              public interface ItemListProxy extends DatastoreObjectProxy
              {
              	 // TODO enums work!
              	 public enum ListType {NOTES, TODO}
              	 String getName();
              	 void setName(String name);
              	 List<ListItemProxy> getItems();
                 AppUserProxy getOwner(); // NOT Key
                 ...
              }




Monday, March 14, 2011                                                      43
DatastoreObject
              package com.listwidget.domain;
              public class DatastoreObject
              {
              	 @Id
              	 private Long id;
              	 private Integer version = 0;
              	
              	 @PrePersist
              	 void onPersist()
              	 {
              	 	 this.version++;
              	 }
                 ...
              }


              package com.listwidget.shared.proxy;
              public interface DatastoreObjectProxy extends EntityProxy
              {
              	 Long getId();
              	 Integer getVersion();
              }




Monday, March 14, 2011                                                    44
ValueProxy
              public class ListItem // POJO
              {
              	 private String itemText;
              	 private Date dateCreated;
              	
              	 public Date getDateCreated()
              	 {
              	 	 return dateCreated;
              	 }
              }



              @ProxyFor(value = ListItem.class)
              public interface ListItemProxy extends ValueProxy
              {
              	 String getItemText();
              	 void setItemText(String itemText);
              	 Date getDateCreated();
              }




Monday, March 14, 2011                                            45
Making a RequestFactory
             public interface ListwidgetRequestFactory extends RequestFactory
             {
             	 @Service(value = ItemListDao.class, locator = DaoServiceLocator.class)
             	 interface ItemListRequestContext extends RequestContext
             	 {
             	 	 Request<List<ItemListProxy>> listAll();
             	 	 Request<Void> save(ItemListProxy list);
             	 	 Request<ItemListProxy> saveAndReturn(ItemListProxy newList);
             	 }
             	 ItemListRequestContext itemListRequest();
             }



             private final ListwidgetRequestFactory rf =
                GWT.create(ListwidgetRequestFactory.class);




Monday, March 14, 2011                                                                  46
Using RequestFactory
              	    @Override
              	    public void persistList(String listName)
              	    {
              	    	 final ListwidgetRequestFactory rf = this.clientFactory
              	    	 	 	 .getRequestFactory();
              	    	 ItemListRequestContext reqCtx = rf.itemListRequest();
              	    	 final ItemListProxy newList = reqCtx.create(ItemListProxy.class);
              	    	 newList.setName(listName);
              	    	 newList.setListType(ListType.TODO);
              	    	 reqCtx.saveAndReturn(newList).fire(new Receiver<ItemListProxy>()
              	    	 {
              	    	 	 @Override
              	    	 	 public void onSuccess(final ItemListProxy savedList)
              	    	 	 {
              	    	 	 	 // Refresh table
              	    	 	 	 listDataProvider.getData();
              	    	 	 }
              	    	 });
              	    }




Monday, March 14, 2011                                                                   47
Using RequestFactory
              	    @Override
              	    public void update(int index, ItemListProxy obj, final String newName)
              	    {
              	    	 ItemListRequestContext reqCtx = clientFactory.getRequestFactory()
              	    	 	 	 .itemListRequest();
              	    	 ItemListProxy editable = reqCtx.edit(obj);
              	    	 editable.setName(newName);
              	    	 reqCtx.save(editable).fire(new Receiver<Void>()
              	    	 {
              	    	 	 @Override
              	    	 	 public void onSuccess(Void response)
              	    	 	 {
              	    	 	 	 eventBus.fireEvent(new MessageEvent(newName + " updated",
              	    	 	 	 	 	 MessageType.INFO));
              	    	 	 }
              	    	 });
              	    }




Monday, March 14, 2011                                                                      48
Using RequestFactory
              	     private void getData()
              	     {
                       // To retrieve relations and value types, use .with()
              	     	 Request<List<ItemListProxy>> findAllReq = rf.itemListRequest()
              	     	 	 	 .listAll().with("owner");
                       // Receiver specifies return type
              	     	 findAllReq.fire(new Receiver<List<ItemListProxy>>()
              	     	 {
              	
              	
                    	 	 @Override
                                                   Text
                    	 	 public void onSuccess(List<ItemListProxy> response)
              	     	 	 {
              	     	 	 	 updateRowData(0, response);
              	     	 	 }
              	     	 });
              	     }




Monday, March 14, 2011                                                                 49
Using RequestFactory
             	     editList = reqCtx.edit(editList);
             	     List<ListItemProxy> items = editList.getItems();
             	     // must initialize collections
             	     if (items == null)
             	     {
             	     	 editList.setItems(new ArrayList<ListItemProxy>());
             	     }
             	     editList.getItems().add(newItem);
             	     reqCtx.save(editList).with("items").to(new Receiver<Void>()
             	     {
             	     	 @Override
             	     	 public void onSuccess(Void response)
             	     	 {
             	     	 	 itemsProvider.setList(editList.getItems());
             	     	 	 itemsProvider.refresh();
             	     	 }
             	     }).fire();




Monday, March 14, 2011                                                           50
GWT MVP - Concepts
                   View

                         -   Interface + implementation

                         -   Interface enables testing without GWTTestCase

                         -   Typically expensive to construct so make reusable

                   Presenter

                         -   No Widgets, just business logic

                         -   Middle man between service layer and views



Monday, March 14, 2011                                                           51
GWT MVP - Concepts
                   Place

                         -   Place represents bookmarkable state of an activity

                         -   PlaceController makes back button / bookmarks
                             work like users expect

                         -   PlaceTokenizers map to / from String tokens on URL




Monday, March 14, 2011                                                            52
Demo
                   third_party/java_src/gwt/svn/trunk/samples/
                   expenses




Monday, March 14, 2011                                           53
Place
              public class EditListPlace extends Place
              {
              	 private String token;
              	 public EditListPlace(String token)
              	 {
              	 	 this.token = token;
              	 }
              	 public String getToken()
              	 {
              	 	 return token;
              	 }
              	 public static class Tokenizer implements PlaceTokenizer<EditListPlace>
              	 {
              	 	 public EditListPlace getPlace(String token)
              	 	 {
              	 	 	 return new EditListPlace(token);
              	 	 }
              	 	 public String getToken(EditListPlace place)
              	 	 {
              	 	 	 return place.getToken();
              	 	 }
              	 }
              }



Monday, March 14, 2011                                                                   54
PlaceHistoryMapper
              /**
                * PlaceHistoryMapper interface is used to attach all places which the
                * PlaceHistoryHandler should be aware of. This is done via the @WithTokenizers
                * annotation or by extending PlaceHistoryMapperWithFactory and creating a
                * separate TokenizerFactory.
                */
              @WithTokenizers({ ListsPlace.Tokenizer.class, EditListPlace.Tokenizer.class })
              public interface AppPlaceHistoryMapper extends PlaceHistoryMapper
              {
              }




Monday, March 14, 2011                                                                           55
Hello Places
                // Start PlaceHistoryHandler with our PlaceHistoryMapper
             PlaceHistoryMapper historyMapper = clientFactory.getHistoryMapper();
             PlaceHistoryHandler historyHandler = new PlaceHistoryHandler(hisoryMapper);
             historyHandler.register(placeController, eventBus, defaultPlace);
             // Goes to place represented on URL or default place
             historyHandler.handleCurrentHistory();




Monday, March 14, 2011                                                                     56
Places: Moving parts




Monday, March 14, 2011             57
Places: Go to




Monday, March 14, 2011      58
Places: Back and forth




Monday, March 14, 2011               59
Activities
                   Activity, ActivityManager are not required!

                   ActivityManager

                         -   Owns a region of the window

                         -   Choose what to do with it on place change

                   Activity (“wake up, set up, show up”)

                         -   Started by ActivityManager

                         -   Provides a widget to display, asynchronously

                         -   Can refuse to relinquish screen

Monday, March 14, 2011                                                      60
Activity
              public class EditListActivity extends AbstractActivity implements Presenter
              {
              	 private ClientFactory clientFactory;
              	 private EventBus eventBus;

              	     public EditListActivity(ClientFactory cf, EditListPlace editListPlace)
              	     {
              	     	 this.clientFactory = cf;
              	     	 this.itemListToken = editListPlace.getToken();
              	     }

              	     @Override
              	     public void start(final AcceptsOneWidget panel, EventBus eventBus)
              	     {
              	     	 this.eventBus = eventBus;
                        ...
                        panel.setWidget(clientFactory.getEditListView());
                    }
                    ...
              }




Monday, March 14, 2011                                                                       61
ActivityMapper
             public class AppActivityMapper implements ActivityMapper {

             	     private ClientFactory clientFactory;

             	     public AppActivityMapper(ClientFactory clientFactory) {
             	     	 super();
             	     	 this.clientFactory = clientFactory;
             	     }

             	     @Override
             	     public Activity getActivity(Place place) {
             	     	 if (place instanceof EditListPlace) {
             	     	 	 return new EditListActivity(clientFactory, (EditListPlace) place);
             	     	 }
             	     	 if (place instanceof ListsPlace)
             	     	 {
             	     	 	 return new ListsActivity(clientFactory);
             	     	 }
             	     	 return null;
             	     }
             }




Monday, March 14, 2011                                                                      62
ActivityMapper Idioms
                   Disposable Activities, shared views:

                         if (place instanceof FooPlace) {
                           return new FooActivity(theOnlyFooView);
                         }

                   Singleton:

                         if (place instanceof FooPlace) {
                           theOnlyFooActivity.update((FooPlace) place);
                           return theOnlyFooActivity;
                         }



Monday, March 14, 2011                                                    63
Get activated




Monday, March 14, 2011      64
Strategies




Monday, March 14, 2011   65
Strategies




Monday, March 14, 2011   66
Activities and Places wiring
             // Start ActivityManager for the nav (west) panel with our WestActivityMapper
             ActivityMapper westActivityMapper = new WestActivityMapper(clientFactory);
             ActivityManager westActivityManager =
                new ActivityManager(westActivityMapper, eventBus);
             westActivityManager.setDisplay(westPanel);

             // Start ActivityManager for the main (center) panel with our CenterActivityMapper
             ActivityMapper centerActivityMapper = new CenterActivityMapper(clientFactory);
             ActivityManager centerActivityManager =
                new ActivityManager(centerActivityMapper, eventBus);
             centerActivityManager.setDisplay(centerPanel);

             // Start PlaceHistoryHandler with our PlaceHistoryMapper
             PlaceHistoryMapper historyMapper = GWT.create(AppPlaceHistoryMapper.class);
             PlaceHistoryHandler historyHandler = new PlaceHistoryHandler(historyMapper);
             historyHandler.register(placeController, eventBus, defaultPlace);

             RootPanel.get().add(dockLayoutPanel);
             // Goes to place represented on URL or default place
             historyHandler.handleCurrentHistory();




Monday, March 14, 2011                                                                            67
Cell Widgets
                   Fast, lightweight table rendering

                   Data binding with
                   DataProviders, ValueUpdaters

                   Scrolling and paging controls

                   Sortable columns, adjustable width

                   TextBox, IntegerBox, ValueBox<T>




Monday, March 14, 2011                                  68
Cell Widgets




Monday, March 14, 2011     69
Editable Column
              // Editable column for list name
              nameColumn = new Column<ItemListProxy,String>(new EditTextCell())
              {
              	 @Override
              	 public String getValue(ItemListProxy list)
              	 {
              	 	 return list.getName();
              	 }
              };




Monday, March 14, 2011                                                            70
Custom Column type
             // Note Flyweight pattern: only one instance of HyperlinkCell passed to the Column
             Column<ItemListProxy, Hyperlink> linkColumn =
                new Column<ItemListProxy, Hyperlink>(new HyperlinkCell())
             {
             	 @Override
             	 public Hyperlink getValue(ItemListProxy list)
             	 {
             	 	 String proxyToken =
                       clientFactory.getRequestFactory().getHistoryToken(list.stableId());
             	 	 String historyToken =
                       clientFactory.getHistoryMapper().getToken(new EditListPlace(proxyToken));
                    Hyperlink h = new Hyperlink(list.getName(),historyToken);
             	 	 return h;
             	 }
             };




Monday, March 14, 2011                                                                             71
Populating a CellTable
             public static class MyDataProvider extends
             	 	 AsyncDataProvider<ItemListProxy>
             {
             	 @Override
             	 protected void onRangeChanged(HasData<ItemListProxy> display)
             	 {
             	 	 // To retrieve relations and value types, use .with()
             	 	 Request<List<ItemListProxy>> findAllReq = rf.itemListRequest()
             	 	 	 	 .listAll().with("owner");
             	 	 // Receiver specifies return type
             	 	 findAllReq.fire(new Receiver<List<ItemListProxy>>()
             	 	 {
             	 	 	 @Override
             	 	 	 public void onSuccess(List<ItemListProxy> response)
             	 	 	 {
             	 	 	 	 updateRowData(0, response);
             	 	 	 }
             	 	 });
             	 }
             }

             this.myDataProvider = new MyDataProvider(requestFactory);




Monday, March 14, 2011                                                            72
Updating with a CellTable
            public class NameFieldUpdater implements FieldUpdater<ItemListProxy, String>
            {
            	 @Override
            	 public void update(int index, ItemListProxy obj, final String newName)
            	 {
            	 	 ItemListRequestContext reqCtx = clientFactory.getRequestFactory()
            	 	 	 	 .itemListRequest();
            	 	 ItemListProxy editable = reqCtx.edit(obj);
            	 	 editable.setName(newName);
            	 	 reqCtx.save(editable).fire(new Receiver<Void>()
            	 	 {
            	 	 	 @Override
            	 	 	 public void onSuccess(Void response)
            	 	 	 {
            	 	 	 	 eventBus.fireEvent(new MessageEvent(newName + " updated",
            	 	 	 	 	 	 MessageType.INFO));
            	 	 	 }
            	 	 });
            	 }
            };

             // Make list name field editable
             display.getNameColumn().setFieldUpdater(new NameFieldUpdater());



Monday, March 14, 2011                                                                     73
GWT Logging
                   GWT now has java.util.Logging emulation




                   Configure in your .gwt.xml



                   Easily enable remote logging, too




Monday, March 14, 2011                                       74
GWT secrets
             -compileReport




Monday, March 14, 2011        75
GWT secrets: faster compile
            -      -draftCompile skips optimizations

            -      Set only one user-agent in gwt.xml for dev

            -      Careful with RPC polymorphism




Monday, March 14, 2011                                          76
GWT secrets: shrink JS
            -      -XdisableClassMetadata: Disables some
                   java.lang.Class methods (e.g. getName())

            -      <set-property name="compiler.stackMode"
                   value="strip"/>
                   Removes client-side stack trace info (can
                   reduce code size up to 15%)

            -      <set-configuration-property
                   name="CssResource.obfuscationPrefix"
                   value="empty"/>



Monday, March 14, 2011                                         77
GWT secrets: shrink JS
            -      <set-property
                   name="compiler.enum.name.obfuscation"
                   value="true"/>
                   (only if you’re not using enums as String values)

            -      -XdisableCastChecking: Disables run-time
                   checking of cast operations
                   (use with caution)

            -      See GWT FAQ, CompilerParameters.gwt.xml




Monday, March 14, 2011                                                 78
GWT speak
                   “Very productive environment for Java
                   developers, but there is a learning curve”

                   “UI layout and styling is a challenge”

                   “GWT has enabled our team to run much faster
                   than we could otherwise”

                   “Would be impossible to write our app without
                   GWT”




Monday, March 14, 2011                                             79
New GWT book
             http://code.google.com/webtoolkit/books.html




Monday, March 14, 2011                                      80
Thank you!
                         Where to get it:
                          http://code.google.com/webtoolkit/

                         Wiki, issue tracker, source:
                          http://code.google.com/p/google-web-toolkit/

                         Official GWT blog:
                          http://google-web-toolkit.blogspot.com/

                         Twitter:
                          @googledevtools



                                              81
Monday, March 14, 2011                                                   81

Mais conteúdo relacionado

Semelhante a Secrets of the GWT

2011 The Year of Web apps
2011 The Year of Web apps2011 The Year of Web apps
2011 The Year of Web appsJungHyuk Kwon
 
Flowdock's full-text search with MongoDB
Flowdock's full-text search with MongoDBFlowdock's full-text search with MongoDB
Flowdock's full-text search with MongoDBFlowdock
 
DevOps Introduction @Cegeka
DevOps Introduction @CegekaDevOps Introduction @Cegeka
DevOps Introduction @Cegekadieterdm
 
Develop and Deploy Scalable Apps with Google App Engine
Develop and Deploy Scalable Apps with Google App EngineDevelop and Deploy Scalable Apps with Google App Engine
Develop and Deploy Scalable Apps with Google App EngineDavid Chandler
 
Seven Simple Reasons to Use AppFuse
Seven Simple Reasons to Use AppFuseSeven Simple Reasons to Use AppFuse
Seven Simple Reasons to Use AppFuseMatt Raible
 
Present and Future of GWT from a developer perspective
Present and Future of GWT from a developer perspectivePresent and Future of GWT from a developer perspective
Present and Future of GWT from a developer perspectiveManuel Carrasco Moñino
 
Java EE6 CodeCamp16 oct 2010
Java EE6 CodeCamp16 oct 2010Java EE6 CodeCamp16 oct 2010
Java EE6 CodeCamp16 oct 2010Codecamp Romania
 
Tech fuse11 toolingtestingci-vs2010teamcity
Tech fuse11 toolingtestingci-vs2010teamcityTech fuse11 toolingtestingci-vs2010teamcity
Tech fuse11 toolingtestingci-vs2010teamcityBaskin Tapkan
 
Building GPE: What We Learned
Building GPE: What We LearnedBuilding GPE: What We Learned
Building GPE: What We Learnedrajeevdayal
 
Keynote: Next Generation Testing
Keynote: Next Generation TestingKeynote: Next Generation Testing
Keynote: Next Generation TestingLoh Chuan Ho Ervin
 
JavaSE - The road forward
JavaSE - The road forwardJavaSE - The road forward
JavaSE - The road forwardeug3n_cojocaru
 
Scalable Apps with Google App Engine
Scalable Apps with Google App EngineScalable Apps with Google App Engine
Scalable Apps with Google App EngineDavid Chandler
 
A path to modularity with Eclipse Virgo
A path to modularity with Eclipse VirgoA path to modularity with Eclipse Virgo
A path to modularity with Eclipse Virgokatya_todorova
 
HTML XHTML HTML5
HTML XHTML HTML5HTML XHTML HTML5
HTML XHTML HTML5timstone
 
Javascript as a target language - GWT kickoff - part1/2
Javascript as a target language - GWT kickoff - part1/2Javascript as a target language - GWT kickoff - part1/2
Javascript as a target language - GWT kickoff - part1/2JooinK
 
Hands on continouous delivery, I TAKE 2014
Hands on continouous delivery, I TAKE 2014Hands on continouous delivery, I TAKE 2014
Hands on continouous delivery, I TAKE 2014Ioan Eugen Stan
 

Semelhante a Secrets of the GWT (20)

2011 The Year of Web apps
2011 The Year of Web apps2011 The Year of Web apps
2011 The Year of Web apps
 
Flowdock's full-text search with MongoDB
Flowdock's full-text search with MongoDBFlowdock's full-text search with MongoDB
Flowdock's full-text search with MongoDB
 
DevOps Introduction @Cegeka
DevOps Introduction @CegekaDevOps Introduction @Cegeka
DevOps Introduction @Cegeka
 
Develop and Deploy Scalable Apps with Google App Engine
Develop and Deploy Scalable Apps with Google App EngineDevelop and Deploy Scalable Apps with Google App Engine
Develop and Deploy Scalable Apps with Google App Engine
 
Pavel Plakhotnik 2015
Pavel Plakhotnik 2015Pavel Plakhotnik 2015
Pavel Plakhotnik 2015
 
Seven Simple Reasons to Use AppFuse
Seven Simple Reasons to Use AppFuseSeven Simple Reasons to Use AppFuse
Seven Simple Reasons to Use AppFuse
 
Present and Future of GWT from a developer perspective
Present and Future of GWT from a developer perspectivePresent and Future of GWT from a developer perspective
Present and Future of GWT from a developer perspective
 
Java EE6 CodeCamp16 oct 2010
Java EE6 CodeCamp16 oct 2010Java EE6 CodeCamp16 oct 2010
Java EE6 CodeCamp16 oct 2010
 
Tech fuse11 toolingtestingci-vs2010teamcity
Tech fuse11 toolingtestingci-vs2010teamcityTech fuse11 toolingtestingci-vs2010teamcity
Tech fuse11 toolingtestingci-vs2010teamcity
 
Building GPE: What We Learned
Building GPE: What We LearnedBuilding GPE: What We Learned
Building GPE: What We Learned
 
Keynote: Next Generation Testing
Keynote: Next Generation TestingKeynote: Next Generation Testing
Keynote: Next Generation Testing
 
JavaSE - The road forward
JavaSE - The road forwardJavaSE - The road forward
JavaSE - The road forward
 
Scalable Apps with Google App Engine
Scalable Apps with Google App EngineScalable Apps with Google App Engine
Scalable Apps with Google App Engine
 
GWT Reloaded
GWT ReloadedGWT Reloaded
GWT Reloaded
 
A path to modularity with Eclipse Virgo
A path to modularity with Eclipse VirgoA path to modularity with Eclipse Virgo
A path to modularity with Eclipse Virgo
 
HTML XHTML HTML5
HTML XHTML HTML5HTML XHTML HTML5
HTML XHTML HTML5
 
Tim stone.html5.rjug.20110316
Tim stone.html5.rjug.20110316Tim stone.html5.rjug.20110316
Tim stone.html5.rjug.20110316
 
Javascript as a target language - GWT kickoff - part1/2
Javascript as a target language - GWT kickoff - part1/2Javascript as a target language - GWT kickoff - part1/2
Javascript as a target language - GWT kickoff - part1/2
 
Anarchist guide to titanium ui
Anarchist guide to titanium uiAnarchist guide to titanium ui
Anarchist guide to titanium ui
 
Hands on continouous delivery, I TAKE 2014
Hands on continouous delivery, I TAKE 2014Hands on continouous delivery, I TAKE 2014
Hands on continouous delivery, I TAKE 2014
 

Mais de David Chandler

Taking Your GWT App to Tablets with GXT 4.0
Taking Your GWT App to Tablets with GXT 4.0Taking Your GWT App to Tablets with GXT 4.0
Taking Your GWT App to Tablets with GXT 4.0David Chandler
 
StORM: a lightweight ORM for Android SQLite
StORM: a lightweight ORM for Android SQLiteStORM: a lightweight ORM for Android SQLite
StORM: a lightweight ORM for Android SQLiteDavid Chandler
 
Easy REST APIs with Jersey and RestyGWT
Easy REST APIs with Jersey and RestyGWTEasy REST APIs with Jersey and RestyGWT
Easy REST APIs with Jersey and RestyGWTDavid Chandler
 
Cómo trabajan los Googlers
Cómo trabajan los GooglersCómo trabajan los Googlers
Cómo trabajan los GooglersDavid Chandler
 
Google App Engine Update 2012
Google App Engine Update 2012Google App Engine Update 2012
Google App Engine Update 2012David Chandler
 
The 90-Day Startup with Google AppEngine for Java
The 90-Day Startup with Google AppEngine for JavaThe 90-Day Startup with Google AppEngine for Java
The 90-Day Startup with Google AppEngine for JavaDavid Chandler
 
Securing JSF Applications Against the OWASP Top Ten
Securing JSF Applications Against the OWASP Top TenSecuring JSF Applications Against the OWASP Top Ten
Securing JSF Applications Against the OWASP Top TenDavid Chandler
 

Mais de David Chandler (11)

Taking Your GWT App to Tablets with GXT 4.0
Taking Your GWT App to Tablets with GXT 4.0Taking Your GWT App to Tablets with GXT 4.0
Taking Your GWT App to Tablets with GXT 4.0
 
StORM: a lightweight ORM for Android SQLite
StORM: a lightweight ORM for Android SQLiteStORM: a lightweight ORM for Android SQLite
StORM: a lightweight ORM for Android SQLite
 
Easy REST APIs with Jersey and RestyGWT
Easy REST APIs with Jersey and RestyGWTEasy REST APIs with Jersey and RestyGWT
Easy REST APIs with Jersey and RestyGWT
 
Cómo trabajan los Googlers
Cómo trabajan los GooglersCómo trabajan los Googlers
Cómo trabajan los Googlers
 
Life of an engineer
Life of an engineerLife of an engineer
Life of an engineer
 
StORM preview
StORM previewStORM preview
StORM preview
 
Google App Engine Update 2012
Google App Engine Update 2012Google App Engine Update 2012
Google App Engine Update 2012
 
GWT Plus HTML 5
GWT Plus HTML 5GWT Plus HTML 5
GWT Plus HTML 5
 
The 90-Day Startup with Google AppEngine for Java
The 90-Day Startup with Google AppEngine for JavaThe 90-Day Startup with Google AppEngine for Java
The 90-Day Startup with Google AppEngine for Java
 
GWT MVP Case Study
GWT MVP Case StudyGWT MVP Case Study
GWT MVP Case Study
 
Securing JSF Applications Against the OWASP Top Ten
Securing JSF Applications Against the OWASP Top TenSecuring JSF Applications Against the OWASP Top Ten
Securing JSF Applications Against the OWASP Top Ten
 

Último

How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessPixlogix Infotech
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?Igalia
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CVKhem
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 

Último (20)

How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 

Secrets of the GWT

  • 1. Secrets of the GWT David Chandler Google Web Toolkit Team Atlanta, GA USA drfibonacci@google.com Monday, March 14, 2011 1
  • 2. Agenda Why rich Web apps with GWT? GWT Quickstart Developer tools GWT performance for your users Building with GWT 2.12 Monday, March 14, 2011 2
  • 3. GWT in 10 sec Asynchronous JavaScript And XML++ Monday, March 14, 2011 3
  • 4. GWT in 30 sec Monday, March 14, 2011 4
  • 5. Browser-Proof Your JS Code IE Firefo x i Safar e m Chro Opera 5 Monday, March 14, 2011 5
  • 6. No plugins required Silverlight VML Flash 6 Monday, March 14, 2011 6
  • 7. Can you find the bug? Hint: JavaScript is a dynamic language 7 Monday, March 14, 2011 7
  • 8. Catch errors at compile time Java is a static language 8 Monday, March 14, 2011 8
  • 9. Completion, refactoring... 9 Monday, March 14, 2011 9
  • 10. Eating our own dogfood += AdSense, Maps, Docs, Groups... 10 Monday, March 14, 2011 10
  • 11. Rich ecosystem www.gwtmarketplace.com Monday, March 14, 2011 11
  • 12. More ecosystem Util: GIN, gwt-dnd, gwt-fx, gwt-comet, ... Widgets: EXT-GWT, Smart-GWT, ... Frameworks: Vaadin! Monday, March 14, 2011 12
  • 13. 4+ years in review May 2006 GWT 1.0 Launch at JavaOne … … Aug 2008 GWT 1.5 Java 5 language support Apr 2009 GWT 1.7 Dedicated IE8 support Fall 2009 GWT 2.0 UIBinder (XML template), runAsync() Oct 2010 GWT 2.1 MVP, RequestFactory, Spring Roo 13 Monday, March 14, 2011 13
  • 14. GWT Quickstart > svn checkout https://google-web-toolkit.googlecode.com/ svn/trunk/samples/expenses expenses > cd expenses/src/main/webapp > mvn -f ../../../pom.xml gwt:run (dev mode) (note: most projects can use mvn gwt:run in the dir containing pom.xml--this one is special because it loads test data from a .txt file in src/main/webapp) 1.Browse to http://127.0.0.1:8888/LoadExpensesDB.html? gwt.codesvr=127.0.0.1:9997 2.Click Generate Data button 3.Browse to Expenses.html to run the app To create an Eclipse project: 1.Install Sonatype m2eclipse and m2extras 2.File | Import | Existing maven project, select expenses/ pom.xml Monday, March 14, 2011 14
  • 15. GWT delivers... Productivity for developers - Language, IDEs, tools, libraries - People, ecosystem Performance for users - 'Perfect' caching - Whole program optimization 15 Monday, March 14, 2011 15
  • 16. Developing with GWT Develop - Google Plugin for Eclipse, GWT Designer, STS / Roo Debug - In Eclipse with dev mode browser plugin Optimize - SpeedTracer for GWT, App Engine, Spring Insight Deploy - Standard WAR or one-button push to App Engine Monday, March 14, 2011 16
  • 17. Google Plugin for Eclipse Monday, March 14, 2011 17
  • 18. Google Plugin for Eclipse Easiest way to get latest GWT, GAE SDKs Debug / Run / Optimize / Deploy Wizards (new module, entry point, ClientBundle, UiBinder) Quick fixes (auto-create RPC Async interface) Run As | GWT JUnit Test Maven integration via m2eclipse plugin Monday, March 14, 2011 18
  • 19. GWT Designer Java, ui.xml Monday, March 14, 2011 19
  • 20. GWT Designer & UiBinder Monday, March 14, 2011 20
  • 21. GWT Designer CSS Editor Monday, March 14, 2011 21
  • 22. Development cycle Write Hit Code Refresh Quick Test 22 Monday, March 14, 2011 22
  • 23. How dev mode works A real browser Web Server Code Server Java Virtual Machine Duke, the Java mascot Copyright © Sun Microsystems Inc., all rights reserved. 23 Monday, March 14, 2011 23
  • 24. Debug in dev mode 24 Monday, March 14, 2011 24
  • 25. Compile for Production Source files: Code, CSS, Images, Resources, … GWT Compiler Your app running here. No plugins. 25 Monday, March 14, 2011 25
  • 26. Optimize with Speed Tracer Monday, March 14, 2011 26
  • 27. Launch SpeedTracer From Chrome... Or from Eclipse... Monday, March 14, 2011 27
  • 28. Server traces GAE, tcServer Monday, March 14, 2011 28
  • 29. One click deploy to GAE Monday, March 14, 2011 29
  • 30. Performance for your users Latency • Perfect Caching Number of connections • ClientBundle Bandwidth • data: URLs & MHTML packaging Browser Performance • Developer guided code splitting • Compiler optimizations 30 Monday, March 14, 2011 30
  • 31. Perfect caching } index.html … ………… ………… ………… … … ………  ……………… … … … … … HTTP … …… <script src='foo.nocache.js' … > ………… If-Modifed-Since foo.nocache.js } ……… … ………… ………  … …… A83B1C.cache.html … … A83B1C.cache.html … … ………   ………… … … ……… …………… … …………… ……  … … ……     …  …… … …… … … ……… ………… …… FOREVER …… ……… … …… …… … … …… … F7312.cache.txt … … 6C5BA.cache.png  …… ……  …… …  ………… … …… Cacheable … …   ……… ……… ……… … ……… … …… … …………… ………… ……… ……… … …………   ………………… …… … … … …… … …… 6C5BA.cache.png F7312.cache.txt 31 Monday, March 14, 2011 31
  • 32. Image sprites for free 20,558 bytes 11 separate images 6,824 bytes 1 bundled image ∑ Separate Bundled 32 Monday, March 14, 2011 32
  • 33. Without ClientBundle 33 Monday, March 14, 2011 33
  • 34. Deferred binding Firefox Webkit (Safari) Opera IE Typical portable 2876 ms 1276 ms 2053 ms 4078 ms setInnerText() textContent=... - 908 ms 1386 ms - innerText=... 2477 ms 918 ms 1520 ms 2469 ms DOM manipulation 7148 ms 1997 ms 4836 ms 14800 ms Improvement 14% 29% 32% 39% 34 Monday, March 14, 2011 34
  • 35. GWT compiler optimization “The fastest code is that which does not run.” Joel Webber GWT co-creator Monday, March 14, 2011 35
  • 36. GWT compiler optimization Does all the stuff you’d do by hand in a tight JS app - Shrinking (obfuscation) - Modularization (pay only for what you use) - Dead code removal - Method inlining …but automated and even tighter Developer-guided code splitting (runAsync) Monday, March 14, 2011 36
  • 37. What’s new in 2.2? Integration with Spring / Roo SafeHTML wrappers GPE: Maven support, integration GWT Designer Application framework - RequestFactory - Activities and Places Cell Widgets and Editor framework Monday, March 14, 2011 37
  • 38. Four flavors of RPC 1. RequestBuilder + JSONParser (see RESTY-GWT) 2. RequestBuilder + XMLParser 3. GWT-RPC (easiest) 4. RequestFactory (new in 2.1) Monday, March 14, 2011 38
  • 39. GWT-RPC @RemoteServiceRelativePath("greet") public interface GreetingService extends RemoteService { String greetServer(String name) throws IllegalArgumentException; } public interface GreetingServiceAsync { void greetServer(String input, AsyncCallback<String> callback) throws IllegalArgumentException; } public class GreetingServiceImpl extends RemoteServiceServlet implements GreetingService { public String greetServer(String input) throws IllegalArgumentException { ... } } Monday, March 14, 2011 39
  • 40. Simple, powerful GWT-RPC Send / receive Plain Old Java Objects (POJO) - Easy: interface, async, & implementation - Versioned to help keep client & server in sync - Even smaller than JSON - Supports polymorphism - No JavaScript hijacking risk (JSON attack) - Easy to find all calls to given service in IDE Monday, March 14, 2011 40
  • 41. GWT 2.1 RequestFactory Newer alternative to GWT-RPC Designed for data-oriented services - Higher level of abstraction than GWT-RPC - Foundation for future caching / batching Even faster than GWT-RPC - JSON-based == very fast (no serialization / deserialization required) - Tracks changes on the client and sends only diffs Monday, March 14, 2011 41
  • 42. RequestFactory The entity / DTO problem EntityProxy / ValueProxy Service stub interfaces extend RequestContext AppRequestFactory extends RequestFactory GWT.create(MyAppRequestFactory.class) Monday, March 14, 2011 42
  • 43. EntityProxy @Entity public class ItemList extends DatastoreObject { private String name; private Key<AppUser> owner; private ListType listType; @Embedded private List<ListItem> items; // value type ... } @ProxyFor(ItemList.class) public interface ItemListProxy extends DatastoreObjectProxy { // TODO enums work! public enum ListType {NOTES, TODO} String getName(); void setName(String name); List<ListItemProxy> getItems(); AppUserProxy getOwner(); // NOT Key ... } Monday, March 14, 2011 43
  • 44. DatastoreObject package com.listwidget.domain; public class DatastoreObject { @Id private Long id; private Integer version = 0; @PrePersist void onPersist() { this.version++; } ... } package com.listwidget.shared.proxy; public interface DatastoreObjectProxy extends EntityProxy { Long getId(); Integer getVersion(); } Monday, March 14, 2011 44
  • 45. ValueProxy public class ListItem // POJO { private String itemText; private Date dateCreated; public Date getDateCreated() { return dateCreated; } } @ProxyFor(value = ListItem.class) public interface ListItemProxy extends ValueProxy { String getItemText(); void setItemText(String itemText); Date getDateCreated(); } Monday, March 14, 2011 45
  • 46. Making a RequestFactory public interface ListwidgetRequestFactory extends RequestFactory { @Service(value = ItemListDao.class, locator = DaoServiceLocator.class) interface ItemListRequestContext extends RequestContext { Request<List<ItemListProxy>> listAll(); Request<Void> save(ItemListProxy list); Request<ItemListProxy> saveAndReturn(ItemListProxy newList); } ItemListRequestContext itemListRequest(); } private final ListwidgetRequestFactory rf = GWT.create(ListwidgetRequestFactory.class); Monday, March 14, 2011 46
  • 47. Using RequestFactory @Override public void persistList(String listName) { final ListwidgetRequestFactory rf = this.clientFactory .getRequestFactory(); ItemListRequestContext reqCtx = rf.itemListRequest(); final ItemListProxy newList = reqCtx.create(ItemListProxy.class); newList.setName(listName); newList.setListType(ListType.TODO); reqCtx.saveAndReturn(newList).fire(new Receiver<ItemListProxy>() { @Override public void onSuccess(final ItemListProxy savedList) { // Refresh table listDataProvider.getData(); } }); } Monday, March 14, 2011 47
  • 48. Using RequestFactory @Override public void update(int index, ItemListProxy obj, final String newName) { ItemListRequestContext reqCtx = clientFactory.getRequestFactory() .itemListRequest(); ItemListProxy editable = reqCtx.edit(obj); editable.setName(newName); reqCtx.save(editable).fire(new Receiver<Void>() { @Override public void onSuccess(Void response) { eventBus.fireEvent(new MessageEvent(newName + " updated", MessageType.INFO)); } }); } Monday, March 14, 2011 48
  • 49. Using RequestFactory private void getData() { // To retrieve relations and value types, use .with() Request<List<ItemListProxy>> findAllReq = rf.itemListRequest() .listAll().with("owner"); // Receiver specifies return type findAllReq.fire(new Receiver<List<ItemListProxy>>() { @Override Text public void onSuccess(List<ItemListProxy> response) { updateRowData(0, response); } }); } Monday, March 14, 2011 49
  • 50. Using RequestFactory editList = reqCtx.edit(editList); List<ListItemProxy> items = editList.getItems(); // must initialize collections if (items == null) { editList.setItems(new ArrayList<ListItemProxy>()); } editList.getItems().add(newItem); reqCtx.save(editList).with("items").to(new Receiver<Void>() { @Override public void onSuccess(Void response) { itemsProvider.setList(editList.getItems()); itemsProvider.refresh(); } }).fire(); Monday, March 14, 2011 50
  • 51. GWT MVP - Concepts View - Interface + implementation - Interface enables testing without GWTTestCase - Typically expensive to construct so make reusable Presenter - No Widgets, just business logic - Middle man between service layer and views Monday, March 14, 2011 51
  • 52. GWT MVP - Concepts Place - Place represents bookmarkable state of an activity - PlaceController makes back button / bookmarks work like users expect - PlaceTokenizers map to / from String tokens on URL Monday, March 14, 2011 52
  • 53. Demo third_party/java_src/gwt/svn/trunk/samples/ expenses Monday, March 14, 2011 53
  • 54. Place public class EditListPlace extends Place { private String token; public EditListPlace(String token) { this.token = token; } public String getToken() { return token; } public static class Tokenizer implements PlaceTokenizer<EditListPlace> { public EditListPlace getPlace(String token) { return new EditListPlace(token); } public String getToken(EditListPlace place) { return place.getToken(); } } } Monday, March 14, 2011 54
  • 55. PlaceHistoryMapper /** * PlaceHistoryMapper interface is used to attach all places which the * PlaceHistoryHandler should be aware of. This is done via the @WithTokenizers * annotation or by extending PlaceHistoryMapperWithFactory and creating a * separate TokenizerFactory. */ @WithTokenizers({ ListsPlace.Tokenizer.class, EditListPlace.Tokenizer.class }) public interface AppPlaceHistoryMapper extends PlaceHistoryMapper { } Monday, March 14, 2011 55
  • 56. Hello Places // Start PlaceHistoryHandler with our PlaceHistoryMapper PlaceHistoryMapper historyMapper = clientFactory.getHistoryMapper(); PlaceHistoryHandler historyHandler = new PlaceHistoryHandler(hisoryMapper); historyHandler.register(placeController, eventBus, defaultPlace); // Goes to place represented on URL or default place historyHandler.handleCurrentHistory(); Monday, March 14, 2011 56
  • 57. Places: Moving parts Monday, March 14, 2011 57
  • 58. Places: Go to Monday, March 14, 2011 58
  • 59. Places: Back and forth Monday, March 14, 2011 59
  • 60. Activities Activity, ActivityManager are not required! ActivityManager - Owns a region of the window - Choose what to do with it on place change Activity (“wake up, set up, show up”) - Started by ActivityManager - Provides a widget to display, asynchronously - Can refuse to relinquish screen Monday, March 14, 2011 60
  • 61. Activity public class EditListActivity extends AbstractActivity implements Presenter { private ClientFactory clientFactory; private EventBus eventBus; public EditListActivity(ClientFactory cf, EditListPlace editListPlace) { this.clientFactory = cf; this.itemListToken = editListPlace.getToken(); } @Override public void start(final AcceptsOneWidget panel, EventBus eventBus) { this.eventBus = eventBus; ... panel.setWidget(clientFactory.getEditListView()); } ... } Monday, March 14, 2011 61
  • 62. ActivityMapper public class AppActivityMapper implements ActivityMapper { private ClientFactory clientFactory; public AppActivityMapper(ClientFactory clientFactory) { super(); this.clientFactory = clientFactory; } @Override public Activity getActivity(Place place) { if (place instanceof EditListPlace) { return new EditListActivity(clientFactory, (EditListPlace) place); } if (place instanceof ListsPlace) { return new ListsActivity(clientFactory); } return null; } } Monday, March 14, 2011 62
  • 63. ActivityMapper Idioms Disposable Activities, shared views: if (place instanceof FooPlace) { return new FooActivity(theOnlyFooView); } Singleton: if (place instanceof FooPlace) { theOnlyFooActivity.update((FooPlace) place); return theOnlyFooActivity; } Monday, March 14, 2011 63
  • 67. Activities and Places wiring // Start ActivityManager for the nav (west) panel with our WestActivityMapper ActivityMapper westActivityMapper = new WestActivityMapper(clientFactory); ActivityManager westActivityManager = new ActivityManager(westActivityMapper, eventBus); westActivityManager.setDisplay(westPanel); // Start ActivityManager for the main (center) panel with our CenterActivityMapper ActivityMapper centerActivityMapper = new CenterActivityMapper(clientFactory); ActivityManager centerActivityManager = new ActivityManager(centerActivityMapper, eventBus); centerActivityManager.setDisplay(centerPanel); // Start PlaceHistoryHandler with our PlaceHistoryMapper PlaceHistoryMapper historyMapper = GWT.create(AppPlaceHistoryMapper.class); PlaceHistoryHandler historyHandler = new PlaceHistoryHandler(historyMapper); historyHandler.register(placeController, eventBus, defaultPlace); RootPanel.get().add(dockLayoutPanel); // Goes to place represented on URL or default place historyHandler.handleCurrentHistory(); Monday, March 14, 2011 67
  • 68. Cell Widgets Fast, lightweight table rendering Data binding with DataProviders, ValueUpdaters Scrolling and paging controls Sortable columns, adjustable width TextBox, IntegerBox, ValueBox<T> Monday, March 14, 2011 68
  • 70. Editable Column // Editable column for list name nameColumn = new Column<ItemListProxy,String>(new EditTextCell()) { @Override public String getValue(ItemListProxy list) { return list.getName(); } }; Monday, March 14, 2011 70
  • 71. Custom Column type // Note Flyweight pattern: only one instance of HyperlinkCell passed to the Column Column<ItemListProxy, Hyperlink> linkColumn = new Column<ItemListProxy, Hyperlink>(new HyperlinkCell()) { @Override public Hyperlink getValue(ItemListProxy list) { String proxyToken = clientFactory.getRequestFactory().getHistoryToken(list.stableId()); String historyToken = clientFactory.getHistoryMapper().getToken(new EditListPlace(proxyToken)); Hyperlink h = new Hyperlink(list.getName(),historyToken); return h; } }; Monday, March 14, 2011 71
  • 72. Populating a CellTable public static class MyDataProvider extends AsyncDataProvider<ItemListProxy> { @Override protected void onRangeChanged(HasData<ItemListProxy> display) { // To retrieve relations and value types, use .with() Request<List<ItemListProxy>> findAllReq = rf.itemListRequest() .listAll().with("owner"); // Receiver specifies return type findAllReq.fire(new Receiver<List<ItemListProxy>>() { @Override public void onSuccess(List<ItemListProxy> response) { updateRowData(0, response); } }); } } this.myDataProvider = new MyDataProvider(requestFactory); Monday, March 14, 2011 72
  • 73. Updating with a CellTable public class NameFieldUpdater implements FieldUpdater<ItemListProxy, String> { @Override public void update(int index, ItemListProxy obj, final String newName) { ItemListRequestContext reqCtx = clientFactory.getRequestFactory() .itemListRequest(); ItemListProxy editable = reqCtx.edit(obj); editable.setName(newName); reqCtx.save(editable).fire(new Receiver<Void>() { @Override public void onSuccess(Void response) { eventBus.fireEvent(new MessageEvent(newName + " updated", MessageType.INFO)); } }); } }; // Make list name field editable display.getNameColumn().setFieldUpdater(new NameFieldUpdater()); Monday, March 14, 2011 73
  • 74. GWT Logging GWT now has java.util.Logging emulation Configure in your .gwt.xml Easily enable remote logging, too Monday, March 14, 2011 74
  • 75. GWT secrets -compileReport Monday, March 14, 2011 75
  • 76. GWT secrets: faster compile - -draftCompile skips optimizations - Set only one user-agent in gwt.xml for dev - Careful with RPC polymorphism Monday, March 14, 2011 76
  • 77. GWT secrets: shrink JS - -XdisableClassMetadata: Disables some java.lang.Class methods (e.g. getName()) - <set-property name="compiler.stackMode" value="strip"/> Removes client-side stack trace info (can reduce code size up to 15%) - <set-configuration-property name="CssResource.obfuscationPrefix" value="empty"/> Monday, March 14, 2011 77
  • 78. GWT secrets: shrink JS - <set-property name="compiler.enum.name.obfuscation" value="true"/> (only if you’re not using enums as String values) - -XdisableCastChecking: Disables run-time checking of cast operations (use with caution) - See GWT FAQ, CompilerParameters.gwt.xml Monday, March 14, 2011 78
  • 79. GWT speak “Very productive environment for Java developers, but there is a learning curve” “UI layout and styling is a challenge” “GWT has enabled our team to run much faster than we could otherwise” “Would be impossible to write our app without GWT” Monday, March 14, 2011 79
  • 80. New GWT book http://code.google.com/webtoolkit/books.html Monday, March 14, 2011 80
  • 81. Thank you! Where to get it: http://code.google.com/webtoolkit/ Wiki, issue tracker, source: http://code.google.com/p/google-web-toolkit/ Official GWT blog: http://google-web-toolkit.blogspot.com/ Twitter: @googledevtools 81 Monday, March 14, 2011 81

Notas do Editor

  1. \n
  2. What&amp;#x2019;s new in GWT?\n
  3. \n
  4. \n
  5. Google Web Toolkit 101\n
  6. \n
  7. \n
  8. \n
  9. You get the benefit of code completion, javadoc\nAND Eclipse refactoring tools\n
  10. One GWT\n
  11. \n
  12. \n
  13. \n
  14. \n
  15. GWT has two main goals\n
  16. Google Web Toolkit gives you tools for the whole development lifecycle\n
  17. Easiest way to get started is with Google Plugin for Eclipse\n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. Instantiations, free, contribute WindowBuilder\nGenerates corresponding Java code and provides round-trip editing\nUiBinder, externalize strings, absolute layout, new LayoutPanel\n
  25. You can also use GWT Designer with UiBinder XML templates\n
  26. GWT Designer provides a nice CSS editor with visual preview\n
  27. Now you&amp;#x2019;ve written some code and you want to test it.\nGWT development mode lets you test changes quickly without having to compile to JavaScript\n
  28. Now you&amp;#x2019;ve written some code and you want to test it.\nGWT development mode lets you test changes quickly without having to compile to JavaScript\n
  29. Now you&amp;#x2019;ve written some code and you want to test it.\nGWT development mode lets you test changes quickly without having to compile to JavaScript\n
  30. Browser plugin connects to the GWT code server running in Eclipse\nand runs your Java code.\n
  31. Browser plugin connects to the GWT code server running in Eclipse\nand runs your Java code.\n
  32. Browser plugin connects to the GWT code server running in Eclipse\nand runs your Java code.\n
  33. Browser plugin connects to the GWT code server running in Eclipse\nand runs your Java code.\n
  34. Browser plugin connects to the GWT code server running in Eclipse\nand runs your Java code.\n
  35. Dev mode also lets you debug right inside Eclipse\n
  36. When you&amp;#x2019;re ready to deploy, you run the GWT compiler, which\npackages your app in a standard WAR structure\n
  37. Download SpeedTracer for Chrome from the GWT team\n
  38. Launch from Eclipse to find Java code for certain events\n
  39. SpeedTracer can even show server-side speed traces in GAE\nand Spring tcServer\n
  40. Deploy WAR to any servlet container\nOr one click to GAE\n
  41. \n
  42. How do you upgrade your application?\nEnsure that new images, CSS, etc. are updated on each browser?\nGenerates random URLs\nNocache does deferred binding (browser detection, i18n), then pulls in cached permutation for the browser\n
  43. GWT compiler creates the bundled image and calculates cropping\nso your can use each image just like normal\n
  44. GWT compiler creates the bundled image and calculates cropping\nso your can use each image just like normal\n
  45. GWT compiler creates the bundled image and calculates cropping\nso your can use each image just like normal\n
  46. GWT compiler creates the bundled image and calculates cropping\nso your can use each image just like normal\n
  47. \n
  48. \n
  49. \n
  50. Even more on its way: lightweight collections, enum ordinalization\n\n
  51. \n
  52. \n
  53. \n
  54. \n
  55. \n
  56. \n
  57. \n
  58. \n
  59. \n
  60. \n
  61. \n
  62. \n
  63. \n
  64. \n
  65. \n
  66. DatastoreObject ID/version, Key, enum, value type\n
  67. \n
  68. ListItem a POJO on server only\nAll proxies go in a shared directory (client and server)\n
  69. interface extends RequestFactory, @Service points to impl, locator can find it\nservice stubs extend RequestContext, return parameterized Request\naccessor for each service stub\n
  70. Create a new object, call .create() to get mutable obj\nFire the request with Receiver (like AsyncCallback)\n
  71. To update, must edit first to get mutable obj\n
  72. .with\n
  73. must edit() parent obj, init Collections, save .with() for relations &amp; value types\n
  74. No special methods to implement\nReusable via factory\n
  75. No special methods to implement\nReusable via factory\n
  76. \n
  77. evil back button\n
  78. \n
  79. Extends Place, constructors can take arguments\nTokenizer converts to/from String\n
  80. \n
  81. Lists all places that participate in browser history\nAll generated, can also implement PlaceHistoryMapper yourself\n
  82. \n
  83. instantiate ActivityManagers, PlaceHistoryMapper, PlaceHistoryHandler\nAdd a widget to the root panel and handleCurrentHistory()\nSee also CachingActivityManager, FilteredActivityManager\n
  84. Define a model to cleanly separate view &amp; presenter code\n
  85. Column represents model of a column, contains no widget code\nSo can use in presenter or view\n
  86. \n
  87. \n
  88. \n
  89. Java is the kingdom of nouns\n
  90. \n
  91. How do you shrink it and make compile faster? shows each permutation, split point, package\n
  92. \n
  93. \n