[gwt-contrib] Re: Proposal: Lightweight GWT-RPC implementation for OpenSocial and Gadgets
Success - I got this to work! Now running GWT-RPC through OpenSocial's gadget.io.makeRequest! Only two lines of code had to be changed in GWT to make the RPC system pluggable. Here is a patch against trunk. Could someone review and approve? The other half consists of custom RequestBuilder and RemoteServiceProxy subclasses. I will continue testing and polishing those and will share them later. Alex On Thu, Jan 22, 2009 at 5:17 PM, Alex Epshteyn alexander.epsht...@gmail.com wrote: Yes, the option to extend RPC and gadgets are two separate ideas. Code generation is one of the core features of GWT, and nothing new is being added to the Java programming language, as the syntax is part of the Java language. The reason GWT works is because HTML and Javascript evolve very slowly. A tight Java binding to a fast-changing Javascript API like Gadgets or OpenSocial is asking for trouble because you won't be able to keep updating the Java code fast enough. Alex On Thu, Jan 22, 2009 at 5:08 PM, Ray Cromwell cromwell...@gmail.com wrote: I think there are two issues. One is providing hooks to allow the RPC call to be dispatched via a customized mechanism. This can range from makeRequest() with POST, to cross-domain JSONP, to ProtocolBuffer RpcChannel. I've brought up this issue time and time again, as I've been an early adopter of writing complex GWT apps inside of Gadgets. I think it would be useful to revisit the RPC design in the future to make it easier to plugin custom methods, not just for Gadgets/makeRequest, but also for stuff like JSON wireformats and ProtocolBuffers. The issue of the GadgetLinker manifest generation is separate. I happen to like the concept, but dislike the current implementation. I like the auto-generation of the manifest, the type safety of dependency-injected interfaces. However, the current system is too inflexible. It doesn't support multiple Gadget views, it doesn't support optional feature requirements. That is, if you require an optional feature in the manifest, the feature interfaces will still get injected even if they weren't loaded. Simply put, I don't find using annotations, generators, and linkers scary. Code generation is one of the core features of GWT, and nothing new is being added to the Java programming language, as the syntax is part of the Java language. On a wider now, realistically, GALGWT needs official bindings for non-legacy Gadgets and OpenSocial. I've implemented JSOs for most of those privately as Gadget features, but it would be nice to have an officially sanctioned Google binding. -Ray On Thu, Jan 22, 2009 at 1:13 PM, Alex Epshteyn alexander.epsht...@gmail.com wrote: Background: OpenSocial containers provide the method gadget.io.makeRequest because gadget scripts aren't able to use XHR due to the SOP. Furthermore, I believe, OpenSocial containers don't expose the _IG_GetCachedUrl(url) method that the gwt-gadgets library uses. Now, regarding the gwt-gadgets library, to be blunt, it simply scares me. I don't want all the gadget stuff brought into the Java programming language with interfaces and annotations. Having the bootsrap and gadget.xml generated with a custom linker is scary and unnecessary. This is just asking for trouble with a leaky abstraction. The RPC Problem: It's very easy to write a Google Gadget with GWT without using the gwt- gadgets library. Simply write your gadget.xml by hand (there's not much to it, really), write your GWT app the traditional way, compile it with the XS linker, and write a script tag referencing your .nocache.js script in your gadget.xml. You can call all the OpenSocial and Gadgets API methods from your GWT code using JSNI (JSO overlay types could simplify things a bit). The only problem is RPC. Currently using GWT-RPC in an OpenSocial container seems impossible. You'd have to write a JSON service. The Proposed Solution: This is just a rough sketch, but I think this can be accomplished as follows: 1) Subclass RequestBuilder to use gadgets.io.makeRequest 2) Subclass RemoteServiceProxy and override the protected method doPrepareRequestBuilder to return an instance of your custom RequestBuilder subclass. 3) Modify ProxyCreator to allow setting a custom superclass for the generated proxy class. I.e. allow chaning this line: composerFactory.setSuperclass(RemoteServiceProxy.class.getSimpleName ()); (Perhaps with a system property defining the class name for starters). --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~--- rpc_hooks.patch Description: Binary data
[gwt-contrib] Re: Proposal: Lightweight GWT-RPC implementation for OpenSocial and Gadgets
I don't quite understand this point. Any JSO you create is going to be tightly bound to the underlying Gadget/OpenSocial APIs, so what's the difference between a JSO binding which is isn't dependency injected, vs one that is, with regard to keeping up with API changes? Are you arguing against using GWT JSOs to call OpenSocial APIs, or just trying to argue against GadgetLinker injecting the reference for you? There seems to be little difference between writing a native method to get the initial reference to an Overlay type, or having it injected for you, with respect to fast evolving specs. All the GadgetLinker does is construct an instance of a type that you tell it and it wouldn't be hard to modify it so inject JSO Overlays. To me, the only issue that controls whether or not you can keep in sink is whether you have access to the mapping source. And even then, that isn't the biggest issue with OpenSocial programming. The actual specs 0.6/0.7/0.8/0.81/0.9 etc aren't changing that fast, in fact, I wish they'd change faster. The real problem with OpenSocial programming, which hits Java programmers just as hard as JavaScript programmers, is poor container implementations, and the fact that the spec is designed in a way that virtually everything is optional to implement. Quick, which containers support notifications, requestShareApp, or activities? Which support OAuth? IMHO, a generator which could parse idiomatic JsDoc/Javascript ala Bob's JS Interop, and with some extra annotations, automatically generate JSO bindings, would actually be superior to writing JSOs by hand to keep them in sink, or even programming Javascript by hand. Why? Because everytime the spec is updated, if there was a mismatch, you could detect errors. However, none of that really matters much, since unless you decide to target a single OS container, probably 90% of the work is workarounds of unsupported or broken features. -Ray On Thu, Jan 22, 2009 at 2:17 PM, Alex Epshteyn alexander.epsht...@gmail.com wrote: The reason GWT works is because HTML and Javascript evolve very slowly. A tight Java binding to a fast-changing Javascript API like Gadgets or OpenSocial is asking for trouble because you won't be able to keep updating the Java code fast enough. Alex On Thu, Jan 22, 2009 at 5:08 PM, Ray Cromwell cromwell...@gmail.com wrote: I think there are two issues. One is providing hooks to allow the RPC call to be dispatched via a customized mechanism. This can range from makeRequest() with POST, to cross-domain JSONP, to ProtocolBuffer RpcChannel. I've brought up this issue time and time again, as I've been an early adopter of writing complex GWT apps inside of Gadgets. I think it would be useful to revisit the RPC design in the future to make it easier to plugin custom methods, not just for Gadgets/makeRequest, but also for stuff like JSON wireformats and ProtocolBuffers. The issue of the GadgetLinker manifest generation is separate. I happen to like the concept, but dislike the current implementation. I like the auto-generation of the manifest, the type safety of dependency-injected interfaces. However, the current system is too inflexible. It doesn't support multiple Gadget views, it doesn't support optional feature requirements. That is, if you require an optional feature in the manifest, the feature interfaces will still get injected even if they weren't loaded. Simply put, I don't find using annotations, generators, and linkers scary. Code generation is one of the core features of GWT, and nothing new is being added to the Java programming language, as the syntax is part of the Java language. On a wider now, realistically, GALGWT needs official bindings for non-legacy Gadgets and OpenSocial. I've implemented JSOs for most of those privately as Gadget features, but it would be nice to have an officially sanctioned Google binding. -Ray On Thu, Jan 22, 2009 at 1:13 PM, Alex Epshteyn alexander.epsht...@gmail.com wrote: Background: OpenSocial containers provide the method gadget.io.makeRequest because gadget scripts aren't able to use XHR due to the SOP. Furthermore, I believe, OpenSocial containers don't expose the _IG_GetCachedUrl(url) method that the gwt-gadgets library uses. Now, regarding the gwt-gadgets library, to be blunt, it simply scares me. I don't want all the gadget stuff brought into the Java programming language with interfaces and annotations. Having the bootsrap and gadget.xml generated with a custom linker is scary and unnecessary. This is just asking for trouble with a leaky abstraction. The RPC Problem: It's very easy to write a Google Gadget with GWT without using the gwt- gadgets library. Simply write your gadget.xml by hand (there's not much to it, really), write your GWT app the traditional way, compile it with the XS linker, and write a script tag referencing your .nocache.js
[gwt-contrib] Re: Proposal: Lightweight GWT-RPC implementation for OpenSocial and Gadgets
Agreed. I used a similar patch in my own implementation a few weeks ago, although yours is simpler. One thing I'd suggest though is to get the superclass setting either from a module property, or from something in the type system, or runtime, rather than the environment. e.g. define-property name=gwt.rpc.proxySuperClass values=com.foo.Bar/ set-property name=gwt.rpc.proxySuperClass value=com.foo.Bar/ which is kind of an abuse of the property system, but allows compiling different permutations of the app for different environments (e.g. gadget vs non-gadget versions) There was some discussion awhile ago of adding new kinds of properties which specify configuration. @GwtProxySuperClass(com.foo.Bar) public interface MyService extends RemoteService { ... } which allows specifying the transport, but does not allow more than 1 transport at a time for the same type (without creating subinterfaces) However you could easily do something like: @GwtProxySuperClass(GadgetProxy) public MyGadgetService extends MyService {...} @GwtProxySuperClass(ProtoBufProxy) public MyProtoBufService extends MyService {...} Using environment properties doesn't seem GWT-like to me, since it kind of buries flags deep inside implementation code that most users won't see and moves it to build scripts. This is one of the things I always disliked about Sun's use of -D parameters all over the JRE code, since finding out a complete list of all these magic variables and exactly what they do is often difficult. GWT's idiom is usually to embed build specific switches via deferred binding properties. -Ray On Thu, Jan 22, 2009 at 8:27 PM, Alex Epshteyn alexander.epsht...@gmail.com wrote: Anyhow, let's get this thread back on track to being a discussion about allowing RPC over non-XHR proxy channels like gadgets.io.makeRequst. You can use my RPC code with or without the gwt-gadgets library. I'd like to get this patch into trunk if no one objects. Alex On Thu, Jan 22, 2009 at 8:38 PM, Ray Cromwell cromwell...@gmail.com wrote: I don't quite understand this point. Any JSO you create is going to be tightly bound to the underlying Gadget/OpenSocial APIs, so what's the difference between a JSO binding which is isn't dependency injected, vs one that is, with regard to keeping up with API changes? Are you arguing against using GWT JSOs to call OpenSocial APIs, or just trying to argue against GadgetLinker injecting the reference for you? There seems to be little difference between writing a native method to get the initial reference to an Overlay type, or having it injected for you, with respect to fast evolving specs. All the GadgetLinker does is construct an instance of a type that you tell it and it wouldn't be hard to modify it so inject JSO Overlays. To me, the only issue that controls whether or not you can keep in sink is whether you have access to the mapping source. And even then, that isn't the biggest issue with OpenSocial programming. The actual specs 0.6/0.7/0.8/0.81/0.9 etc aren't changing that fast, in fact, I wish they'd change faster. The real problem with OpenSocial programming, which hits Java programmers just as hard as JavaScript programmers, is poor container implementations, and the fact that the spec is designed in a way that virtually everything is optional to implement. Quick, which containers support notifications, requestShareApp, or activities? Which support OAuth? IMHO, a generator which could parse idiomatic JsDoc/Javascript ala Bob's JS Interop, and with some extra annotations, automatically generate JSO bindings, would actually be superior to writing JSOs by hand to keep them in sink, or even programming Javascript by hand. Why? Because everytime the spec is updated, if there was a mismatch, you could detect errors. However, none of that really matters much, since unless you decide to target a single OS container, probably 90% of the work is workarounds of unsupported or broken features. -Ray On Thu, Jan 22, 2009 at 2:17 PM, Alex Epshteyn alexander.epsht...@gmail.com wrote: The reason GWT works is because HTML and Javascript evolve very slowly. A tight Java binding to a fast-changing Javascript API like Gadgets or OpenSocial is asking for trouble because you won't be able to keep updating the Java code fast enough. Alex On Thu, Jan 22, 2009 at 5:08 PM, Ray Cromwell cromwell...@gmail.com wrote: I think there are two issues. One is providing hooks to allow the RPC call to be dispatched via a customized mechanism. This can range from makeRequest() with POST, to cross-domain JSONP, to ProtocolBuffer RpcChannel. I've brought up this issue time and time again, as I've been an early adopter of writing complex GWT apps inside of Gadgets. I think it would be useful to revisit the RPC design in the future to make it easier to plugin custom methods, not just for
[gwt-contrib] Re: Proposal: Lightweight GWT-RPC implementation for OpenSocial and Gadgets
I agree that an environment variable isn't ideal, but could you explain the annotations you listed? Is that a proposed future way to access module properties from inside a generator? GeneratorContext.getPropertyOracle() is the way to get these at runtime, correct? So do you want me to add define-property name=gwt.rpc.proxySuperClass values=com.foo.Bar/ to /com/google/gwt/user/RemoteService.gwt.xml ? I'm fine with that, except I'm not sure about the values attribute. I don't want end-user modules to be forced to choose from a pre-defined set of values for this property. I want to support providing arbitrary subclasses of RemoteServiceProxy. From the docs: define-property name=property_name values=property_values : Define a property and allowable values (comma-separated identifiers). This element is typically used to generate a value that will be evaluated by a rule using a when... element. Alex On Fri, Jan 23, 2009 at 1:25 AM, Ray Cromwell cromwell...@gmail.com wrote: Agreed. I used a similar patch in my own implementation a few weeks ago, although yours is simpler. One thing I'd suggest though is to get the superclass setting either from a module property, or from something in the type system, or runtime, rather than the environment. e.g. define-property name=gwt.rpc.proxySuperClass values=com.foo.Bar/ set-property name=gwt.rpc.proxySuperClass value=com.foo.Bar/ which is kind of an abuse of the property system, but allows compiling different permutations of the app for different environments (e.g. gadget vs non-gadget versions) There was some discussion awhile ago of adding new kinds of properties which specify configuration. @GwtProxySuperClass(com.foo.Bar) public interface MyService extends RemoteService { ... } which allows specifying the transport, but does not allow more than 1 transport at a time for the same type (without creating subinterfaces) However you could easily do something like: @GwtProxySuperClass(GadgetProxy) public MyGadgetService extends MyService {...} @GwtProxySuperClass(ProtoBufProxy) public MyProtoBufService extends MyService {...} Using environment properties doesn't seem GWT-like to me, since it kind of buries flags deep inside implementation code that most users won't see and moves it to build scripts. This is one of the things I always disliked about Sun's use of -D parameters all over the JRE code, since finding out a complete list of all these magic variables and exactly what they do is often difficult. GWT's idiom is usually to embed build specific switches via deferred binding properties. -Ray On Thu, Jan 22, 2009 at 8:27 PM, Alex Epshteyn alexander.epsht...@gmail.com wrote: Anyhow, let's get this thread back on track to being a discussion about allowing RPC over non-XHR proxy channels like gadgets.io.makeRequst. You can use my RPC code with or without the gwt-gadgets library. I'd like to get this patch into trunk if no one objects. Alex On Thu, Jan 22, 2009 at 8:38 PM, Ray Cromwell cromwell...@gmail.com wrote: I don't quite understand this point. Any JSO you create is going to be tightly bound to the underlying Gadget/OpenSocial APIs, so what's the difference between a JSO binding which is isn't dependency injected, vs one that is, with regard to keeping up with API changes? Are you arguing against using GWT JSOs to call OpenSocial APIs, or just trying to argue against GadgetLinker injecting the reference for you? There seems to be little difference between writing a native method to get the initial reference to an Overlay type, or having it injected for you, with respect to fast evolving specs. All the GadgetLinker does is construct an instance of a type that you tell it and it wouldn't be hard to modify it so inject JSO Overlays. To me, the only issue that controls whether or not you can keep in sink is whether you have access to the mapping source. And even then, that isn't the biggest issue with OpenSocial programming. The actual specs 0.6/0.7/0.8/0.81/0.9 etc aren't changing that fast, in fact, I wish they'd change faster. The real problem with OpenSocial programming, which hits Java programmers just as hard as JavaScript programmers, is poor container implementations, and the fact that the spec is designed in a way that virtually everything is optional to implement. Quick, which containers support notifications, requestShareApp, or activities? Which support OAuth? IMHO, a generator which could parse idiomatic JsDoc/Javascript ala Bob's JS Interop, and with some extra annotations, automatically generate JSO bindings, would actually be superior to writing JSOs by hand to keep them in sink, or even programming Javascript by hand. Why? Because everytime the spec is updated, if there was a mismatch, you could detect errors. However, none of that really matters much, since unless you decide to target a single OS container,
[gwt-contrib] Re: Proposal: Lightweight GWT-RPC implementation for OpenSocial and Gadgets
You can extend properties in your own module file, so if a user has a need in the future to override the proxy superclass, they can extend-property + set-property the new override. You'll see that RPC already uses a property for settings in the RemoteService.gwt.xml -Ray On Thu, Jan 22, 2009 at 11:02 PM, Alex Epshteyn alexander.epsht...@gmail.com wrote: I agree that an environment variable isn't ideal, but could you explain the annotations you listed? Is that a proposed future way to access module properties from inside a generator? GeneratorContext.getPropertyOracle() is the way to get these at runtime, correct? So do you want me to add define-property name=gwt.rpc.proxySuperClass values=com.foo.Bar/ to /com/google/gwt/user/RemoteService.gwt.xml ? I'm fine with that, except I'm not sure about the values attribute. I don't want end-user modules to be forced to choose from a pre-defined set of values for this property. I want to support providing arbitrary subclasses of RemoteServiceProxy. From the docs: define-property name=property_name values=property_values : Define a property and allowable values (comma-separated identifiers). This element is typically used to generate a value that will be evaluated by a rule using a when... element. Alex On Fri, Jan 23, 2009 at 1:25 AM, Ray Cromwell cromwell...@gmail.com wrote: Agreed. I used a similar patch in my own implementation a few weeks ago, although yours is simpler. One thing I'd suggest though is to get the superclass setting either from a module property, or from something in the type system, or runtime, rather than the environment. e.g. define-property name=gwt.rpc.proxySuperClass values=com.foo.Bar/ set-property name=gwt.rpc.proxySuperClass value=com.foo.Bar/ which is kind of an abuse of the property system, but allows compiling different permutations of the app for different environments (e.g. gadget vs non-gadget versions) There was some discussion awhile ago of adding new kinds of properties which specify configuration. @GwtProxySuperClass(com.foo.Bar) public interface MyService extends RemoteService { ... } which allows specifying the transport, but does not allow more than 1 transport at a time for the same type (without creating subinterfaces) However you could easily do something like: @GwtProxySuperClass(GadgetProxy) public MyGadgetService extends MyService {...} @GwtProxySuperClass(ProtoBufProxy) public MyProtoBufService extends MyService {...} Using environment properties doesn't seem GWT-like to me, since it kind of buries flags deep inside implementation code that most users won't see and moves it to build scripts. This is one of the things I always disliked about Sun's use of -D parameters all over the JRE code, since finding out a complete list of all these magic variables and exactly what they do is often difficult. GWT's idiom is usually to embed build specific switches via deferred binding properties. -Ray On Thu, Jan 22, 2009 at 8:27 PM, Alex Epshteyn alexander.epsht...@gmail.com wrote: Anyhow, let's get this thread back on track to being a discussion about allowing RPC over non-XHR proxy channels like gadgets.io.makeRequst. You can use my RPC code with or without the gwt-gadgets library. I'd like to get this patch into trunk if no one objects. Alex On Thu, Jan 22, 2009 at 8:38 PM, Ray Cromwell cromwell...@gmail.com wrote: I don't quite understand this point. Any JSO you create is going to be tightly bound to the underlying Gadget/OpenSocial APIs, so what's the difference between a JSO binding which is isn't dependency injected, vs one that is, with regard to keeping up with API changes? Are you arguing against using GWT JSOs to call OpenSocial APIs, or just trying to argue against GadgetLinker injecting the reference for you? There seems to be little difference between writing a native method to get the initial reference to an Overlay type, or having it injected for you, with respect to fast evolving specs. All the GadgetLinker does is construct an instance of a type that you tell it and it wouldn't be hard to modify it so inject JSO Overlays. To me, the only issue that controls whether or not you can keep in sink is whether you have access to the mapping source. And even then, that isn't the biggest issue with OpenSocial programming. The actual specs 0.6/0.7/0.8/0.81/0.9 etc aren't changing that fast, in fact, I wish they'd change faster. The real problem with OpenSocial programming, which hits Java programmers just as hard as JavaScript programmers, is poor container implementations, and the fact that the spec is designed in a way that virtually everything is optional to implement. Quick, which containers support notifications, requestShareApp, or activities? Which support OAuth? IMHO, a