IMHO, The interesting case is not AOP of outgoing objects, but AOP of
incoming objects (return values from RPC). This might even help some
of the GWT/GAE/JDO issues, where you could AOP enhance an incoming
model object to track dirty modification of fields.  This is not
unlike the JRE serialization mechanisms like readResolve() this allow
replacement.

-Ray


On Wed, Apr 22, 2009 at 7:19 PM, Arthur Kalmenson <[email protected]> wrote:
>
>> 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.
>
> Yeah, that is an interesting question. However, wouldn't the AOP be
> happening before you send the object over the wire? You wouldn't
> really care about any interception at that point....
>
> --
> Arthur Kalmenson
>
>
>
> On Wed, Apr 22, 2009 at 12:28 AM, Ray Cromwell <[email protected]> wrote:
>>
>> On Tue, Apr 21, 2009 at 7:11 PM, Arthur Kalmenson <[email protected]> 
>> 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 <[email protected]> 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
>>>> <[email protected]> wrote:
>>>>> Sounds a good solution.
>>>>> How would this solve the use case "data returned by RPC call" ?
>>>>>
>>>>> 2009/4/21 Ray Cromwell <[email protected]>
>>>>>>
>>>>>> 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
>>>>>> <[email protected]> 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 <[email protected]>
>>>>>> >>
>>>>>> >> On Tue, Apr 21, 2009 at 12:38 PM, nicolas de loof
>>>>>> >> <[email protected]> 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 <[email protected]>
>>>>>> >>>>
>>>>>> >>>> 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 <[email protected]>
>>>>>> >>>> wrote:
>>>>>> >>>>>
>>>>>> >>>>>
>>>>>> >>>>>
>>>>>> >>>>> On 20 avr, 08:43, nicolas de loof <[email protected]> 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
-~----------~----~----~----~------~----~------~--~---

Reply via email to