SlideShare ist ein Scribd-Unternehmen logo
1 von 36
Remote Procedure Calls in GWT
•   How they are implemented
•   How to use them effectively
•   Best practices and design patterns
•   Future directions and possibilities
•   Discussion
Introduction
• Your presenter: Rob Jellinghaus
• Contributor to GWT
  – Refactored server-side RPC implementation in GWT
    1.4
• Architect at SF startup
• http://robjsoftware.org
What is GWT RPC?
• Simple way for your GWT clients to call your
  Java server code
• Looks a lot like regular Java procedure calls;
  can pass complex objects easily
• Will skim over the basics
  – GWT documentation is good
• Won’t address security
  – Too large a topic
  – Covered elsewhere at this conference
All Abstractions Leak
• Abstractions are great, but hidden details have a
  way of surfacing
  – Spolsky’s Law: All non-trivial abstractions, to
    some degree, are leaky
• GWT RPC is no exception
  – At least GWT is upfront about such things!
• Forewarned is forearmed
Asynchrony
• The biggest difference: GWT RPC returns immediately
• Normal procedure call:
   Object result = myService.doWork();
   doSomethingWith(result);
• GWT RPC:
   myService.doWork(myCallback);
   … wait a while …
   public void onSuccess(Object result) {
       doSomethingWith(result);
   }
Asynchrony Is Your Friend
• The very definition of AJAX
   – Old news to AJAX hackers, but unusual in the Java
     world
• If your app isn’t waiting for the server, then
  your users aren’t either
• Don’t work around it, embrace it!
   – Workarounds are horrible and user-hostile
GWT RPC Lives in the Compiler
• RPC is implemented as a compiler extension
  – See Ray Cromwell’s talk on “Generators”
• Enables very highly optimized RPC code
  – Compiler looks at your interfaces and object types
  – Emits tightly tuned encoding / decoding Javascript
• If GWT can’t compile it, you can’t send it
  – Unlike RMI / Java serialization, where you can send
    objects for which you don’t have source
Very brief example
• This class:
   public class Entry implements com.google.gwt.user.client.rpc.IsSerializable{
      private dto.domain.Blog blog;
      private java.lang.String body;
      …
   }



• Gets this generated deserializer (details elided):
   function dto_domain_Entry_1FieldSerializer_deserialize(streamReader, instance) {
       dto_domain_Entry_1FieldSerializer_setBlog (instance,
       com_google_gwt_lang_Cast_dynamicCast__Ljava_lang_Object_2I…
         (streamReader.readObject__(), 17));
       dto_domain_Entry_1FieldSerializer_setBody… (instance,
       streamReader.readString__());
     …
   }
GWT serialization vs. others
• GWT serialization:
   – Fully statically compiled, metadata-guided
   – No class hooks
• Java serialization:
   – Reflection-based
   – readObject, writeObject hooks
• Java persistence serialization:
   – Reflection-based, metadata-guided
   – Bytecode proxies injected
Server integration: basics
• Simplest technique: RemoteServiceServlet
   public interface MyServiceInterface { public Object
     doWork(); }
   public class MyServiceServlet extends RemoteServiceServlet
     implements MyServiceInterface {
       public Object doWork() { … }
   }
• Works nicely out of the box
• Requires one servlet class per interface you expose
   – Doesn’t work well to expose pre-existing components
   – Fixed with my refactorings in GWT 1.4
Server integration: Spring
• Several Spring integrations exist
  – George Georgovassilis & Rob Hanson’s GWT-SL
    server library
  – Chris Lee’s one-page integration
• Couples with Spring’s “handler” mechanism for
  web requests
• Can expose pure POJOs (GWT-SL), or can
  annotate service classes (Chris Lee)
Server integration: Seam
• Seam 2.0 has built-in GWT integration
   – GWTService web resource
• Set your endpointURL to be “seam/resource/gwt”
• RPC requests route to a Seam component by interface
  name:
   @Name("org.jboss.seam.example.remoting.gwt.client.MyService")
   public class ServiceImpl implements MyService
   {
      @WebRemote
      public String askIt(String question)
      {
        return "42. Its the real question that you seek now.";
      }…
   }
Server integration: Seam/JSF + GWT
• Wrap your GWT module in a JSF component
• Drop it into a JSF page
• Route its RPC to any Seam component:
  <!-- routes to the BlogService on the gwtBlog component -->
      <bloglist:component id="main2">
          <gwt:gwtListener serviceBean="#{gwtBlog}"/>
      </bloglist:component>


• Only one problem… broken with Seam 2 at the
  moment
  – Anyone want to help? 
Using GWT RPC Effectively
• We’ve covered the basics
• Now for best practices
  – Responsiveness
  – Asynchrony
  – Serialization interactions
  – API design and service orientation
Responsiveness: Balanced RPC
• Messages Want To Be Small
  – Small messages are quick to process
  – Low encoding & decoding overhead
• But Messages Want To Be Big
  – Networks are slow
  – Many messages = much exposure to network latency
• Balance your RPC
  – Only pull data visible to the user; paginate on server
  – Don’t build too many UI elements either
Asynchrony: No More Straight Lines
• Synchronous code might look like this
  – (can’t use Java 5 yet in GWT 1.4):
  Blog blog = blogService.getBlog();
  List entries = blogService.getEntries();
  for (int i = 0; i < entries.size(); i++) {
       BlogEntry entry = (BlogEntry)entries.get(i);
       TreeItem item = new TreeItem(entry.getTitle());
       tree.addItem(item);
       String body = blogService.formatText(entry.getId());
       entry.setBody(body);
  }
Fun with Inner Classes
• Anonymous inner classes split up the code inline:
  Blog blog = null;
  List entries = null;
  blogService.getBlog(new AsyncCallback() {
       public void onSuccess(Object result) {
                blog = (Blog)result;
                blogService.getEntries(new AsyncCallback() {
                         public void onSuccess(Object result) {
                                  entries = (List)result;
                         }
                });
       }
  });

