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 -~----------~----~----~----~------~----~------~--~---