On Tue, Apr 21, 2009 at 7:11 PM, Arthur Kalmenson <arthur.k...@gmail.com> wrote: > > Hmm, but don't you normally send some kind of Model or domain object > over the wire and not something that would need to be injected with > dependencies by Gin?
I think what he's saying is that he might have an RPC method like this: public interface MyService extends RemoteService { MyBean getBean(); } Now, MyBean does not implement interface X, but a generator/AOP interceptor could make a subclass of MyBean that has interface X implement. IIRC, GWT RPC just invokes the default constructor, so there's no way to intercept this and substitute a replacement. I think the other thing he might want to do is intercept client-side UI classes and make them call addPropertyChangeListener() on a model object based on certain invocations. -Ray > And Bruce, that's an interesting example. I was thinking how one would > implement AOP in GWT, perhaps it's not as hard as I originally > thought. Is there a way to extend this example to dynamically create > proxies for any class that'll be advised by some aspect? > > Also, Nicolas, AFAIK, the GWT team (bobv) is working on a data binding > (and validation?) framework. I'm hoping something will hit the > incubator soon so we can all jump on board and help out. It'd > definitely have saved us thousands of lines of glue code ;). > > P.S. Sorry about not writing up that how-to for GWTMockUtilities, > Bruce. I'll try to do it some time this week. > > Best regards, > -- > Arthur Kalmenson > > > > On Tue, Apr 21, 2009 at 2:58 PM, Ray Cromwell <cromwell...@gmail.com> wrote: >> >> Interesting question. Gin auto-creates RPC interfaces as well, for >> example, if you have: >> >> public interface MyFoo extends Ginjector { >> MyServiceAsync getService(); >> } >> >> then Gin implicitly looks for MyService.class and invokes >> GWT.create(MyService.class) when calling getService(). Since Gin is >> handling the creation, I'm not sure if it handles RPC methods with >> classes have have @Inject annotations, but you could probably setup a >> separate binding. The de-serialization logic in RPC is not likely to >> allow Gin interception, since it apparently uses default constructors >> to create classes, and what you want it to do is delegate the >> construction to some injectable mechanism (e.g. to substitute your own >> subclasses) >> >> It doesn't sound impossible to make this work, and is probably easier >> to get right than trying to make new Foo() interceptable by the >> compiler. I would join the Gin groups and ask the guys there about it. >> >> -Ray >> >> >> On Tue, Apr 21, 2009 at 11:49 AM, nicolas de loof >> <nicolas.del...@gmail.com> wrote: >>> Sounds a good solution. >>> How would this solve the use case "data returned by RPC call" ? >>> >>> 2009/4/21 Ray Cromwell <cromwell...@gmail.com> >>>> >>>> I really think Guice-style dependency injection is the way to go to >>>> solve this problem, rather than trying to emulate Java >>>> Proxies/Classloader in the compiler. If you use Guice/Gin, then in Gin >>>> you can inject GWT.create-d versions, and in JUnit-mode, you can use >>>> regular Guice injection. The code use is 99% between GWT and non-GWT >>>> versions test versions, with the exception of the >>>> Guice-config/Injector creation. >>>> >>>> Because of the way Gin works transitively, you only need a single >>>> GWT.create() and this is isolated to your startup code while in your >>>> JUnit version, you kick off a Guice-injected class instead. >>>> >>>> -Ray >>>> >>>> On Tue, Apr 21, 2009 at 11:28 AM, nicolas de loof >>>> <nicolas.del...@gmail.com> wrote: >>>> > A simple example : databinding >>>> > Lets consider I want to bind some Label text to some model Bean value. >>>> > Gwt >>>> > Label widget "text" can be accessed as a javaBean property, so this >>>> > sound a >>>> > typical java.beans.binding use-case >>>> > This requires my model bean to support PropertyChangeListeners. As I'm >>>> > lazy >>>> > I'd like a generator to create an "enhanced" model class with such >>>> > support >>>> > for the "value" property. >>>> > I can get this to work today if my model Bean is created using >>>> > GWT.create(), >>>> > but this makes my code GWT-dependant and not testable in "standalone" >>>> > junit. >>>> > If the generator "enhanced" class is used even when I use " new Model() >>>> > " or >>>> > get a Model bean from RPC, my code can be easily unit tested. >>>> > Cheers, >>>> > Nicolas >>>> > >>>> > 2009/4/21 Bruce Johnson <br...@google.com> >>>> >> >>>> >> On Tue, Apr 21, 2009 at 12:38 PM, nicolas de loof >>>> >> <nicolas.del...@gmail.com> wrote: >>>> >>> >>>> >>> The only critism I'd have is the requirement to use GWT.create() to >>>> >>> get >>>> >>> code from a generator. This is a requirement when the generated code >>>> >>> doesn't >>>> >>> extend the source type (for example for Async interfaces) but not when >>>> >>> the >>>> >>> genrator is used to add some capabilities (ie acts as a decorator), >>>> >>> for >>>> >>> example to add PropertyChangeListener to a model bean. >>>> >> >>>> >> Perhaps if you could distill down a more concrete example, it could get >>>> >> the wheels turning. Enhancements to GWT.create() certainly aren't off >>>> >> the >>>> >> table. Ray Cromwell has made some pretty useful-sounding suggestions in >>>> >> the >>>> >> past. We just have to find large-group consensus on what makes the most >>>> >> sense, striking a balance between power, clarity, and of course, >>>> >> optimizability. >>>> >> >>>> >> Here's a quick back-of-envelope pattern that could possibly work: >>>> >> >>>> >> class PersonBean { >>>> >> void setName(String name): >>>> >> String getName(); >>>> >> } >>>> >> >>>> >> interface MethodCallLogger { >>>> >> } >>>> >> >>>> >> class MyEntryPoint { >>>> >> class PersonBeanWithMethodCallLogger extends PersonBean implements >>>> >> MethodCallLogger { >>>> >> // empty, but a subclass gets generated >>>> >> } >>>> >> >>>> >> public void onModuleLoad() { >>>> >> // Have a generate-with rule for MethodCallLoggerGenerator, >>>> >> triggered >>>> >> by assignability to "MethodCallLogger" >>>> >> PersonBean pb = GWT.create(PersonBeanWithMethodCallLogger.class); >>>> >> pb.setName("Nicolas"); >>>> >> } >>>> >> } >>>> >> >>>> >> // Generated... >>>> >> class PersonBeanWithMethodCallLoggerImpl extends >>>> >> PersonBeanWithMethodCallLogger { >>>> >> void setName(String name) { >>>> >> someLogger.log("setName('" + name + "') called"); >>>> >> super.setName(name); >>>> >> } >>>> >> >>>> >> ... >>>> >> } >>>> >> >>>> >> As formulated above, this pattern doesn't compose well. But it might be >>>> >> that we can forge a pattern like this into something everyone likes >>>> >> eventually. >>>> >> >>>> >> -- Bruce >>>> >> >>>> >>> >>>> >>> This makes unit testing more difficult as code that uses GWT.create >>>> >>> cannot run in "classic" jUnit. It would be great to have the compiler >>>> >>> use >>>> >>> generator-extended classes even when created using the standard "new" >>>> >>> keyword. >>>> >>> Thanks a lot for the explanation. >>>> >>> Nicolas >>>> >>> >>>> >>> 2009/4/21 Bruce Johnson <br...@google.com> >>>> >>>> >>>> >>>> A sort of philosophical meta-point that may or may not be of >>>> >>>> interest... >>>> >>>> >>>> >>>> When we started GWT, we were worried about managing the complexity of >>>> >>>> compile-time code generation, so we tried to find the simplest, most >>>> >>>> easy-to-debug approach we could think of. GWT's model of never >>>> >>>> changing >>>> >>>> existing code[1], but only adding new Java source during the compile, >>>> >>>> is >>>> >>>> really a design choice, not a technical limitation. The benefit of >>>> >>>> the >>>> >>>> current design is that you can add -gen to hosted mode and map the >>>> >>>> corresponding folder into your source path, and then easily step >>>> >>>> through all >>>> >>>> your code, both handwritten and generated, in the debugger. This >>>> >>>> avoids >>>> >>>> tricky or confusing situations wherein the source code you see >>>> >>>> appears to be >>>> >>>> doing something different than the bytecode that's running. It seems >>>> >>>> good to >>>> >>>> avoid that kind of dichotomy, on the principle that >>>> >>>> straightforward-though-verbose is generally better than >>>> >>>> fancy-but-confusing. >>>> >>>> >>>> >>>> [1] Overlay types were the first time we ever even did bytecode >>>> >>>> rewriting, and that support is implemented at a very deep level. >>>> >>>> Also, JSOs >>>> >>>> are intended to be among only a very few "magic" things in GWT >>>> >>>> (basically, >>>> >>>> JSNI, GWT.create(), GWT.runAsync(), and JSOs). We went to a lot of >>>> >>>> effort to >>>> >>>> ensure that JSOs worked according to a fixed set of rules that are >>>> >>>> not hard >>>> >>>> to comply with, even if people don't fully understand why the >>>> >>>> implementation >>>> >>>> requires it. >>>> >>>> >>>> >>>> On Mon, Apr 20, 2009 at 11:11 AM, Thomas Broyer <t.bro...@gmail.com> >>>> >>>> wrote: >>>> >>>>> >>>> >>>>> >>>> >>>>> >>>> >>>>> On 20 avr, 08:43, nicolas de loof <nicolas.del...@gmail.com> wrote: >>>> >>>>> > > > I wonder if there is any way to also "pre-process" Java >>>> >>>>> > > > sources, >>>> >>>>> > > > for >>>> >>>>> > > example >>>> >>>>> > > > this would enable support for Aspect Oriented Programming or >>>> >>>>> > > > maybe some >>>> >>>>> > > > DataBinding framework. >>>> >>>>> > >>>> >>>>> > > Depends what you mean by "pre-process"... Generally, generators >>>> >>>>> > > analyze the class they're called for (for example, looking for >>>> >>>>> > > specific annotations on methods or on the class itself) and >>>> >>>>> > > according >>>> >>>>> > > to this generate a Java class extending the one they've been >>>> >>>>> > > called >>>> >>>>> > > for. >>>> >>>>> > > (is this understandable? is this at least no-so-bad english?) >>>> >>>>> > >>>> >>>>> > In many case the generator will create from MyClassX some >>>> >>>>> > MyClassXImpl or >>>> >>>>> > equivalent that extends the original one, bu not REPLACE it as >>>> >>>>> > Java >>>> >>>>> > source. >>>> >>>>> > This is what I mean by "pre-process". >>>> >>>>> > >>>> >>>>> > For example, to implement a AOP framework I'd like to instrument >>>> >>>>> > all >>>> >>>>> > calls >>>> >>>>> > to some method. For this reason I'd like a generator / >>>> >>>>> > pre-processor >>>> >>>>> > to >>>> >>>>> > check the source files and detect the matching pointcuts to add >>>> >>>>> > some >>>> >>>>> > adived >>>> >>>>> > code. Many other example can apply, including annotation >>>> >>>>> > processing >>>> >>>>> > for >>>> >>>>> > declarative coding (ex : @Property annotation to automagically >>>> >>>>> > introduce the >>>> >>>>> > required PropertyChangeListeners) >>>> >>>>> >>>> >>>>> You would generate a subclass that delegates to super.method() >>>> >>>>> after/ >>>> >>>>> before the aspect(s) code. >>>> >>>>> >>>> >>>>> > I never tried it myself, but I'n not sure a generator can REPLACE >>>> >>>>> > the >>>> >>>>> > original Java Source. >>>> >>>>> >>>> >>>>> AFAICT, it can't, but there's probably no need for this. >>>> >>>>> >>>> >>>>> > I may be wrong but I also thing the generated code is >>>> >>>>> > only available when using GWT.create(), >>>> >>>>> >>>> >>>>> The generator is only called at the point where GWT.create() is >>>> >>>>> called >>>> >>>>> (I may be wrong but you could generate a different output for each >>>> >>>>> GWT.create() call-point for the same class literal), so yes, you're >>>> >>>>> right. >>>> >>>>> >>>> >>>>> >>>> >>>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>> >>>> >>> >>>> >>> >>>> >> >>>> >> >>>> >> >>>> > >>>> > >>>> > > >>>> > >>>> >>>> >>> >>> >>> > >>> >> >> > >> > > > > --~--~---------~--~----~------------~-------~--~----~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~----------~----~----~----~------~----~------~--~---