Maybe the simpler answer is to have a read resolve / write object  
equivalent.

I personally think coupling these value objects all the way from your  
database tier to the browser smells.

The detached object problem seems like a symptom of the smell.

On 23/04/2009, at 12:22 PM, Ray Cromwell <[email protected]> wrote:

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