From: Renaud P. <ren...@in...> - 2006-02-01 11:23:52
|
Ok, For those how are interested, I've updated the Spoon-AOP home page with=20 what we said here and with some more analysis and performance figures. I=20 have also added the examples in the Spoon CVS. http://www.lifl.fr/~pawlak/spoon-aop/ Best regards, /Renaud Adrian Colyer wrote: > My last post on the subject, and then we should let folks investigate=20 > the good stuff that Spoon offers as you say. >=20 >> Really? Well, I took this example exactly because in AspectJ, you=20 >> cannot access the number of parameters as static information. In=20 >> Spoon-AOP you can. So I can write an advice that says: >> >> if(_argumentCount_=3D=3D0) { do_0 } >> if(_argumentCount_=3D=3D1) { do_1 } >> if(_argumentCount_>=3D2) { do_gte_2 } >> >> And there will be no overhead.=20 >=20 >=20 > You /can/ access the number of parameters as static information using=20 > thisJoinPointStaticPart.getSignature(), but it's not as succint as in=20 > Spoon-AOP: >=20 > int getNumParameters(JoinPoint.StaticPart tjpsp) { > Signature sig =3D tjpsp.getSignature(); > if (sig instanceof CodeSignature) { > return ((CodeSignature)sig).getParameterTypes().length; > } else { > return 0; > } > } >=20 > if we had lots of people asking for easy static access to the number of= =20 > parameters, we could obviously simplify that, but no-one's ever asked a= faik! >=20 > If I needed to implement your example in AspectJ, I'd probably do this: >=20 > before() : args() { > do_0(); > } >=20 > before() : args(*) { > do_1(); > } >=20 > before() : args(*,*,..) { > do_gte_2(); > } >=20 > but I've also never yet needed to write advice that was conditional on=20 > the number of parameters and didn't need access to the parameter values= ... >=20 > Eric described the approach that AspectJ takes to JoinPoint information= =20 > in his post - we build it statically in generated code as this performs= =20 > better than runtime generation using reflection. >=20 > Regards, Adrian. >=20 > Renaud Pawlak wrote: >=20 >> Hi Adrian, >> >> As I said on the Spoon-AOP page, this is on-going work and I need to=20 >> investigate and explain more what it does exactly. For the moment, it=20 >> may seem a little bit "magic" when you do not know about Spoon=20 >> templates and I am sorry about this. I will complete and explain=20 >> better when my time will allow me. >> >> However, I would like to explain myself a little bit better in this=20 >> email and answer some of your questions. >> >>> into spoon itself yet). Your comment on the AspectJ performance is a=20 >>> little misleading.=20 >> >> I am sorry about this, but it is hard to cover all the details of=20 >> things when you want to make a clear point. Here, the code I show=20 >> gives the results I put in my table. Anybody can try it and get the=20 >> same results. I am perfectly aware that this example is a little bit=20 >> biased (like most performance figures), but that's to make my point. >> >>> AspectJ will optimize any use of thisJoinPoint that uses only the=20 >>> "thisJoinPointStaticPart" of the JoinPoint interface.=20 >>> "thisJoinPoint.getArgs()" falls out of that contract, because it=20 >>> returns the actual argument array. The statically knowable subset of=20 >>> join point information can be no different between Spoon-AOP and=20 >>> AspectJ (or any other Java-based AOP implementation). >> >> Really? Well, I took this example exactly because in AspectJ, you=20 >> cannot access the number of parameters as static information. In=20 >> Spoon-AOP you can. So I can write an advice that says: >> >> if(_argumentCount_=3D=3D0) { do_0 } >> if(_argumentCount_=3D=3D1) { do_1 } >> if(_argumentCount_>=3D2) { do_gte_2 } >> >> And there will be no overhead. >> >> Even better, if the number of arguments is 1 for a given joinpoint,=20 >> the woven code will be exactly (partial evaluation): >> >> do_1 >> >> If you want to know all the information that Spoon-AOP can statically=20 >> access, you can refer to the template parameters defined in the Aspect= =20 >> class: http://www.lifl.fr/~pawlak/spoon-aop/javadoc/spoon/aop/Aspect.h= tml >> >> Anyway, in addition to these statically known info about the=20 >> joinpoint, Spoon-AOP is open by using compile-time reflection,=20 >> similarly to Josh:=20 >> http://www.csg.is.titech.ac.jp/paper/chiba-aosd2004.pdf >> >> It means that any aspect can define new static info by introspecting a= =20 >> Java metamodel provided by Spoon at compile time. For example, let's=20 >> say I want to add an information that tells me if a method uses a=20 >> field f, well I can do it with Spoon-AOP (and use it in my advice with= =20 >> no runtime overhead)! >> >>> In AspectJ you can: >>> >>> * implement the example much more efficiently using a pointcut: =20 >>> before() : execution(* ToBeAdvised.*(*,..)) { ... } >> >> I have never seen that before. Does it mean that you capture all the=20 >> methods that have more than zero arguments? Well, in that case, I have= =20 >> to say two things: >> >> - if you want to implement my example, you have to write two pieces of= =20 >> advice (one for the case argCount is 0 and one otherwise). I don't=20 >> think that it is very nice or readable. >> - what if you want to do something special in case there are 3=20 >> arguments (for instance)? >> >>> * in general, bind the contextual information you need explicitly,=20 >>> giving you typed advice and no overhead >> >> Yep, but it will also give you less reusable advice code and pointcuts= =20 >> (LESS reusable aspects in general). Sometimes, you want to perform=20 >> GENERIC actions, with minimal information, but with no overhead. It is= =20 >> most of the time not possible with AspectJ. >> >>> * use thisJoinPointStaticPart (or the static parts of thisJoinPoint,=20 >>> which will be optimised to give the same result) >> >> I'd like too, but sometimes I'd like not. >> >>> * only use the full thisJoinPoint object when you really need runtime= =20 >>> access to the actual this, target, and args objects (and then there=20 >>> are lazyTjp optimizations that will also kick in) >> >> I don't know about this. Is it some kind of partial evaluation? Spoon=20 >> already support partial evaluation during the weaving process. That's=20 >> why it is so fast in my example, without requiring any special JVM=20 >> enhancements. >> >>> The JoinPoint implementation is also not based on java.lang.reflect=20 >>> under the covers (you state otherwise). >> >> Ooops! I will change it, but I would be very interested in knowing=20 >> exactly how it is done then, because I lack time to dive into AspectJ=20 >> sources... Note that java.lang.reflect is very optimized nowadays and=20 >> that's why I assumed that it was use here. I'm surprised. >> >>> In what way do you believe Spoon-AOP is "better typed" than most of=20 >>> the classical AOP approaches? Can you give an example where Spoon-AOP= =20 >>> has stronger typing than an equivalent AspectJ program? >> >> Well, I never said that Spoon-AOP was better-typed that AspectJ.=20 >> Actually, as far as I can tell it is just as well typed. >> >> But, what is interesting here, is that Spoon-AOP is not a new=20 >> language, but a pure Java framework that uses CT-reflection to extends= =20 >> the Java's semantics. So, compared to the framework approaches (JAC,=20 >> JBoss-AOP, Spring...), Spoon-AOP is much better typed. >> >> Also, I think that Spoon-AOP is easier to use than AspectJ for a=20 >> similar type safetyness and better performances. >> >> For instance, with AspectJ, you have to bind the parameters you use=20 >> when you want type safety and performance. With Spoon-AOP, you can do=20 >> it in several ways. For instance to advise this method: >> >> @A >> void m(int i, String s) { ... } >> >> You can write this advice: >> >> @A @Before >> void a(int i,String s) { >> System.out.println("args=3D"+i+","+s); >> } >> >> This is kind of similar to AspectJ where you have to bind the=20 >> parameters explicitly... BUT it is not reusable. Indeed, it is=20 >> efficient but it does not work for any number of parameters. A more=20 >> reusable way of doing it in Spoon-AOP, would be: >> >> @A @Before >> void a() { >> System.out.print("args=3D"); >> if(_argumentCount_>=3D1) >> System.out.print(","+_arguments_[0]); >> if(_argumentCount_>=3D2) >> System.out.print(","+_arguments_[1]); >> if(_argumentCount_>=3D3) >> System.out.print(","+_arguments_[2]); >> System.out.println(); >> } >> >> These look like untyped argument accesses, but actually they are not.=20 >> Indeed _arguments_ does not represent the runtime arguments, but **the= =20 >> compile-time argument accesses**. Then, the compilation phase for the=20 >> woven code will perform the type checking. For instance, with the=20 >> method m(int i, String s), the woven code will be (after partial=20 >> evaluation): >> >> void m(int i, String s) { >> System.out.print("args=3D"); >> System.out.print(","+i); >> System.out.print(","+s); >> System.out.println(); >> ... // original m code >> } >> >> ..., which is more efficient than a reflective version... >> >> (Note that I could also make a foreach loop (finite loop), but my=20 >> partial evaluator does not know how to deal with these yet.) >> >> Whatever, I feel like I said too much already and that nobody will=20 >> read this. Once again, this is ongoing work and I am sure that there=20 >> are still a lot of defects. Also, it will be hard to defend it by=20 >> myself if nobody comes and see what it does exactly... So I'd like to=20 >> encourage anybody that would have some extra time to try it and to=20 >> report on it :) >> >> Cheers, >> /Renaud >> >>> Renaud Pawlak wrote: >>> >>>> Dear all, >>>> >>>> It is my pleasure to announce here the first release of Spoon: a=20 >>>> powerful Java 5 annotation processing tool. >>>> >>>> It is available in Open Source at http://spoon.gforge.inria.fr/ >>>> >>>> Spoon is similar to APT=20 >>>> (http://java.sun.com/j2se/1.5.0/docs/guide/apt/GettingStarted.html)=20 >>>> except that it provides a full metamodel of Java 5 (also models the=20 >>>> Java code in the method bodies) and that it implements compile-time=20 >>>> reflection. So, Spoon can be used for more in-depth and fine-grained= =20 >>>> program transformation and analysis. >>>> >>>> In addition, for specifying the transformations, Spoon allows the=20 >>>> use of pure-Java templates (which can be compared to Velocity=20 >>>> templates except that they are written in Java and, as such,=20 >>>> directly benefit the IDE support for type soundness, navigation, and= =20 >>>> other features). >>>> >>>> Finally, let me point out for you a small application of Spoon: an=20 >>>> original and efficient annotation-driven AOP weaver called=20 >>>> "Spoon-AOP" available at http://www.lifl.fr/~pawlak/spoon-aop/ >>>> >>>> Enjoy! >>>> /Renaud >>>> >>> >>> >>> __________________________________________________ >>> AOSD Discuss mailing list - di...@ao... >>> To unsubscribe go to http://aosd.net >>> >>> Check out the AOSD.net Wiki: http://aosd.net/wiki >>> >> >=20 >=20 >=20 > __________________________________________________ > AOSD Discuss mailing list - di...@ao... > To unsubscribe go to http://aosd.net >=20 > Check out the AOSD.net Wiki: http://aosd.net/wiki >=20 --=20 Renaud Pawlak Researcher INRIA Futurs - Projet JACQUARD LIFL, UMR CNRS 8022, Equipe GOAL - B=E2timent M3 59655 Villeneuve d'Ascq C=E9dex - FRANCE Phone: (+33) 3 28 77 85 79 Cell: (+33) 6 62 00 19 19 Fax: (+33) 3 28 77 85 37 Emails: ren...@in... / pa...@li... WWW: http://www.lifl.fr/~pawlak |