[gwt-contrib] Re: Java source transformation
To implement Interceptors in gwt one does just needs to follow the same general patterns that exist in real java and aop. I have already done interceptors / aop for gwt as part of my own di module in gwt. One does not need interceptors in gwt a lot of extra behind the scenes classes are needed both generated and framework to make it work. 1/ To intercept one class you need to subclass the target. 2/ every public method needs to include some stuff to handle firing of said interceptors. 3/ if u want the interceptors to be able to truly intercept and be able to modify parameters, veto the call to the target substitute a different return value etc a lot of extra code is needed. If u want too see am example download my project and run the test cases with the gen flag on. Supporting other dynamic mechanisms like reflection are also possible but the amount of generated stuff required bloats your javascript by significant amounts. One of the goals of gwt is to produce minimalist code and this goes against this mantra. On 23/04/2009, at 12:19 PM, Arthur Kalmenson arthur.k...@gmail.com 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 cromwell...@gmail.com wrote: 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-contrib] Re: Java source transformation
If there was a low cost way to disable inlining and conversion to static methods of certain functions, you might be able handle the interception dynamically, e.g. for(method in myClass.prototype) { if(shouldIntercept(myClass.prototype[method])) { myClass.prototype[method] = function() { return @com.foo.InterceptorRegistry::methodInterceptor(...)(...); } } } You'd have to implement one method for Hosted Mode, and another for web mode. This would not really add any bloat, as method names could be registered for interception using their obfuscated ids, and only non-pruned methods would be picked up by the introspector. There are quite a few JS frameworks that implement stuff like this. The problem is, if you can't force non-inlining and non-monomorphic conversions, then you run the risk of inlined or statically invoked callsites not invoking the interceptors. One way to force this is to simply switch the parameter eval order in your methods, which disables inlining (for now, but not guaranteed to work in future). Preventing the staticifier from running is more difficult. You have to induce polymorphism by subclassing in a way that the method call can't be inferred final, and this will lead to bloat. Perhaps future compiler hints like @DoNotInline could help, or maybe reusing 'volatile' some how, like if a method references a violate parameter, it can't be inlined or staticified. -Ray On Wed, Apr 22, 2009 at 11:41 PM, Miroslav Pokorny miroslav.poko...@gmail.com wrote: To implement Interceptors in gwt one does just needs to follow the same general patterns that exist in real java and aop. I have already done interceptors / aop for gwt as part of my own di module in gwt. One does not need interceptors in gwt a lot of extra behind the scenes classes are needed both generated and framework to make it work. 1/ To intercept one class you need to subclass the target. 2/ every public method needs to include some stuff to handle firing of said interceptors. 3/ if u want the interceptors to be able to truly intercept and be able to modify parameters, veto the call to the target substitute a different return value etc a lot of extra code is needed. If u want too see am example download my project and run the test cases with the gen flag on. Supporting other dynamic mechanisms like reflection are also possible but the amount of generated stuff required bloats your javascript by significant amounts. One of the goals of gwt is to produce minimalist code and this goes against this mantra. On 23/04/2009, at 12:19 PM, Arthur Kalmenson arthur.k...@gmail.com 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 cromwell...@gmail.com wrote: 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
[gwt-contrib] Re: Java source transformation
Too much extra nonsense adding annotations everywhere. You could have written a more efficient decorator fir less keystrokes and the decorator will always be faster at runtime and save the compiler from overheating with extra passes and complexity. It's never a good thing to chest and reuse something line volatile. Today you aNt it for this and tomorrow someone else will have an equally useful thing which they want to steel volatile for. Why not keep it simple and just writeba decorator ? On 23/04/2009, at 5:10 PM, Ray Cromwell cromwell...@gmail.com wrote: If there was a low cost way to disable inlining and conversion to static methods of certain functions, you might be able handle the interception dynamically, e.g. for(method in myClass.prototype) { if(shouldIntercept(myClass.prototype[method])) { myClass.prototype[method] = function() { return @com.foo.InterceptorRegistry::methodInterceptor(...) (...); } } } You'd have to implement one method for Hosted Mode, and another for web mode. This would not really add any bloat, as method names could be registered for interception using their obfuscated ids, and only non-pruned methods would be picked up by the introspector. There are quite a few JS frameworks that implement stuff like this. The problem is, if you can't force non-inlining and non-monomorphic conversions, then you run the risk of inlined or statically invoked callsites not invoking the interceptors. One way to force this is to simply switch the parameter eval order in your methods, which disables inlining (for now, but not guaranteed to work in future). Preventing the staticifier from running is more difficult. You have to induce polymorphism by subclassing in a way that the method call can't be inferred final, and this will lead to bloat. Perhaps future compiler hints like @DoNotInline could help, or maybe reusing 'volatile' some how, like if a method references a violate parameter, it can't be inlined or staticified. -Ray On Wed, Apr 22, 2009 at 11:41 PM, Miroslav Pokorny miroslav.poko...@gmail.com wrote: To implement Interceptors in gwt one does just needs to follow the same general patterns that exist in real java and aop. I have already done interceptors / aop for gwt as part of my own di module in gwt. One does not need interceptors in gwt a lot of extra behind the scenes classes are needed both generated and framework to make it work. 1/ To intercept one class you need to subclass the target. 2/ every public method needs to include some stuff to handle firing of said interceptors. 3/ if u want the interceptors to be able to truly intercept and be able to modify parameters, veto the call to the target substitute a different return value etc a lot of extra code is needed. If u want too see am example download my project and run the test cases with the gen flag on. Supporting other dynamic mechanisms like reflection are also possible but the amount of generated stuff required bloats your javascript by significant amounts. One of the goals of gwt is to produce minimalist code and this goes against this mantra. On 23/04/2009, at 12:19 PM, Arthur Kalmenson arthur.k...@gmail.com 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 cromwell...@gmail.com wrote: 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
[gwt-contrib] Re: Java source transformation
What about support for true aop alliance like interfaces where the one can modify parameters, change return values etc. Just adding a list of interested interceptors adds some bloat to every enhanced and I use the word loosely costs. There's no need for this anyway, just like there's no need for reflection in gwt. One could argue that serializing java types for rpc adds bloat... On the one hand the compiler is trying to prune unreachsble classes and then something like this adds stuff back in. I believe dojo which tries to copy many java constructs has it's own aop module...How popular is it? Does anyone really care for it compared to the other stuff? There's no need for aop just write up a decorator and do whatever, no generator kicking in which saves additional time , smaller output etc. Are there really benefits that a decorator doesn't solve that aop would ??? On 23/04/2009, at 5:10 PM, Ray Cromwell cromwell...@gmail.com wrote: If there was a low cost way to disable inlining and conversion to static methods of certain functions, you might be able handle the interception dynamically, e.g. for(method in myClass.prototype) { if(shouldIntercept(myClass.prototype[method])) { myClass.prototype[method] = function() { return @com.foo.InterceptorRegistry::methodInterceptor(...) (...); } } } You'd have to implement one method for Hosted Mode, and another for web mode. This would not really add any bloat, as method names could be registered for interception using their obfuscated ids, and only non-pruned methods would be picked up by the introspector. There are quite a few JS frameworks that implement stuff like this. The problem is, if you can't force non-inlining and non-monomorphic conversions, then you run the risk of inlined or statically invoked callsites not invoking the interceptors. One way to force this is to simply switch the parameter eval order in your methods, which disables inlining (for now, but not guaranteed to work in future). Preventing the staticifier from running is more difficult. You have to induce polymorphism by subclassing in a way that the method call can't be inferred final, and this will lead to bloat. Perhaps future compiler hints like @DoNotInline could help, or maybe reusing 'volatile' some how, like if a method references a violate parameter, it can't be inlined or staticified. -Ray On Wed, Apr 22, 2009 at 11:41 PM, Miroslav Pokorny miroslav.poko...@gmail.com wrote: To implement Interceptors in gwt one does just needs to follow the same general patterns that exist in real java and aop. I have already done interceptors / aop for gwt as part of my own di module in gwt. One does not need interceptors in gwt a lot of extra behind the scenes classes are needed both generated and framework to make it work. 1/ To intercept one class you need to subclass the target. 2/ every public method needs to include some stuff to handle firing of said interceptors. 3/ if u want the interceptors to be able to truly intercept and be able to modify parameters, veto the call to the target substitute a different return value etc a lot of extra code is needed. If u want too see am example download my project and run the test cases with the gen flag on. Supporting other dynamic mechanisms like reflection are also possible but the amount of generated stuff required bloats your javascript by significant amounts. One of the goals of gwt is to produce minimalist code and this goes against this mantra. On 23/04/2009, at 12:19 PM, Arthur Kalmenson arthur.k...@gmail.com 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 cromwell...@gmail.com wrote: 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
[gwt-contrib] Re: Java source transformation
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 cromwell...@gmail.com 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 arthur.k...@gmail.com 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 cromwell...@gmail.com wrote: 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
[gwt-contrib] Re: Java source transformation
Volatile has a long history of disabling compiler optimizations, in both Java, and C/C++, so it is not quite inappropriate to use it for this purpose. GWT already uses volatile for this purpose, for example, volatile fields are not subject to type-tightening or being promoted to final, and in some areas, expressions that evaluate as volatile are considered to have side effects, even if the operations themselves are side effect free. Volatile in C/C++ prevents a bunch of optimizations as well and must be used in some circumstances (like if you want a busy-wait spin loop to not be dead-code-eliminated) Whether or not AOP is useful or not is besides the point. The point is, the cost of AOP is not as high as the cost of reflection, and implementing AOP isn't an 'all or nothing' proposition. I personally don't use AOP, but if someone asks me whether there's an efficient way to do it, the answer is, maybe there is. I don't think it is helpful to just shutdown discussion over a particular pattern because one doesn't like it. On Thu, Apr 23, 2009 at 12:47 AM, Miroslav Pokorny miroslav.poko...@gmail.com wrote: Too much extra nonsense adding annotations everywhere. You could have written a more efficient decorator fir less keystrokes and the decorator will always be faster at runtime and save the compiler from overheating with extra passes and complexity. It's never a good thing to chest and reuse something line volatile. Today you aNt it for this and tomorrow someone else will have an equally useful thing which they want to steel volatile for. Why not keep it simple and just writeba decorator ? On 23/04/2009, at 5:10 PM, Ray Cromwell cromwell...@gmail.com wrote: If there was a low cost way to disable inlining and conversion to static methods of certain functions, you might be able handle the interception dynamically, e.g. for(method in myClass.prototype) { if(shouldIntercept(myClass.prototype[method])) { myClass.prototype[method] = function() { return @com.foo.InterceptorRegistry::methodInterceptor(...) (...); } } } You'd have to implement one method for Hosted Mode, and another for web mode. This would not really add any bloat, as method names could be registered for interception using their obfuscated ids, and only non-pruned methods would be picked up by the introspector. There are quite a few JS frameworks that implement stuff like this. The problem is, if you can't force non-inlining and non-monomorphic conversions, then you run the risk of inlined or statically invoked callsites not invoking the interceptors. One way to force this is to simply switch the parameter eval order in your methods, which disables inlining (for now, but not guaranteed to work in future). Preventing the staticifier from running is more difficult. You have to induce polymorphism by subclassing in a way that the method call can't be inferred final, and this will lead to bloat. Perhaps future compiler hints like @DoNotInline could help, or maybe reusing 'volatile' some how, like if a method references a violate parameter, it can't be inlined or staticified. -Ray On Wed, Apr 22, 2009 at 11:41 PM, Miroslav Pokorny miroslav.poko...@gmail.com wrote: To implement Interceptors in gwt one does just needs to follow the same general patterns that exist in real java and aop. I have already done interceptors / aop for gwt as part of my own di module in gwt. One does not need interceptors in gwt a lot of extra behind the scenes classes are needed both generated and framework to make it work. 1/ To intercept one class you need to subclass the target. 2/ every public method needs to include some stuff to handle firing of said interceptors. 3/ if u want the interceptors to be able to truly intercept and be able to modify parameters, veto the call to the target substitute a different return value etc a lot of extra code is needed. If u want too see am example download my project and run the test cases with the gen flag on. Supporting other dynamic mechanisms like reflection are also possible but the amount of generated stuff required bloats your javascript by significant amounts. One of the goals of gwt is to produce minimalist code and this goes against this mantra. On 23/04/2009, at 12:19 PM, Arthur Kalmenson arthur.k...@gmail.com 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 cromwell...@gmail.com wrote: On Tue, Apr 21, 2009 at 7:11 PM, Arthur Kalmenson
[gwt-contrib] Re: Java source transformation
Of course the answer to many programming questions is yes it can be done and that sounds cool, but there is a big but. Given the necessary compiler support - eg: to stop inlining of methods you may wish to intercept - the question remains is this the best way to solve this problem. On the server aop is often used to solve problems -like tx management - which are not present in a gwt app. I appreciate the problem with sending detached objects, however nothing has been said to refute my previous comments that maybe, just maybe detached objects in gwt are a bad idea...i'd like hear some thoughts on that. Btw I'm all for experimentation, don't get me wrong. In this case I did it one way and thinking back I believe there are alternatives and I am just voicing my opinions on my observations... Hth. On 23/04/2009, at 6:15 PM, Ray Cromwell cromwell...@gmail.com wrote: Volatile has a long history of disabling compiler optimizations, in both Java, and C/C++, so it is not quite inappropriate to use it for this purpose. GWT already uses volatile for this purpose, for example, volatile fields are not subject to type-tightening or being promoted to final, and in some areas, expressions that evaluate as volatile are considered to have side effects, even if the operations themselves are side effect free. Volatile in C/C++ prevents a bunch of optimizations as well and must be used in some circumstances (like if you want a busy-wait spin loop to not be dead-code-eliminated) Whether or not AOP is useful or not is besides the point. The point is, the cost of AOP is not as high as the cost of reflection, and implementing AOP isn't an 'all or nothing' proposition. I personally don't use AOP, but if someone asks me whether there's an efficient way to do it, the answer is, maybe there is. I don't think it is helpful to just shutdown discussion over a particular pattern because one doesn't like it. On Thu, Apr 23, 2009 at 12:47 AM, Miroslav Pokorny miroslav.poko...@gmail.com wrote: Too much extra nonsense adding annotations everywhere. You could have written a more efficient decorator fir less keystrokes and the decorator will always be faster at runtime and save the compiler from overheating with extra passes and complexity. It's never a good thing to chest and reuse something line volatile. Today you aNt it for this and tomorrow someone else will have an equally useful thing which they want to steel volatile for. Why not keep it simple and just writeba decorator ? On 23/04/2009, at 5:10 PM, Ray Cromwell cromwell...@gmail.com wrote: If there was a low cost way to disable inlining and conversion to static methods of certain functions, you might be able handle the interception dynamically, e.g. for(method in myClass.prototype) { if(shouldIntercept(myClass.prototype[method])) { myClass.prototype[method] = function() { return @com.foo.InterceptorRegistry::methodInterceptor(...) (...); } } } You'd have to implement one method for Hosted Mode, and another for web mode. This would not really add any bloat, as method names could be registered for interception using their obfuscated ids, and only non-pruned methods would be picked up by the introspector. There are quite a few JS frameworks that implement stuff like this. The problem is, if you can't force non-inlining and non-monomorphic conversions, then you run the risk of inlined or statically invoked callsites not invoking the interceptors. One way to force this is to simply switch the parameter eval order in your methods, which disables inlining (for now, but not guaranteed to work in future). Preventing the staticifier from running is more difficult. You have to induce polymorphism by subclassing in a way that the method call can't be inferred final, and this will lead to bloat. Perhaps future compiler hints like @DoNotInline could help, or maybe reusing 'volatile' some how, like if a method references a violate parameter, it can't be inlined or staticified. -Ray On Wed, Apr 22, 2009 at 11:41 PM, Miroslav Pokorny miroslav.poko...@gmail.com wrote: To implement Interceptors in gwt one does just needs to follow the same general patterns that exist in real java and aop. I have already done interceptors / aop for gwt as part of my own di module in gwt. One does not need interceptors in gwt a lot of extra behind the scenes classes are needed both generated and framework to make it work. 1/ To intercept one class you need to subclass the target. 2/ every public method needs to include some stuff to handle firing of said interceptors. 3/ if u want the interceptors to be able to truly intercept and be able to modify parameters, veto the call to the target substitute a different return value etc a lot of extra code is needed. If u want too see am example download my project and run the test cases with the gen flag on. Supporting other dynamic
[gwt-contrib] Re: Java source transformation
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 cromwell...@gmail.com wrote: 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
[gwt-contrib] Re: Java source transformation
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 arthur.k...@gmail.com 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 cromwell...@gmail.com wrote: 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-contrib] Re: Java source transformation
On Tue, Apr 21, 2009 at 12:38 PM, nicolas de loof nicolas.del...@gmail.comwrote: 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.comwrote: 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
[gwt-contrib] Re: Java source transformation
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.comwrote: 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
[gwt-contrib] Re: Java source transformation
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
[gwt-contrib] Re: Java source transformation
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,
[gwt-contrib] Re: Java source transformation
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
[gwt-contrib] Re: Java source transformation
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
[gwt-contrib] Re: Java source transformation
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) I never tried it myself, but I'n not sure a generator can REPLACE the original Java Source. I may be wrong but I also thing the generated code is only available when using GWT.create(), making the code less testable (with standard junit, not GWTTestCase) and fully GWT-dependenant. Cheers, Nicolas --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Java source transformation
GWT generators cannot access the source AST of the original class, only the class metadata (fields/method names, parameters, signatures), no method body stuff. If you're looking to do AOP/Method Interception, I suggest you take a look at Google Gin which is a Guice implementation for Git. It's a dependency injection framework, and you'll only need a single GWT.create() call in the beginning to start the process. You can't 'intercept' classes with regular GWT generators like you can with a classloader if that's what you're trying to do. But with Gin, the dependency injection is transitive, so in effect, you can intercept other classes that appear as injected parameters or fields. -Ray On Sun, Apr 19, 2009 at 11:43 PM, 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) I never tried it myself, but I'n not sure a generator can REPLACE the original Java Source. I may be wrong but I also thing the generated code is only available when using GWT.create(), making the code less testable (with standard junit, not GWTTestCase) and fully GWT-dependenant. Cheers, Nicolas --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Java source transformation
What I'm looking for is both some AOP capability and a way to port javaFx bind keyword to Java / GWT. gwt-beans-binding is doing databinding using marker interface in model and wrappers for widgets. This makes impossible to use advanced widgets from 3rd tier librairy without some more code to write. Anyway, thanks a lot for this interesting link. Nicolas 2009/4/20 Ray Cromwell cromwell...@gmail.com GWT generators cannot access the source AST of the original class, only the class metadata (fields/method names, parameters, signatures), no method body stuff. If you're looking to do AOP/Method Interception, I suggest you take a look at Google Gin which is a Guice implementation for Git. It's a dependency injection framework, and you'll only need a single GWT.create() call in the beginning to start the process. You can't 'intercept' classes with regular GWT generators like you can with a classloader if that's what you're trying to do. But with Gin, the dependency injection is transitive, so in effect, you can intercept other classes that appear as injected parameters or fields. -Ray On Sun, Apr 19, 2009 at 11:43 PM, 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) I never tried it myself, but I'n not sure a generator can REPLACE the original Java Source. I may be wrong but I also thing the generated code is only available when using GWT.create(), making the code less testable (with standard junit, not GWTTestCase) and fully GWT-dependenant. Cheers, Nicolas --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Java source transformation
With regards to AOP, as Ray mentioned, you might want to check out Google GIN. They haven't yet implemented Interceptors (AFAIK), so you might want to combine efforts with them to get this to work. With regards to data binding, bobv is, AFAIK, working on that feature. If you hold off until it's dropped in the incubator, you could avoid duplicate work. Best regards, -- Arthur Kalmenson On Mon, Apr 20, 2009 at 3:03 AM, nicolas de loof nicolas.del...@gmail.com wrote: What I'm looking for is both some AOP capability and a way to port javaFx bind keyword to Java / GWT. gwt-beans-binding is doing databinding using marker interface in model and wrappers for widgets. This makes impossible to use advanced widgets from 3rd tier librairy without some more code to write. Anyway, thanks a lot for this interesting link. Nicolas 2009/4/20 Ray Cromwell cromwell...@gmail.com GWT generators cannot access the source AST of the original class, only the class metadata (fields/method names, parameters, signatures), no method body stuff. If you're looking to do AOP/Method Interception, I suggest you take a look at Google Gin which is a Guice implementation for Git. It's a dependency injection framework, and you'll only need a single GWT.create() call in the beginning to start the process. You can't 'intercept' classes with regular GWT generators like you can with a classloader if that's what you're trying to do. But with Gin, the dependency injection is transitive, so in effect, you can intercept other classes that appear as injected parameters or fields. -Ray On Sun, Apr 19, 2009 at 11:43 PM, 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) I never tried it myself, but I'n not sure a generator can REPLACE the original Java Source. I may be wrong but I also thing the generated code is only available when using GWT.create(), making the code less testable (with standard junit, not GWTTestCase) and fully GWT-dependenant. Cheers, Nicolas --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Java source transformation
I'll definitly take a look at GIN. I'm not used with Guice (as I'm a Spring user) but concept is familiar. Any chance to see Google Guice contribute to JSR 299 ? Data binding will be a killer feature when available compared to hand-written PropertyChangeListeners and related boilerplate code. Is there any implementation draft doc somewhere ? Any chance to see a GWT emulation for javax.beans.binding (JSR295) ? 2009/4/20 Arthur Kalmenson arthur.k...@gmail.com With regards to AOP, as Ray mentioned, you might want to check out Google GIN. They haven't yet implemented Interceptors (AFAIK), so you might want to combine efforts with them to get this to work. With regards to data binding, bobv is, AFAIK, working on that feature. If you hold off until it's dropped in the incubator, you could avoid duplicate work. Best regards, -- Arthur Kalmenson On Mon, Apr 20, 2009 at 3:03 AM, nicolas de loof nicolas.del...@gmail.com wrote: What I'm looking for is both some AOP capability and a way to port javaFx bind keyword to Java / GWT. gwt-beans-binding is doing databinding using marker interface in model and wrappers for widgets. This makes impossible to use advanced widgets from 3rd tier librairy without some more code to write. Anyway, thanks a lot for this interesting link. Nicolas 2009/4/20 Ray Cromwell cromwell...@gmail.com GWT generators cannot access the source AST of the original class, only the class metadata (fields/method names, parameters, signatures), no method body stuff. If you're looking to do AOP/Method Interception, I suggest you take a look at Google Gin which is a Guice implementation for Git. It's a dependency injection framework, and you'll only need a single GWT.create() call in the beginning to start the process. You can't 'intercept' classes with regular GWT generators like you can with a classloader if that's what you're trying to do. But with Gin, the dependency injection is transitive, so in effect, you can intercept other classes that appear as injected parameters or fields. -Ray On Sun, Apr 19, 2009 at 11:43 PM, 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) I never tried it myself, but I'n not sure a generator can REPLACE the original Java Source. I may be wrong but I also thing the generated code is only available when using GWT.create(), making the code less testable (with standard junit, not GWTTestCase) and fully GWT-dependenant. Cheers, Nicolas --~--~-~--~~~---~--~~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~--~~~~--~~--~--~---
[gwt-contrib] Re: Java source transformation
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 -~--~~~~--~~--~--~---