• But gets very nested and tough to read
Callback Objects
• Break out the callbacks into helpers:
     Blog blog = null;
     blogService.getBlog(new AsyncCallback() {
       public void onSuccess(Object result) {
                blog = (Blog)result;
                blogService.getBlogEntries(makeEntriesCallback());
       }
     });
  public AsyncCallback makeEntriesCallback() {
     return new AsyncCallback() {
       public void onSuccess(Object result) {
         List entries = (List)result;
         …

• Makes the sequence more descriptive
Stateful Callback Objects
• Multiple RPCs in flight at once:
   List entries = (List)result;
   for (int i = 0; i < entries.size(); i++) {
      BlogEntry entry = (BlogEntry)entries.get(I);
      TreeItem item = new TreeItem(entry.getTitle()); tree.addItem(item);
      blogService.fetchText(entry.getId(), makeEntryCallback(item));
      …
   }
   public AsyncCallback makeEntryCallback(TreeItem item) {
      return new AsyncCallback() {
        public void onSuccess(Object text) {
           item.setText((String)text); } } }

• Each callback knows what to do with its response
• Can extend this pattern to all kinds of sequences
Transactions
• Updates can sometimes require multiple server
  calls
• Keep state in your client until commit time
  – The less server state the better
  – But can’t send too much state at once when
    committing
• Can use “chained command” pattern in your
  service
  – Send a whole sequence of API calls
  – Rather like offline sync in Google Gears
When Abstractions Attack
• GWT makes it easy to call your Java backend
• Many Java backends use Hibernate, JPA, EJB3…
• GWT abstraction: serialize object graph to Javascript
   – Needs to see all the source
• JPA abstraction: load partial object graph lazily
   – Create secret hidden $$CGLIB classes, private collections
• GWT + JPA: KABOOM!
   – GWT can’t serialize a lazy persistence proxy or Hibernate
     PersistentMap
   – Spolsky’s Revenge
DTOs: Back to the Future
• Data transfer objects: intermediate object layer
• Copy your persistent objects into separate DTO
  structure
  – GWT only sees the DTO objects
  – Explicit control over what gets sent
  – Can limit features used in DTO objects (avoid
    generics, annotations)
  – Risk of lots of boilerplate code
Generated DTOs: Less Boilerplate
• Automatically generate DTOs at build time
   – Codehaus JAM project: Java source walker
   – Compile DTOs into a standalone GWT module
   for (JField field : jClass.getFields()) {
     String name = field.getSimpleName();
     String type = field.getType().getQualifiedName();
     if (type.startsWith("java.")) {
       // skip over classes that aren't emulated by GWT…


• Reflection can populate DTOs
   – Kind of an intermediate “serializer” from persistent objects to
     DTO objects
   – Hibernate4gwt project allows this (with merging, too)
Rocket Science: Customizing RPC
• GWT ServerSerializationStreamWriter
   – Custom GWT class that traverses objects
   – Can make subclass with special handling of persistent classes
       • Null out lazy collections, load lazy proxy objects
   – Risks breaking if GWT changes RPC implementation
   public void serializeValue(Object value, Class type) throws
   SerializationException {
   …
   else if (type == java.util.Set.class) {
      Set hashSet = new HashSet();
      if (value instanceof PersistentSet) {
      PersistentSet persSet = (PersistentSet) value;
      if (persSet.wasInitialized()){
        hashSet.addAll(persSet);
      }…
The Trouble with Merging
• Once you send your objects back up, you have to merge
  them
• Seam / JPA stateful dogma says this is a weakness of
  GWT and other rich clients
   – Stateful apps keep persistence context around while user is
     interacting; dirty objects tracked for free
• But persistence contexts die badly if commit fails
   – Only solution is to abandon all your modified state!
• GWT APIs need to clearly identify what’s changed
   – Simplifies the merge problem
   – Arguably easier to recover from conflicts
   – Scales better, too
DAOs are not APIs
• Tempting to just expose your persistence layer
• Don’t do this!
  – Persistence operations are not a good API
• APIs should be intentional
  – Should be tuned to application use cases
  – Objects exposed should be client-meaningful
     • May or may not be your domain objects
  – Think services rather than data accesses
• Service-oriented backends are more scalable
Serializable != IsSerializable
• Java serialization is not GWT serialization
  – Java serialization expects a very particular contract
  – Hardcoded to binary / byte level; lots of existing
    readObject, writeObject methods
  – Those methods not necessarily compilable by GWT
  – Java serialization not efficient in Javascript
• In GWT, “java.lang.Serializable” just means
  “OK to send by GWT RPC”
  – Does NOT mean “Will use existing readObject /
    writeObject implementations”
The Home Stretch
• Cool tricks
• GWT 1.5
• Future possibilities
  – Ranging from “sensible” to “wildly ambitious”
• Other interesting systems
• Conclusion
Preserialized objects
• You’ve got a bunch of initialization data
   – You want to download it efficiently
   – Maximum-speed startup, one round-trip
      • iPhone apps, anyone?
• Serialize the data on the server, then save the
  bytes
• Blast them out from cache, then deserialize
  them explicitly
   – In GWT 1.5: get SerializationStreamReader from
     client-side RPC proxy
GWT 1.5: Java 5 for the win!
• Plan: full support for enumerated types, generic
  collections
• No more @gwt.typeargs
  – Typed collections get optimized RPC automatically
• Annotations are OK
  – Not yet clear what GWT will use them for
  – Compiler should be able to ignore annotations w/o
    available source
     • So @Entity, @Component, etc. won’t choke GWT
Possibility: RPC metadata
• Support for request/response headers in RPC
  messages
• Use cases:
  – Servers that use HTTP headers for authorization
  – Support for Spring webflow / Seam conversations
• API totally undefined:
  – Stateful instantiation of Service? Callback functions?
  – Related to RPC cancellation / request control?
  – Discuss on GWT Contributors forum
Possibility: JSON-style encoding
• GWT compiler generates current deserializers
  – Pretty much the best Javascript functions can do
  – But still not as good as JSON
• What if RPC payloads were deserialized by the
  browser, as with JSON?
  – Could be blazingly fast deserialization
  – AND less client-side code
  – But lots of issues to work out (see GWTC thread)
• Not high priority for GWT 1.5, but later…?
Possibility: Declarative data binding
• Right now RPC is strictly imperative
• Some modern frameworks (Seam) support
  declarative data binding
  – Refer to server data objects by name
  – UI components bind to specific sub-objects
• Declarative UI support underway for GWT;
  perhaps data binding a natural extension?
  – Could also integrate some support for offline
    synchronization?
  – Pagination done “under the hood”?
Possibility: Generalized mappings
• Persistence mapping is very similar to client-server
  DTO mapping
   – In both cases, you have data spaces containing objects that
     must be transferred and correlated
• Why not a unified answer?
   – What if persistence mappings could be extended to define data
     transfer behaviors to the client?
   – And then further, to define client-side update sets and
     synchronization behaviors?
   – Attack the DTO problem at the framework level!
• See LINQ 2.0 work from Microsoft Research
Other interesting systems
• Good old RMI (Sun)
   – Classloader problems much worse than widely known
• Caja (Ben Laurie, Mark Miller, Google)
   –   Capability-secure Javascript
   –   Mobile code, with non-broken sandboxes
   –   Influenced by E (asynchronous capability messaging)
   –   (GWT -> Caja scriptlets???)
• LINQ 2.0 (Erik Meijer, Microsoft)
   – Automatically restructure sequential client app to be
     asynchronous multi-tier app
   – Integrate SQL queries, XML mappings, RPC
   – MSIL -> Javascript (like GWT for .NET bytecode)
Thanks!
• Hope this was helpful 
• Thanks to GWT team & Pearson
• http://robjsoftware.org/gwt2007
  – links & further references
• Go forth and create great apps!
  – And then post about them on the GWT groups!
  – And then start contributing to GWT!!!

Weitere ähnliche Inhalte

Was ist angesagt?

Building a serverless company on AWS lambda and Serverless framework
Building a serverless company on AWS lambda and Serverless frameworkBuilding a serverless company on AWS lambda and Serverless framework
Building a serverless company on AWS lambda and Serverless frameworkLuciano Mammino
 
Developing distributed applications with Akka and Akka Cluster
Developing distributed applications with Akka and Akka ClusterDeveloping distributed applications with Akka and Akka Cluster
Developing distributed applications with Akka and Akka ClusterKonstantin Tsykulenko
 
Apache Sling - Distributed Eventing, Discovery, and Jobs (adaptTo 2013)
Apache Sling - Distributed Eventing, Discovery, and Jobs (adaptTo 2013)Apache Sling - Distributed Eventing, Discovery, and Jobs (adaptTo 2013)
Apache Sling - Distributed Eventing, Discovery, and Jobs (adaptTo 2013)Carsten Ziegeler
 
Dropwizard Internals
Dropwizard InternalsDropwizard Internals
Dropwizard Internalscarlo-rtr
 
Play + scala + reactive mongo
Play + scala + reactive mongoPlay + scala + reactive mongo
Play + scala + reactive mongoMax Kremer
 
Reactive integrations with Akka Streams
Reactive integrations with Akka StreamsReactive integrations with Akka Streams
Reactive integrations with Akka StreamsKonrad Malawski
 
Batching and Java EE (jdk.io)
Batching and Java EE (jdk.io)Batching and Java EE (jdk.io)
Batching and Java EE (jdk.io)Ryan Cuprak
 
Distributed Eventing in OSGi - Carsten Ziegeler
Distributed Eventing in OSGi - Carsten ZiegelerDistributed Eventing in OSGi - Carsten Ziegeler
Distributed Eventing in OSGi - Carsten Ziegelermfrancis
 
Developing Java based microservices ready for the world of containers
Developing Java based microservices ready for the world of containersDeveloping Java based microservices ready for the world of containers
Developing Java based microservices ready for the world of containersClaus Ibsen
 
Lightbend Lagom: Microservices Just Right (Scala Days 2016 Berlin)
Lightbend Lagom: Microservices Just Right (Scala Days 2016 Berlin)Lightbend Lagom: Microservices Just Right (Scala Days 2016 Berlin)
Lightbend Lagom: Microservices Just Right (Scala Days 2016 Berlin)mircodotta
 
Securing Microservices using Play and Akka HTTP
Securing Microservices using Play and Akka HTTPSecuring Microservices using Play and Akka HTTP
Securing Microservices using Play and Akka HTTPRafal Gancarz
 
Dropwizard and Groovy
Dropwizard and GroovyDropwizard and Groovy
Dropwizard and Groovytomaslin
 
Projects Valhalla, Loom and GraalVM at JCon 2020
Projects Valhalla, Loom and GraalVM at JCon 2020Projects Valhalla, Loom and GraalVM at JCon 2020
Projects Valhalla, Loom and GraalVM at JCon 2020Vadym Kazulkin
 
Short intro to scala and the play framework
Short intro to scala and the play frameworkShort intro to scala and the play framework
Short intro to scala and the play frameworkFelipe
 
System Integration with Akka and Apache Camel
System Integration with Akka and Apache CamelSystem Integration with Akka and Apache Camel
System Integration with Akka and Apache Camelkrasserm
 
Why jakarta ee matters (ConFoo 2021)
Why jakarta ee matters (ConFoo 2021)Why jakarta ee matters (ConFoo 2021)
Why jakarta ee matters (ConFoo 2021)Ryan Cuprak
 
Distributed Eventing in OSGi
Distributed Eventing in OSGiDistributed Eventing in OSGi
Distributed Eventing in OSGiCarsten Ziegeler
 
Elements for an iOS Backend
Elements for an iOS BackendElements for an iOS Backend
Elements for an iOS BackendLaurent Cerveau
 
Objective-C Is Not Java
Objective-C Is Not JavaObjective-C Is Not Java
Objective-C Is Not JavaChris Adamson
 

Was ist angesagt? (20)

Building a serverless company on AWS lambda and Serverless framework
Building a serverless company on AWS lambda and Serverless frameworkBuilding a serverless company on AWS lambda and Serverless framework
Building a serverless company on AWS lambda and Serverless framework
 
Developing distributed applications with Akka and Akka Cluster
Developing distributed applications with Akka and Akka ClusterDeveloping distributed applications with Akka and Akka Cluster
Developing distributed applications with Akka and Akka Cluster
 
Apache Sling - Distributed Eventing, Discovery, and Jobs (adaptTo 2013)
Apache Sling - Distributed Eventing, Discovery, and Jobs (adaptTo 2013)Apache Sling - Distributed Eventing, Discovery, and Jobs (adaptTo 2013)
Apache Sling - Distributed Eventing, Discovery, and Jobs (adaptTo 2013)
 
Dropwizard Internals
Dropwizard InternalsDropwizard Internals
Dropwizard Internals
 
Play + scala + reactive mongo
Play + scala + reactive mongoPlay + scala + reactive mongo
Play + scala + reactive mongo
 
Reactive integrations with Akka Streams
Reactive integrations with Akka StreamsReactive integrations with Akka Streams
Reactive integrations with Akka Streams
 
Batching and Java EE (jdk.io)
Batching and Java EE (jdk.io)Batching and Java EE (jdk.io)
Batching and Java EE (jdk.io)
 
Distributed Eventing in OSGi - Carsten Ziegeler
Distributed Eventing in OSGi - Carsten ZiegelerDistributed Eventing in OSGi - Carsten Ziegeler
Distributed Eventing in OSGi - Carsten Ziegeler
 
Developing Java based microservices ready for the world of containers
Developing Java based microservices ready for the world of containersDeveloping Java based microservices ready for the world of containers
Developing Java based microservices ready for the world of containers
 
Lightbend Lagom: Microservices Just Right (Scala Days 2016 Berlin)
Lightbend Lagom: Microservices Just Right (Scala Days 2016 Berlin)Lightbend Lagom: Microservices Just Right (Scala Days 2016 Berlin)
Lightbend Lagom: Microservices Just Right (Scala Days 2016 Berlin)
 
Securing Microservices using Play and Akka HTTP
Securing Microservices using Play and Akka HTTPSecuring Microservices using Play and Akka HTTP
Securing Microservices using Play and Akka HTTP
 
Dropwizard and Groovy
Dropwizard and GroovyDropwizard and Groovy
Dropwizard and Groovy
 
Projects Valhalla, Loom and GraalVM at JCon 2020
Projects Valhalla, Loom and GraalVM at JCon 2020Projects Valhalla, Loom and GraalVM at JCon 2020
Projects Valhalla, Loom and GraalVM at JCon 2020
 
Short intro to scala and the play framework
Short intro to scala and the play frameworkShort intro to scala and the play framework
Short intro to scala and the play framework
 
System Integration with Akka and Apache Camel
System Integration with Akka and Apache CamelSystem Integration with Akka and Apache Camel
System Integration with Akka and Apache Camel
 
Why jakarta ee matters (ConFoo 2021)
Why jakarta ee matters (ConFoo 2021)Why jakarta ee matters (ConFoo 2021)
Why jakarta ee matters (ConFoo 2021)
 
Distributed Eventing in OSGi
Distributed Eventing in OSGiDistributed Eventing in OSGi
Distributed Eventing in OSGi
 
Elements for an iOS Backend
Elements for an iOS BackendElements for an iOS Backend
Elements for an iOS Backend
 
Node.js code tracing
Node.js code tracingNode.js code tracing
Node.js code tracing
 
Objective-C Is Not Java
Objective-C Is Not JavaObjective-C Is Not Java
Objective-C Is Not Java
 

Andere mochten auch

Иван Бордюг - Инструмент автоматизации регрессионного тестирования на основе ...
Иван Бордюг - Инструмент автоматизации регрессионного тестирования на основе ...Иван Бордюг - Инструмент автоматизации регрессионного тестирования на основе ...
Иван Бордюг - Инструмент автоматизации регрессионного тестирования на основе ...automated-testing.info
 
Александр Кабалюк – SilkTest
Александр Кабалюк – SilkTestАлександр Кабалюк – SilkTest
Александр Кабалюк – SilkTestautomated-testing.info
 
Курс молодого бойца-автоматизатора – как стать ветераном и остаться в живых
Курс молодого бойца-автоматизатора – как стать ветераном и остаться в живыхКурс молодого бойца-автоматизатора – как стать ветераном и остаться в живых
Курс молодого бойца-автоматизатора – как стать ветераном и остаться в живыхautomated-testing.info
 
Швейцарский нож для Android
Швейцарский нож для AndroidШвейцарский нож для Android
Швейцарский нож для Androidautomated-testing.info
 
Тестирование производительности Ajax приложений с помощью JMeter
Тестирование производительности Ajax приложений с помощью JMeterТестирование производительности Ajax приложений с помощью JMeter
Тестирование производительности Ajax приложений с помощью JMeterautomated-testing.info
 
Философия и построение тестового фреймворка на основе BDD в PHP проектах
Философия и построение тестового фреймворка на основе BDD в PHP проектахФилософия и построение тестового фреймворка на основе BDD в PHP проектах
Философия и построение тестового фреймворка на основе BDD в PHP проектахautomated-testing.info
 

Andere mochten auch (7)

Иван Бордюг - Инструмент автоматизации регрессионного тестирования на основе ...
Иван Бордюг - Инструмент автоматизации регрессионного тестирования на основе ...Иван Бордюг - Инструмент автоматизации регрессионного тестирования на основе ...
Иван Бордюг - Инструмент автоматизации регрессионного тестирования на основе ...
 
Александр Кабалюк – SilkTest
Александр Кабалюк – SilkTestАлександр Кабалюк – SilkTest
Александр Кабалюк – SilkTest
 
Курс молодого бойца-автоматизатора – как стать ветераном и остаться в живых
Курс молодого бойца-автоматизатора – как стать ветераном и остаться в живыхКурс молодого бойца-автоматизатора – как стать ветераном и остаться в живых
Курс молодого бойца-автоматизатора – как стать ветераном и остаться в живых
 
Швейцарский нож для Android
Швейцарский нож для AndroidШвейцарский нож для Android
Швейцарский нож для Android
 
Тестирование производительности Ajax приложений с помощью JMeter
Тестирование производительности Ajax приложений с помощью JMeterТестирование производительности Ajax приложений с помощью JMeter
Тестирование производительности Ajax приложений с помощью JMeter
 
Философия и построение тестового фреймворка на основе BDD в PHP проектах
Философия и построение тестового фреймворка на основе BDD в PHP проектахФилософия и построение тестового фреймворка на основе BDD в PHP проектах
Философия и построение тестового фреймворка на основе BDD в PHP проектах
 
За пределами PageObject
За пределами PageObjectЗа пределами PageObject
За пределами PageObject
 

Ähnlich wie Gwt and rpc use 2007 1

Servletarchitecture,lifecycle,get,post
Servletarchitecture,lifecycle,get,postServletarchitecture,lifecycle,get,post
Servletarchitecture,lifecycle,get,postvamsitricks
 
Servletarchitecture,lifecycle,get,post
Servletarchitecture,lifecycle,get,postServletarchitecture,lifecycle,get,post
Servletarchitecture,lifecycle,get,postvamsitricks
 
Servletarchitecture,lifecycle,get,post
Servletarchitecture,lifecycle,get,postServletarchitecture,lifecycle,get,post
Servletarchitecture,lifecycle,get,postvamsi krishna
 
How to Contribute to Apache Usergrid
How to Contribute to Apache UsergridHow to Contribute to Apache Usergrid
How to Contribute to Apache UsergridDavid M. Johnson
 
Using React with Grails 3
Using React with Grails 3Using React with Grails 3
Using React with Grails 3Zachary Klein
 
WTF is Twisted?
WTF is Twisted?WTF is Twisted?
WTF is Twisted?hawkowl
 
DjangoCon 2010 Scaling Disqus
DjangoCon 2010 Scaling DisqusDjangoCon 2010 Scaling Disqus
DjangoCon 2010 Scaling Disquszeeg
 
Spring Day | Spring and Scala | Eberhard Wolff
Spring Day | Spring and Scala | Eberhard WolffSpring Day | Spring and Scala | Eberhard Wolff
Spring Day | Spring and Scala | Eberhard WolffJAX London
 
BITM3730Week12.pptx
BITM3730Week12.pptxBITM3730Week12.pptx
BITM3730Week12.pptxMattMarino13
 
Introduction tomcat7 servlet3
Introduction tomcat7 servlet3Introduction tomcat7 servlet3
Introduction tomcat7 servlet3JavaEE Trainers
 
Groovy & Grails eXchange 2012 vert.x presentation
Groovy & Grails eXchange 2012 vert.x presentationGroovy & Grails eXchange 2012 vert.x presentation
Groovy & Grails eXchange 2012 vert.x presentationStuart (Pid) Williams
 
Ratpack Web Framework
Ratpack Web FrameworkRatpack Web Framework
Ratpack Web FrameworkDaniel Woods
 
Synchronous Commands over Apache Kafka (Neil Buesing, Object Partners, Inc) K...
Synchronous Commands over Apache Kafka (Neil Buesing, Object Partners, Inc) K...Synchronous Commands over Apache Kafka (Neil Buesing, Object Partners, Inc) K...
Synchronous Commands over Apache Kafka (Neil Buesing, Object Partners, Inc) K...confluent
 
[Kotlin Serverless 工作坊] 單元 4 - 實作 RSS Aggregator
[Kotlin Serverless 工作坊] 單元 4 - 實作 RSS Aggregator[Kotlin Serverless 工作坊] 單元 4 - 實作 RSS Aggregator
[Kotlin Serverless 工作坊] 單元 4 - 實作 RSS AggregatorShengyou Fan
 
4th Lecture: JSP and such
4th Lecture:  JSP and such4th Lecture:  JSP and such
4th Lecture: JSP and suchManolis Vavalis
 

Ähnlich wie Gwt and rpc use 2007 1 (20)

Liferay (DXP) 7 Tech Meetup for Developers
Liferay (DXP) 7 Tech Meetup for DevelopersLiferay (DXP) 7 Tech Meetup for Developers
Liferay (DXP) 7 Tech Meetup for Developers
 
Servletarchitecture,lifecycle,get,post
Servletarchitecture,lifecycle,get,postServletarchitecture,lifecycle,get,post
Servletarchitecture,lifecycle,get,post
 
Servletarchitecture,lifecycle,get,post
Servletarchitecture,lifecycle,get,postServletarchitecture,lifecycle,get,post
Servletarchitecture,lifecycle,get,post
 
Servletarchitecture,lifecycle,get,post
Servletarchitecture,lifecycle,get,postServletarchitecture,lifecycle,get,post
Servletarchitecture,lifecycle,get,post
 
How to Contribute to Apache Usergrid
How to Contribute to Apache UsergridHow to Contribute to Apache Usergrid
How to Contribute to Apache Usergrid
 
Servlets
ServletsServlets
Servlets
 
Using React with Grails 3
Using React with Grails 3Using React with Grails 3
Using React with Grails 3
 
WTF is Twisted?
WTF is Twisted?WTF is Twisted?
WTF is Twisted?
 
Life outside WO
Life outside WOLife outside WO
Life outside WO
 
DjangoCon 2010 Scaling Disqus
DjangoCon 2010 Scaling DisqusDjangoCon 2010 Scaling Disqus
DjangoCon 2010 Scaling Disqus
 
JS Essence
JS EssenceJS Essence
JS Essence
 
Spring Day | Spring and Scala | Eberhard Wolff
Spring Day | Spring and Scala | Eberhard WolffSpring Day | Spring and Scala | Eberhard Wolff
Spring Day | Spring and Scala | Eberhard Wolff
 
BITM3730Week12.pptx
BITM3730Week12.pptxBITM3730Week12.pptx
BITM3730Week12.pptx
 
Scala and Spring
Scala and SpringScala and Spring
Scala and Spring
 
Introduction tomcat7 servlet3
Introduction tomcat7 servlet3Introduction tomcat7 servlet3
Introduction tomcat7 servlet3
 
Groovy & Grails eXchange 2012 vert.x presentation
Groovy & Grails eXchange 2012 vert.x presentationGroovy & Grails eXchange 2012 vert.x presentation
Groovy & Grails eXchange 2012 vert.x presentation
 
Ratpack Web Framework
Ratpack Web FrameworkRatpack Web Framework
Ratpack Web Framework
 
Synchronous Commands over Apache Kafka (Neil Buesing, Object Partners, Inc) K...
Synchronous Commands over Apache Kafka (Neil Buesing, Object Partners, Inc) K...Synchronous Commands over Apache Kafka (Neil Buesing, Object Partners, Inc) K...
Synchronous Commands over Apache Kafka (Neil Buesing, Object Partners, Inc) K...
 
[Kotlin Serverless 工作坊] 單元 4 - 實作 RSS Aggregator
[Kotlin Serverless 工作坊] 單元 4 - 實作 RSS Aggregator[Kotlin Serverless 工作坊] 單元 4 - 實作 RSS Aggregator
[Kotlin Serverless 工作坊] 單元 4 - 實作 RSS Aggregator
 
4th Lecture: JSP and such
4th Lecture:  JSP and such4th Lecture:  JSP and such
4th Lecture: JSP and such
 

Gwt and rpc use 2007 1

  • 1. Remote Procedure Calls in GWT • How they are implemented • How to use them effectively • Best practices and design patterns • Future directions and possibilities • Discussion
  • 2. Introduction • Your presenter: Rob Jellinghaus • Contributor to GWT – Refactored server-side RPC implementation in GWT 1.4 • Architect at SF startup • http://robjsoftware.org
  • 3. What is GWT RPC? • Simple way for your GWT clients to call your Java server code • Looks a lot like regular Java procedure calls; can pass complex objects easily • Will skim over the basics – GWT documentation is good • Won’t address security – Too large a topic – Covered elsewhere at this conference
  • 4. All Abstractions Leak • Abstractions are great, but hidden details have a way of surfacing – Spolsky’s Law: All non-trivial abstractions, to some degree, are leaky • GWT RPC is no exception – At least GWT is upfront about such things! • Forewarned is forearmed
  • 5. Asynchrony • The biggest difference: GWT RPC returns immediately • Normal procedure call: Object result = myService.doWork(); doSomethingWith(result); • GWT RPC: myService.doWork(myCallback); … wait a while … public void onSuccess(Object result) { doSomethingWith(result); }
  • 6. Asynchrony Is Your Friend • The very definition of AJAX – Old news to AJAX hackers, but unusual in the Java world • If your app isn’t waiting for the server, then your users aren’t either • Don’t work around it, embrace it! – Workarounds are horrible and user-hostile
  • 7. GWT RPC Lives in the Compiler • RPC is implemented as a compiler extension – See Ray Cromwell’s talk on “Generators” • Enables very highly optimized RPC code – Compiler looks at your interfaces and object types – Emits tightly tuned encoding / decoding Javascript • If GWT can’t compile it, you can’t send it – Unlike RMI / Java serialization, where you can send objects for which you don’t have source
  • 8. Very brief example • This class: public class Entry implements com.google.gwt.user.client.rpc.IsSerializable{ private dto.domain.Blog blog; private java.lang.String body; … } • Gets this generated deserializer (details elided): function dto_domain_Entry_1FieldSerializer_deserialize(streamReader, instance) { dto_domain_Entry_1FieldSerializer_setBlog (instance, com_google_gwt_lang_Cast_dynamicCast__Ljava_lang_Object_2I… (streamReader.readObject__(), 17)); dto_domain_Entry_1FieldSerializer_setBody… (instance, streamReader.readString__()); … }
  • 9. GWT serialization vs. others • GWT serialization: – Fully statically compiled, metadata-guided – No class hooks • Java serialization: – Reflection-based – readObject, writeObject hooks • Java persistence serialization: – Reflection-based, metadata-guided – Bytecode proxies injected
  • 10. Server integration: basics • Simplest technique: RemoteServiceServlet public interface MyServiceInterface { public Object doWork(); } public class MyServiceServlet extends RemoteServiceServlet implements MyServiceInterface { public Object doWork() { … } } • Works nicely out of the box • Requires one servlet class per interface you expose – Doesn’t work well to expose pre-existing components – Fixed with my refactorings in GWT 1.4
  • 11. Server integration: Spring • Several Spring integrations exist – George Georgovassilis & Rob Hanson’s GWT-SL server library – Chris Lee’s one-page integration • Couples with Spring’s “handler” mechanism for web requests • Can expose pure POJOs (GWT-SL), or can annotate service classes (Chris Lee)
  • 12. Server integration: Seam • Seam 2.0 has built-in GWT integration – GWTService web resource • Set your endpointURL to be “seam/resource/gwt” • RPC requests route to a Seam component by interface name: @Name("org.jboss.seam.example.remoting.gwt.client.MyService") public class ServiceImpl implements MyService { @WebRemote public String askIt(String question) { return "42. Its the real question that you seek now."; }… }
  • 13. Server integration: Seam/JSF + GWT • Wrap your GWT module in a JSF component • Drop it into a JSF page • Route its RPC to any Seam component: <!-- routes to the BlogService on the gwtBlog component --> <bloglist:component id="main2"> <gwt:gwtListener serviceBean="#{gwtBlog}"/> </bloglist:component> • Only one problem… broken with Seam 2 at the moment – Anyone want to help? 
  • 14. Using GWT RPC Effectively • We’ve covered the basics • Now for best practices – Responsiveness – Asynchrony – Serialization interactions – API design and service orientation
  • 15. Responsiveness: Balanced RPC • Messages Want To Be Small – Small messages are quick to process – Low encoding & decoding overhead • But Messages Want To Be Big – Networks are slow – Many messages = much exposure to network latency • Balance your RPC – Only pull data visible to the user; paginate on server – Don’t build too many UI elements either
  • 16. Asynchrony: No More Straight Lines • Synchronous code might look like this – (can’t use Java 5 yet in GWT 1.4): Blog blog = blogService.getBlog(); List entries = blogService.getEntries(); for (int i = 0; i < entries.size(); i++) { BlogEntry entry = (BlogEntry)entries.get(i); TreeItem item = new TreeItem(entry.getTitle()); tree.addItem(item); String body = blogService.formatText(entry.getId()); entry.setBody(body); }
  • 17. Fun with Inner Classes • Anonymous inner classes split up the code inline: Blog blog = null; List entries = null; blogService.getBlog(new AsyncCallback() { public void onSuccess(Object result) { blog = (Blog)result; blogService.getEntries(new AsyncCallback() { public void onSuccess(Object result) { entries = (List)result; } }); } }); • But gets very nested and tough to read
  • 18. Callback Objects • Break out the callbacks into helpers: Blog blog = null; blogService.getBlog(new AsyncCallback() { public void onSuccess(Object result) { blog = (Blog)result; blogService.getBlogEntries(makeEntriesCallback()); } }); public AsyncCallback makeEntriesCallback() { return new AsyncCallback() { public void onSuccess(Object result) { List entries = (List)result; … • Makes the sequence more descriptive
  • 19. Stateful Callback Objects • Multiple RPCs in flight at once: List entries = (List)result; for (int i = 0; i < entries.size(); i++) { BlogEntry entry = (BlogEntry)entries.get(I); TreeItem item = new TreeItem(entry.getTitle()); tree.addItem(item); blogService.fetchText(entry.getId(), makeEntryCallback(item)); … } public AsyncCallback makeEntryCallback(TreeItem item) { return new AsyncCallback() { public void onSuccess(Object text) { item.setText((String)text); } } } • Each callback knows what to do with its response • Can extend this pattern to all kinds of sequences
  • 20. Transactions • Updates can sometimes require multiple server calls • Keep state in your client until commit time – The less server state the better – But can’t send too much state at once when committing • Can use “chained command” pattern in your service – Send a whole sequence of API calls – Rather like offline sync in Google Gears
  • 21. When Abstractions Attack • GWT makes it easy to call your Java backend • Many Java backends use Hibernate, JPA, EJB3… • GWT abstraction: serialize object graph to Javascript – Needs to see all the source • JPA abstraction: load partial object graph lazily – Create secret hidden $$CGLIB classes, private collections • GWT + JPA: KABOOM! – GWT can’t serialize a lazy persistence proxy or Hibernate PersistentMap – Spolsky’s Revenge
  • 22. DTOs: Back to the Future • Data transfer objects: intermediate object layer • Copy your persistent objects into separate DTO structure – GWT only sees the DTO objects – Explicit control over what gets sent – Can limit features used in DTO objects (avoid generics, annotations) – Risk of lots of boilerplate code
  • 23. Generated DTOs: Less Boilerplate • Automatically generate DTOs at build time – Codehaus JAM project: Java source walker – Compile DTOs into a standalone GWT module for (JField field : jClass.getFields()) { String name = field.getSimpleName(); String type = field.getType().getQualifiedName(); if (type.startsWith("java.")) { // skip over classes that aren't emulated by GWT… • Reflection can populate DTOs – Kind of an intermediate “serializer” from persistent objects to DTO objects – Hibernate4gwt project allows this (with merging, too)
  • 24. Rocket Science: Customizing RPC • GWT ServerSerializationStreamWriter – Custom GWT class that traverses objects – Can make subclass with special handling of persistent classes • Null out lazy collections, load lazy proxy objects – Risks breaking if GWT changes RPC implementation public void serializeValue(Object value, Class type) throws SerializationException { … else if (type == java.util.Set.class) { Set hashSet = new HashSet(); if (value instanceof PersistentSet) { PersistentSet persSet = (PersistentSet) value; if (persSet.wasInitialized()){ hashSet.addAll(persSet); }…
  • 25. The Trouble with Merging • Once you send your objects back up, you have to merge them • Seam / JPA stateful dogma says this is a weakness of GWT and other rich clients – Stateful apps keep persistence context around while user is interacting; dirty objects tracked for free • But persistence contexts die badly if commit fails – Only solution is to abandon all your modified state! • GWT APIs need to clearly identify what’s changed – Simplifies the merge problem – Arguably easier to recover from conflicts – Scales better, too
  • 26. DAOs are not APIs • Tempting to just expose your persistence layer • Don’t do this! – Persistence operations are not a good API • APIs should be intentional – Should be tuned to application use cases – Objects exposed should be client-meaningful • May or may not be your domain objects – Think services rather than data accesses • Service-oriented backends are more scalable
  • 27. Serializable != IsSerializable • Java serialization is not GWT serialization – Java serialization expects a very particular contract – Hardcoded to binary / byte level; lots of existing readObject, writeObject methods – Those methods not necessarily compilable by GWT – Java serialization not efficient in Javascript • In GWT, “java.lang.Serializable” just means “OK to send by GWT RPC” – Does NOT mean “Will use existing readObject / writeObject implementations”
  • 28. The Home Stretch • Cool tricks • GWT 1.5 • Future possibilities – Ranging from “sensible” to “wildly ambitious” • Other interesting systems • Conclusion
  • 29. Preserialized objects • You’ve got a bunch of initialization data – You want to download it efficiently – Maximum-speed startup, one round-trip • iPhone apps, anyone? • Serialize the data on the server, then save the bytes • Blast them out from cache, then deserialize them explicitly – In GWT 1.5: get SerializationStreamReader from client-side RPC proxy
  • 30. GWT 1.5: Java 5 for the win! • Plan: full support for enumerated types, generic collections • No more @gwt.typeargs – Typed collections get optimized RPC automatically • Annotations are OK – Not yet clear what GWT will use them for – Compiler should be able to ignore annotations w/o available source • So @Entity, @Component, etc. won’t choke GWT
  • 31. Possibility: RPC metadata • Support for request/response headers in RPC messages • Use cases: – Servers that use HTTP headers for authorization – Support for Spring webflow / Seam conversations • API totally undefined: – Stateful instantiation of Service? Callback functions? – Related to RPC cancellation / request control? – Discuss on GWT Contributors forum
  • 32. Possibility: JSON-style encoding • GWT compiler generates current deserializers – Pretty much the best Javascript functions can do – But still not as good as JSON • What if RPC payloads were deserialized by the browser, as with JSON? – Could be blazingly fast deserialization – AND less client-side code – But lots of issues to work out (see GWTC thread) • Not high priority for GWT 1.5, but later…?
  • 33. Possibility: Declarative data binding • Right now RPC is strictly imperative • Some modern frameworks (Seam) support declarative data binding – Refer to server data objects by name – UI components bind to specific sub-objects • Declarative UI support underway for GWT; perhaps data binding a natural extension? – Could also integrate some support for offline synchronization? – Pagination done “under the hood”?
  • 34. Possibility: Generalized mappings • Persistence mapping is very similar to client-server DTO mapping – In both cases, you have data spaces containing objects that must be transferred and correlated • Why not a unified answer? – What if persistence mappings could be extended to define data transfer behaviors to the client? – And then further, to define client-side update sets and synchronization behaviors? – Attack the DTO problem at the framework level! • See LINQ 2.0 work from Microsoft Research
  • 35. Other interesting systems • Good old RMI (Sun) – Classloader problems much worse than widely known • Caja (Ben Laurie, Mark Miller, Google) – Capability-secure Javascript – Mobile code, with non-broken sandboxes – Influenced by E (asynchronous capability messaging) – (GWT -> Caja scriptlets???) • LINQ 2.0 (Erik Meijer, Microsoft) – Automatically restructure sequential client app to be asynchronous multi-tier app – Integrate SQL queries, XML mappings, RPC – MSIL -> Javascript (like GWT for .NET bytecode)
  • 36. Thanks! • Hope this was helpful  • Thanks to GWT team & Pearson • http://robjsoftware.org/gwt2007 – links & further references • Go forth and create great apps! – And then post about them on the GWT groups! – And then start contributing to GWT!!!

Hinweis der Redaktion

  1. Welcome to this talk about remote procedure calls in GWT. I’ll be starting with a look at GWT’s RPC implementation, which has some tradeoffs that directly affect your code. I’ll also cover how best to use RPC in GWT, and how to structure your applications to leverage it most effectively, in terms of best practices and design patterns you may find useful. Finally, I’ll talk about some possible RPC extensions and future features that are under consideration for GWT 1.5, and finally leave some time for discussion.
  2. A quick introduction: My name is Rob Jellinghaus. I’m up here because I am a GWT contributor; I started working with GWT late last year, and wanted to integrate it with Seam. I rapidly discovered that the GWT server-side RPC implementation wasn’t well structured to expose pre-existing server components. I proposed a refactoring for it and implemented it, with lots of excellent review from Miguel Mendez on the GWT team. So I’ve got some familiarity with RPC’s internals. I’m also an architect at a San Francisco startup where we’re doing a good amount of rich client work, so I’m acquainted with the problem space. I’m honored to be included in this conference, thanks guys!
  3. So what is GWT RPC? It’s a built-in mechanism in GWT for your clients to call your Java server code. You expose an interface to the server, you call it from the client, you can pass complex Java objects back and forth. Like everything in GWT, it’s continually getting tweaked for higher performance. Overall, it’s a powerful abstraction. Since many of you have worked with it already, I won’t be giving detailed examples of how to set up GWT RPC; the GWT documentation covers the basics effectively.
  4. GWT RPC does its best to make it convenient to call your server code, by abstracting away many of the details. But Joel Spolsky has a well-known law that all abstractions leak. GWT RPC is no exception. This isn’t a slam on GWT; we’ll see plenty of other non-GWT leaky abstraction examples later in this talk. One of GWT’s strengths is that it doesn’t try to push its abstractions beyond their limits; GWT is very upfront about what realities it can and can’t hide from you. Being aware of these issues will let you manage them effectively.
  5. Still moving quickly through the basics: GWT RPC is asynchronous, which means you don’t get results right away. Results come back later, and are passed to a callback handler you define. Results from the server look more or less just like user interface events from your user. This completely changes how you write your code.
  6. This asynchronous RPC is a very, very good thing. It’s so good that it’s the very definition of AJAX. If your app isn’t waiting for the server, then your users aren’t either. Later in the talk I’ll detail some useful patterns for leveraging asynchrony.
  7. The other key thing to know about GWT RPC is that, unlike many other RPC systems, it is built into the GWT compiler. It uses the GWT compiler’s “generators” technology (see Ray Cromwell’s talk) to emit customized serialization code for each of the types that you send over RPC. This code knows exactly what fields and references your RPC types contain, and is tuned to run as fast as possible in the browser’s scripting engine.
  8. Just to make this concrete, here’s an example from a GWT demo application I’ll be showing. It’s Yet Another Blogging App, and it has a class for blog entries that looks like this. The GWT compiler emits RPC deserialization code that looks like this. It walks through each field of a BlogEntry pulling its data from the stream. This code is straight-line Javascript that has no conditionals or dispatching, and that therefore runs very fast.
  9. Just to make this concrete, here’s an example from a GWT demo application I’ll be showing. It’s Yet Another Blogging App, and it has a class for blog entries that looks like this. The GWT compiler emits RPC deserialization code that looks like this. It walks through each field of a BlogEntry pulling its data from the stream. This code is straight-line Javascript that has no conditionals or dispatching, and that therefore runs very fast.
  10. At some point you need to couple GWT RPC to your server code. The simplest technique for doing this is to subclass RemoteServiceServlet.
  11. Spolsky: http://www.joelonsoftware.com/articles/LeakyAbstractions.html Chris Lee / Spring annotation exposure: http://blog.digitalascent.com/2007/11/gwt-rpc-with-spring-2x_12.html GWT-SL / Spring POJO exposure: http://gwt-widget.sourceforge.net/?q=node/39 Seam &amp; GWT: http://docs.jboss.com/seam/2.0.0.GA/reference/en/html/gwt.html Seam &amp; GWT &amp; JSF: http://unrealities.com/seamgwt Custom StreamWriter: http://groups.google.com/group/Google-Web-Toolkit-Contributors/browse_thread/thread/669e3d31b60bb1be Cancelling RPC: http://groups.google.com/group/Google-Web-Toolkit/browse_thread/thread/5d94093b34b65a71 Client-side explicit deserialization: http://groups.google.com/group/Google-Web-Toolkit/browse_thread/thread/a192fb396cc2df0b# Directly-eval&apos;able server responses: http://groups.google.com/group/Google-Web-Toolkit-Contributors/browse_thread/thread/761f743d2d7471ee RMI problems: http://research.sun.com/techrep/2007/smli_tr-2007-162.pdf http://research.sun.com/techrep/2006/smli_tr-2006-149.pdf Caja: http://www.links.org/?p=271 E: http://www.erights.org/ LINQ 2.0: http://research.microsoft.com/~emeijer/ http://www.itwriting.com/blog/?p=158 http://research.microsoft.com/~emeijer/Papers/DemocratizingTheCloudOOPSLA2007.pdf