Discussions

News: Implementing IoC with AOP

  1. Implementing IoC with AOP (52 messages)

    Bill Burke has written about how Inversion of Control is a cross-cutting concern. He mocked up how you could use AOP to inject dependencies through constructor and field interception. Holy Loose Coupling batman.

    Excerpt
    I was thinking about Inversion of Control the other day and a thought crossed my mind. Most frameworks out there make you either pre-declare individual instances of your objects through XML or a runtime call, or they make you create your objects through an API. Why should I have to go through an API to lookup my inverted objects? Could IoC itself be a cross-cutting concern? I thought it would be cool if you could inject dependencies whenever an object is created with a "new" rather than going through an API. Here's some stuff I thought up using JBoss AOP.

    Constructor Interception

    A simple example would be to inject an instance of javax.transaction.TransactionManager into any object that needed it through the class's setTransactionManager method. To do this, a simple constructor execution pointcut and advice binding would do the trick:

    <bind pointcut="execution(*->new(..))">
       <interceptor class="TMInjectorInterceptor"/>
    </bind>
    Read more about Implementing IoC with AOP

    Threaded Messages (52)

  2. Field interception is a very elegant way for implementing rubbish like the 1.1 entity beans public fields.

    But I think it's too implicit for injection. I'd prefer a protected getter / public setter pair:

      TransactionManager tm;

      protected TransactionManager getTransactionManager() {
         return tm;
      }
      public void setTransactionManager(TransactionManager tm) {
        this.tm = tm;
      }


    Then I could bind an interceptor to the getter, if I'm running in a AOP environment and use the public setter otherwise. Within in an J2EE container, I could derive a class that overrides the getter, querying the JNDI. Of course, this could be achieved with a special interceptor, too, if there is AOP available in the J2Ee container.

    Holger
  3. Field interception is a very elegant way for implementing rubbish like the 1.1 entity beans public fields.But I think it's too implicit for injection. I'd prefer a protected getter / public setter pair: TransactionManager tm; protected TransactionManager getTransactionManager() { return tm; } public void setTransactionManager(TransactionManager tm) { this.tm = tm; }Then I could bind an interceptor to the getter, if I'm running in a AOP environment and use the public setter otherwise. Within in an J2EE container, I could derive a class that overrides the getter, querying the JNDI. Of course, this could be achieved with a special interceptor, too, if there is AOP available in the J2Ee container.Holger
    JBoss AOP is tightly integrated with our container in JBoss 4 (soon JBoss 3.2 series too). And OF COURSE, it can be run standalone outside, in any environment.

    Personally, I'm leaning toward field interception that is prefaced with a tag as the preferred method to inject:

    @inject private TransactionManager tm;

    get and set would be intercepted. Get, finds the TM. Set throws an exception ("NOT ALLOWED TO SET AN INJECTED FIELD");

    Then again, I'm open for anything.....
  4. Great. I'm also fun of metatags when we speak about AOP. But why not intercept only set method? We will have private field inialized without set method and we will have only get method. Compile time check for setting such variables sound good to me.
    Is't here some AOP framework supporting 1.5 metatags?
  5. @inject private TransactionManager tm;
    I'd prefer that too, but I still need the public setter for non AOP environments.

    Holger Engels
  6. Implementing IoC with AOP[ Go to top ]

    I was thinking about Inversion of Control the other day and a thought crossed my mind. Most frameworks out there make you either pre-declare individual instances of your objects through XML or a runtime call, or they make you create your objects through an API. Why should I have to go through an API to lookup my inverted objects?
    I thought that JBOSS guys love j2ee so they love jndi :)
     Could IoC itself be a cross-cutting concern? I thought it would be cool if you could inject dependencies whenever an object is created with a "new" rather than going through an API.
    There are some IoC frameworks these day which have no API for looking up components. Injection is completely transparent and for the users of the given container it's really irrelevant how does it happen and how it's implemented. BTW: Mid size of popular IoC containers is probably still way smaller then JBOSS AOP framework...

    And how is this going to release you from the need of declaring specfication --> implementaion bindings for components :)
     Here's some stuff I thought up using JBoss AOP. ConstructorInterception
    A simple example would be to inject an instance of javax.transaction.TransactionManager into any object that needed it through the class's setTransactionManager method. To do this, a simple constructor execution pointcut and advice binding would do the trick:[..code..]
    What's the profit out of it?
    Unless you really believe that containers are evil and you
    want to avoid them, you might live with the idea that your components need the container to run and that without it they are useless. And this idea is even
    making stronger requirements for "Component Composer" as AOP and byte code engineering must be really used by any container which will be used to run such component. Which is fine but dependency on container gets even stronger (which is also fine) but (I might be wrong here in my judgment:)) it's quite different from what popular IoC containers (like picco) are offering and promoting and what I think is bit too simple...

    Michal
  7. Implementing IoC with AOP[ Go to top ]

    What's the profit out of it? Unless you really believe that containers are evil and youwant to avoid them, you might live with the idea that your components need the container to run and that without it they are useless.
    The profit isn't to get rid of the container. This isn't an agrument for or against containers, but rather to provide transparent IoC. So that you work with POJOs and not APIs. So that you can just do:

    POJO pojo = new POJO();

    And dependencies get automatically injected.

    This is JBoss's POJO strategy and the same sort of concepts are everywhere in the stuff we're doing. Marc will talk a bunch about it at the TSS Symposium with his "Transparent Middleware" keynote.

    Bill
  8. Implementing IoC with AOP[ Go to top ]

    What's the profit out of it? Unless you really believe that containers are evil and youwant to avoid them, you might live with the idea that your components need the container to run and that without it they are useless.
    The profit isn't to get rid of the container. This isn't an agrument for or against containers, but rather to provide transparent IoC. So that you work with POJOs and not APIs. So that you can just do:POJO pojo = new POJO();And dependencies get automatically injected.
    I think you didn't understand my point. My question was what's the profit of this approach over other approaches used by other IoC containers?

    And my point was that paradoxically this approach is putting stronger requirements over the container and makes it impossible to easily use components implemented accordingly to your idea inside other containers without byte code manipulation.

    The container, which I am using, and I have contributed to (plexus) have a capability of running components written for different APIs (plexus-native, avalon, spring, soon also picco). Each of them has its particularities but none of them __by design___ is requiring things like AOP for such an elementary stuff like dependency injection. I honsetly think that this simply would be overkill in case of them. I am also big fan of AOP but I feel that many neophytes to AOP simply overuse it or are not using it properly. The same applies to OOP – if you don’t have an experience of 1-2 years you know nothing about.
    This is JBoss's POJO strategy and the same sort of concepts are everywhere in the stuff we're doing.
    Marc will talk a bunch about it at the TSS Symposium with his "Transparent Middleware" keynote.Bill
    journey diaries from the early days of the trip?

    Michal
  9. Implementing IoC with AOP[ Go to top ]

    Michal,

    You're sounding kind of bitter. Where can we read up on plexus?
    Thanks,

    Steve
  10. Plexus[ Go to top ]

    http://plexus.codehaus.org/
  11. Implementing IoC with AOP[ Go to top ]

    is requiring things like AOP for such an elementary stuff like dependency injection.
    Agreed. AOP is powerful ( kind of macroses on steroids ) and easily can and will be abused. There is nothing wrong with coding to an API, and I would say that is preferable approach because API is supposedly a result of efforts of not-so-stupid developer(s). There is no guarantee whatsoever that a developer will come up with something better than other guys, quite contrary an average developer will produce something stupid.

    I would say that AOP somehow promotes wheel reinvention as a side effect.
  12. Implementing IoC with AOP[ Go to top ]

    AOP is powerful ( kind of macroses on steroids ) and easily can and will be abused.
    I would say AOP is sort of like macros done safely. As everything it could be abused, but I think it can be abused to a lesser extent than macros can (and I speak from experience, I've worked professionally for two years with Common Lisp). By making the AspectJ compiler more "pedantic" I think it would be possible to achieve a safety level completely acceptable for mainstream usage. For example AspectJ could signal an error if a pointcut does not catch anything, or even completely disallow wildcards in pointcuts (I'm not sure, but I think you never really need them).
  13. Implementing IoC with AOP[ Go to top ]

    By making the AspectJ compiler more "pedantic" I think it would be possible to achieve a safety level completely acceptable for mainstream usage.
    I do not think that AOP is safer than C++ macroses/templates ( cannot speak for Lisp ) and AOP even looks more obscure for me.
    IMO: Support from AspectJ( or other aspect compiler) is far from being enough.
     There is an ultimate need for an IDE that will treat AO stuff as first class language citizens and provide the same level of support as IDEA provides for Java. Without such support it will be very difficult to develop with AOP in a decent project.
  14. Abuse me[ Go to top ]

    AOP is powerful ( kind of macroses on steroids ) and easily can and will be abused.
    I disagree on the analogy that AOP is macros on steroids.

    Like any technology you can abuse it. That's why I think the biggest bang of AOP will come to framework developers such as ourselves. AOP provides such a unique way of packaging our services to users as to make our frameworks very transparent and easy to use.
    IMO: Support from AspectJ( or other aspect compiler) is far from being enough. There is an ultimate need for an IDE that will treat AO stuff as first class language citizens and provide the same level of support as IDEA provides for Java. Without such support it will be very difficult to develop with AOP in a decent project.
    I fully agree on this topic. IDE support is a must as you need to know exactly who is affected by a particular pointcut expression.

    One thing that helps all this abuse is defining an API between your aspects and your aspectized POJOs. I think annotations are a perfect match with AOP in many situations. (BTW annotations + AOP IS a good analogy of macros on steroids). It gives you a typed way to trigger and apply your aspects to your application. Clearly any future IDE will at least support annotations well...

    Bill
  15. Abuse me[ Go to top ]

    I disagree on the analogy that AOP is macros on steroids.
    Lets compare:
    C/C++ Macros: gets replaced by piece of code during textual preprocessing, which is analogous to AOP compile step. AOP of course goes further and can do much more and at runtime too, but in the essence AOP and macroses are very similar.

    Aspects can be applied to code even without explicit annotation or mentioning in source code that makes them very obscure (but powerful), however it does not alter their macro-like functionality, so the demand for IDE support.
  16. Abuse me[ Go to top ]

    I disagree on the analogy that AOP is macros on steroids.
    Lets compare: C/C++ Macros: gets replaced by piece of code during textual preprocessing, which is analogous to AOP compile step. AOP of course goes further and can do much more and at runtime too, but in the essence AOP and macroses are very similar.Aspects can be applied to code even without explicit annotation or mentioning in source code that makes them very obscure (but powerful), however it does not alter their macro-like functionality, so the demand for IDE support.
    Yes, I'm very familiar with C/C++ macros as I was one for years before Java. There is a huge difference as these macros are not encapsulated, nor are they typed. Macros are inlined as part of your source, where aspects are compiled like any other java source file. Macros in C/C++ are a source level construct done through a preprocessor. Very simple replacement. Very different. Aspects can be applied outside the scope of your java source while macros are declared as part of the source. Again, very different.

    But I agree, IDE support is a must.

    Bill
  17. Macros and AOP[ Go to top ]

    I have to agree with you on this one Bill (is the earth suddenly shaking really hard or is it just me?).

    C++ and C macros are very, very simplistic simple text substitutions. I mean really simplistic. The C and C++ standards are written in such a way that:

      
          
    • The macro processor can run as a stand alone literal preprocessor
    •     
    • The macro processor has close to 0 knowledge of C or C++ syntax or semantics
    •   
    When I say "close to 0 knowledge", what that means is that the preprocessor knows a couple of extremely primitive syntax points, but knows nothing about program structure, semantics, or even most of the syntax rules.

    Even if you want to compare to a more sane macro system, it still doesn't hold. Macros are purposefully invoked within your source code. The entire point of AOP is quite different - to specifically _not_ include the aspect code.

    A template argument likewise doesn't really hold, for the same reason as macros, unless the only point is to talk about complexity. And even there it's a murky analogy.

    Macros are insidious not because of complexity, but because they're too simple, too dumb and literal minded. All of their problems stem from the fact that it's nothing more than literal text substitution.

    C++ templates are insidious because the syntax is hideously deformed, and because the C++ template rules introduce very subtle semantics that catch even veteran C++ programmers. Using templates can be reasonably painless to an extent if they're very well fritten, but writing them is pretty much always a bear.

    With AOP, the real problems are:
        
    • It's not necesarily easy to know what a pointcut is going to match.
    •   
    • As a corollary, when looking at a piece of code you may not be aware that a pointcut is active against it
    •   
    • In most AOP systems it's so easy to write a pointcut that a certain class of people will be encouraged to go hog while and create an explosion of unnecessary pointcuts and aspects.
    •   
    • Many AOP features are, by their nature, very facile at circumventing a pre-existing design. Intercepting calls in various means via pointcuts, introducing code via advice - these features can be used to hack new functionality onto a pre-existing design in a very, very ugly manner. Put another way AOP represents an easy out for many people - a substitute for a good design, if you will.
    By my way of thinking, in the long term AOP will be a second-string player in the developer's playbook (how's that for subtly mixing metaphors :-). It will be very much like implementation inheritance - a very useful thing but not something to be overdone. It should not, in my opinion, be something as fundamental, pervasive, and used repeatedly like variables, methods, classes, and use of interfaces and interface inhertiance.

    In my mind, the last bit is the real yardstick of a new technique or language feature - compare it to Java variables, methods, classes, interfaces, and how they are used (and explicitly excluding implementation inheritance aka extends). If a feature is as universally applicable to many coding problems as, say, an interface - or the lowly variable or method - then you're onto something. AOP doesn't meet that criteria, it's not (or perhaps I should say, should not) be as pervasive in use as classes and methods and variables and interfaces.

    As a counterpoint, consider closures (in particular, closures a la groovy). Closures in my mind are right up there with variables and methods and classes and interfaces in their universal applicability. They could be widely used on a day-to-day coding basis by people. AOP in my mind doesn't reach that level of applicability. And attempts to reach that kind of applicability with it will lead to heartaches that outweigh the benefits.

        -Mike
  18. Macros and AOP[ Go to top ]

    I agree with a lot of your points about AOP, but I think your points are very situational and cannot be used to generalize the entire AOP paradigm. Let me explain.
    With AOP, the real problems are:
    • It's not necesarily easy to know what a pointcut is going to match.
    I've said this before, this is definately a probelm with AOP. You need an IDE. You need a good AOP precompiler that can analyse the application of your aspects. An additonal thing that I belive can help greatly is the combination of annotations and AOPs. It gives you a typed way of applying your aspects in a non-oblivious way. The annotation approach is useful in many ways (i.e. transaction demarcation) and not useful in others (i.e. security boundaries).
    • As a corollary, when looking at a piece of code you may not be aware that a pointcut is active against it
    • In most AOP systems it's so easy to write a pointcut that a certain class of people will be encouraged to go hog while and create an explosion of unnecessary pointcuts and aspects.
    • Many AOP features are, by their nature, very facile at circumventing a pre-existing design. Intercepting calls in various means via pointcuts, introducing code via advice - these features can be used to hack new functionality onto a pre-existing design in a very, very ugly manner. Put another way AOP represents an easy out for many people - a substitute for a good design, if you will.
    These statements are all similar so I will address them in one place. Much of this obliviousness that AOP can inject is desired and prevelant in OOP and OOP based frameworks. Take a factory for instance. Use a factory and your code is oblivious to the fact of what object is REALLY being allocated. EJBs are oblivious to transaction demarcation and security. Persistence frameworks hide what JDBC calls are being made, etc.

    The points you make are all part of the evolution of AOP. We are all learning the best way to apply this new paradigm. Vincent Massol wrote a nice article on investigating how AOP helps with testing. Dion and the atrack guys as well as ourselves at JBoss are investing how AOP helps with middleware.

    I think the evolution of AOP will be as follows:
    1. It will be used most successfully at first by framework developers such as ourselves in providing new and powerful ways to apply and snap on their technologies.
    2. ISVs will start will start to identify predefined and prepackaged pointcuts into their systems. JBoss has done this. BEA has done this. AOP is a perfect implementor of the Observer/Observable pattern and this pattern is perfect for integration work. I've Blogged abou this before.
    3. Many projects will fail miserably AOP.
    4. After many successes and failures of points 1-3, patterns and methodologies will emerge after the dust settles.
    5. Go back 10, 15 years, and this evolution sounds very similar to OOP.
    By my way of thinking, in the long term AOP will be a second-string player in the developer's playbook
    I totally agree with this statement. An interesting AOP presentation at AOSD had a slide stating that OOP solves 80-90% of problems and AOP solves the 10-20% of problems that OOP isn't good at.
    (how's that for subtly mixing metaphors :-).
    You are just so clever.
    It will be very much like implementation inheritance - a very useful thing but not something to be overdone. It should not, in my opinion, be something as fundamental, pervasive, and used repeatedly like variables, methods, classes, and use of interfaces and interface inhertiance. In my mind, the last bit is the real yardstick of a new technique or language feature - compare it to Java variables, methods, classes, interfaces, and how they are used (and explicitly excluding implementation inheritance aka extends). If a feature is as universally applicable to many coding problems as, say, an interface - or the lowly variable or method - then you're onto something. AOP doesn't meet that criteria, it's not (or perhaps I should say, should not) be as pervasive in use as classes and methods and variables and interfaces.As a counterpoint, consider closures (in particular, closures a la groovy). Closures in my mind are right up there with variables and methods and classes and interfaces in their universal applicability. They could be widely used on a day-to-day coding basis by people. AOP in my mind doesn't reach that level of applicability. And attempts to reach that kind of applicability with it will lead to heartaches that outweigh the benefits. -Mike
    Again, I agree, see above, but just because it only solves a subset a problems doesn't mean we should just so trivially dismiss it as a bad idea. If this is not your intent, then I apologize.

    Bill
  19. Macros and AOP[ Go to top ]

    Bill Burke: 3. Many projects will fail miserably AOP.

    I think this will be a very true expectation. Most developers should avoid it unless they really know what they're doing. The lead designer/developer should be aware and in control of whatever AOP gets put into the system. We just started using Hibernate, which is great, but I don't see us using AOP anytime in the near future.

    I'm very excited about what AOP will allow framework/container developers to do, tough. POJO/J3EE/Whatever you want to call it is going to be a lot of fun, and I can't wait.

    Steve
  20. Macros and AOP[ Go to top ]

    Bill:
    Many projects will fail miserably AOP.
    Steve:
    Most developers should avoid it unless they really know what they're doing.
    This suggests the invention of a new skill.
  21. Macros and AOP[ Go to top ]

    I've said this before, this is definately a probelm with AOP. You need an IDE. You need a good AOP precompiler that can analyse the application of your aspects. An additonal thing that I belive can help greatly is the combination of annotations and AOPs. It gives you a typed way of applying your aspects in a non-oblivious way. The annotation approach is useful in many ways (i.e. transaction demarcation) and not useful in others (i.e. security boundaries).
    Yes, it can be managed in the ways you indicate. But it still should be listed as an issue that people should be aware of. It's an indicator that as AOP grows it needs to be managed carefully and you shouldn't go too nuts with it - just like with too much implementation inheritance. Even with annotations this is still true.
    These statements are all similar so I will address them in one place. Much of this obliviousness that AOP can inject is desired and prevelant in OOP and OOP based frameworks. Take a factory for instance. Use a factory and your code is oblivious to the fact of what object is REALLY being allocated. EJBs are oblivious to transaction demarcation and security. Persistence frameworks hide what JDBC calls are being made, etc.

    The points you make are all part of the evolution of AOP. We are all learning the best way to apply this new paradigm. Vincent Massol wrote a nice article on investigating how AOP helps with testing. Dion and the atrack guys as well as ourselves at JBoss are investing how AOP helps with middleware.
    Yep, agreed. In pointing these out I wasn't trying to state that they indicate that AOP is bad. Rather, I was showing that it's not a no brainer and there is potential for abuse that should be watched - and that the abuse mechanism in this case is rather novel compared to ones that people are familiar with today.

    When a novel technology just starts to come into common practice, there seems to inevitably be a cycle that has been repeated from time immemorial:

      - Early adopters experimenting all over the map
      - Said early adopters writing optimistic and enthusiastic articles about it
      - "The masses" start to adopt based on the early adopter's enthusisasm.
      - Early results are good, because people always start small and they benefit from the "low hanging fruit".
      - Over time, usage grows, complexity in usage grows, people start to see the downsides
      - As more time goes by, people will write books like "Bitter AOP" and "Pragmatic AOP" and "AOP Sucks - The Case for Procedural Programming" :-)
      - A few people will note that the gist of these books are issues that were obvious early on to the early adopters, but were suppressed and/or ignored due to undue enthusiasm or an unconscious need to suppress negative comments

    It could truly be said that unbridled enthusiasm is the mechanism of positive change in the industry, and also the source of its biggest problems.
    I think the evolution of AOP will be as follows:
    [...]
    Yeah, similar to the cycle I described, but obviously from a different viewpoint :-). You imply that when a new technology emerges people _must_ struggle through with it, usually for years, before it settles down. I do not believe that to be the case. If you have a critical mind and general software development experience, you can analyze AOP today and get a pretty good idea of its pros and cons. You may not see it all - few people are that good - but you can see most of it. The problem is that the early adopters emphasize the positives and actively work to suppress the negatives in their enthusiasm, and this is the true source of the cycle that you describe. If enough key early adopters approach the topic with a small dose of pragmatism IMHO this sort of cycle can be largely avoided.

    The Pros and Cons of AOP are clear enough today that both sides can be examined. We don't have to wait 3 or 5 or 7 years for a "Bitter AOP" book, we can write the chapters right now.

        -Mike
  22. Macros and AOP[ Go to top ]

    The problem is that the early adopters emphasize the positives and actively work to suppress the negatives in their enthusiasm, and this is the true source of the cycle that you describe.
    This was what I was trying to say before. AOPs first successes will be with framework developers such as ourselves. The users of the framework won't even know that AOP was used to implement the framework, just that they're using powerful transparent middleware.
    If enough key early adopters approach the topic with a small dose of pragmatism IMHO this sort of cycle can be largely avoided.The Pros and Cons of AOP are clear enough today that both sides can be examined. We don't have to wait 3 or 5 or 7 years for a "Bitter AOP" book, we can write the chapters right now. -Mike
    I'm sure you'll be the one to write the "Bitter AOP" book. I'll write "AOP for (and by) dummies", and of course, Rickard will write "AOP for Aliens".

    Bill
  23. Implementing IoC with AOP[ Go to top ]

    For example AspectJ could signal an error if a pointcut does not catch anything, or even completely disallow wildcards in pointcuts (I'm not sure, but I think you never really need them).
    If you're using JBoss AOP in compile-time mode, it has a -report switch on the aopc compiler which will give an XML dump of all pointcuts and advice bindings and where they are applied. There is also an "Unbound Bindings" category which shows bindings that are not bound at all. This is useful for debugging when you have erroneous pointcut expressions.

    If you're using JBoss AOP within JBoss microkernel with Tomcat, you can use our management console to get a graphical view of this information through a tree widget:

    See more information here: JBoss AOP Debugging and Analysis Tools

    Bill
  24. And my point was that paradoxically this approach is putting stronger requirements over the container and makes it impossible to easily use components implemented accordingly to your idea inside other containers without byte code manipulation.
    But arent' these components just POJO's or at most JavaBeans, completely agnostic about the container, it's wirings and whatever? You should be able to take the same component deployed in JBoss4, and use it on Spring, Pico, or any other container, as long as they dont depend on the container's API. BTW, this is one advantage of not using the container's API for component wiring.

    Regards,
    Henrique Steckelberg
  25. And my point was that paradoxically this approach is putting stronger requirements over the container and makes it impossible to easily use components implemented accordingly to your idea inside other containers without byte code manipulation.
    But arent' these components just POJO's or at most JavaBeans, completely agnostic about the container, it's wirings and whatever? You should be able to take the same component deployed in JBoss4, and use it on Spring, Pico, or any other container, as long as they dont depend on the container's
    There is no such thing like container API. There is always an API supported by container and by components. Any container can support as many APIs as you wish. For example it'a possible to have a container which will be able to run EJBs and picco components together (idea is rather stupid but technically speaking it's possible). And my point was that Bill's idea was defining the API (which is a contract which both container(s) and components must implement)
    which is requiering AOP techniques. It means that is somebody would use such components inside (for example) spring container, spring container will be required to use AOP for "wireing" them together.
    I am not judging this solution. I just made an observation regarding some of its implications.
    API. BTW, this is one advantage of not using the container's API for component wiring.Regards,Henrique Steckelberg
    Maybe it's an advantage maybe not ... it depends on your point of view. And yes Bill's idea is defining API which makes it much harder
    to easly run such components inside other containers. And there is nothing wrong with it. It's just a feature of this solution.

    Michal
  26. Implementing IoC with AOP[ Go to top ]

    And my point was that Bill's idea was defining the API (which is a contract which both container(s) and components must implement)which is requiering AOP techniques.
    One of the points with IoC with AOP is that you do not have to have a contract between your container and component. The field interception example I gave is a perfect example. You could tailor your injections per class with different aspects.
    And yes Bill's idea is defining API which makes it much harderto easly run such components inside other containers. And there is nothing wrong with it. It's just a feature of this solution. Michal
    Please explain exactly how IoC with AOP makes it harder to easily run such components inside other containers? JBoss AOP runs outside of the JBoss container and inside the jboss container. It would work with Pico/Spring, without Pico/Spring. I fail to see your point.

    Bill
  27. Implementing IoC with AOP[ Go to top ]

    And my point was that Bill's idea was defining the API (which is a contract which both container(s) and components must implement)which is requiering AOP techniques.
    One of the points with IoC with AOP is that you do not have to have a contract between your container and component. The field interception example I gave is a perfect example.
    It's not the "strong point" of IoC with AOP. Every other containers which supports this kind of IoC which we are talking about is doing it very well without AOP. Simply AOP is not helping at all to implement this particular aspect of the container. The same thing implemented without AOP is as simple or even more simple then AOP based implementation.
    You could tailor your injections per class with different aspects.
    And yes Bill's idea is defining API which makes it much harderto easly run such components inside other containers. And there is nothing wrong with it. It's just a feature of this solution. Michal
    Please explain exactly how IoC with AOP makes it harder to easily run such components inside other containers? JBoss AOP runs outside of the JBoss container and inside the jboss container. It would work with Pico/Spring, without Pico/Spring. I fail to see your point.Bill
    It is harder to use such components in other containers simply becouse those containers _are_ required to use byte code engeering for componet composition. The code which injects dependencies to components in any of "traditional" ways doesn't have to be longer then 100 lines of code (1 KB of compiled code) and is super simple. Small IoC containers have much less then 1 MB of full size and most likely it's not impossible to use them in devices like mobile phones. JBoss AOP framework (and most of the others framworks) will at the best case double this size. And I don't see any profits in your idea over setter injection, contructor injecton or field injection.


    Michal
  28. Implementing IoC with AOP[ Go to top ]

    And my point was that Bill's idea was defining the API (which is a contract which both container(s) and components must implement)which is requiering AOP techniques.
    One of the points with IoC with AOP is that you do not have to have a contract between your container and component. The field interception example I gave is a perfect example.
    It's not the "strong point" of IoC with AOP. Every other containers which supports this kind of IoC which we are talking about is doing it very well without AOP. Simply AOP is not helping at all to implement this particular aspect of the container. The same thing implemented without AOP is as simple or even more simple then AOP based implementation.
    You could tailor your injections per class with different aspects.
    And yes Bill's idea is defining API which makes it much harderto easly run such components inside other containers. And there is nothing wrong with it. It's just a feature of this solution. Michal
    Please explain exactly how IoC with AOP makes it harder to easily run such components inside other containers? JBoss AOP runs outside of the JBoss container and inside the jboss container. It would work with Pico/Spring, without Pico/Spring. I fail to see your point.Bill
    It is harder to use such components in other containers simply becouse those containers _are_ required to use byte code engeering for componet composition. The code which injects dependencies to components in any of "traditional" ways doesn't have to be longer then 100 lines of code (1 KB of compiled code) and is super simple. Small IoC containers have much less then 1 MB of full size and most likely it's not impossible to use them in devices like mobile phones. JBoss AOP framework (and most of the others framworks) will at the best case double this size. And I don't see any profits in your idea over setter injection, contructor injecton or field injection.


    Michal
  29. Michael, I think you are not getting things right here: the components don't know _anything_ about how they are being wired, they don't depend on the container, they are completely container agnostic. You can take the exact same components and deploy them on Pico, Spring or JBoss AOP, and they should all work, without having to change anything in the containers code at all. The only difference between the 3 deployment schemas will be the deployment descriptor files (XML or whatever), which are unique to each container, and not expected to be portable anyway. So your concept that AOP would make components harder to deploy is not an issue actually, the components _are_ portable between IoC containers, no matter if they use a pure java API approach or AOP or C code + JNI to wire them; and each container can use whatever IoC mechanism they want, regardless of other container's chosen mechanism.

    BTW: wouldn't it be time now that these non-portable descriptor files should be "standardized" for light frameworks (J3EE), following the "innovate-standardize" cycle so many propose these days, or is it too early for that?

    Regards,
    Henrique Steckelberg
  30. Michael, I think you are not getting things right here: the components don't know _anything_ about how they are being wired, they don't depend on the container, they are completely container agnostic.
    Its true that componenst are always container agnostic.
    But it is ceratainly not true that components don't know how their dependencies will be injected. This is the part of the API to which both componet and container must conform.


    If you have


    class Foo()
    {
       public Foo( Baa baa, Gaa gaa );
    }



    class Foo()
    {
       private Baa baa;
       private Gaa gaa;
    }


    or

    class Foo()
    {
       public void setBaa( Baa baa);
       public void setGaa( Gaa gaa);
    }


    or (what Bill is prpposing)

    class Foo
    {
       void some_method()
       {
            baa = new Baa();
       }
    }


    Those are cleary 4 different contracts (for both containers and components) and always you are making assumptions how the things will work.
     You can take the exact same components and deploy them on Pico, Spring or JBoss AOP, and they should all work, without having to change anything in the containers code at all. The only difference between the 3 deployment schemas will be the deployment descriptor files (XML or whatever), which are unique to each container, and not expected to be portable anyway. So your concept that AOP would make components harder to deploy is not an issue actually, the components _are_ portable between IoC containers, no matter if they use a pure java API approach or AOP or C code + JNI to wire them; and each container can use whatever IoC mechanism they want, regardless of other container's chosen mechanism.BTW: wouldn't it be time now that these non-portable descriptor files should be "standardized" for light frameworks (J3EE), following the "innovate-standardize" cycle so many propose these days, or is it too early for that?Regards,Henrique Steckelberg
    My only point was that if you __explicity_ require AOP or JNI for "wiring" components it makes the contract which must be implemented by any of those containers much more strict and difficult. Setter based dependency injection is much easier to implement then the fourth of the presented contracts. This contract is: container will manipualte the byte code of the component to inject dependencies. There is nothing in this contract per se if it will be implemented with AOP or not. The contract for Setter Dependecy Injection (called also IoC type 2) just states that your dependencies will be injected via setter methods. Isn't it less demending? It can be implement within 2 hours by avg. developer.
    I am not saying that AOP based dependecy injection is something super hard or impossiblt to implement. If you are using "fat" frameworks like JBoss-AOP or some better and proven alternatives like AspectJ it is actually quite easy to implement it.

    Michal
  31. Michael, I think you can implement any type of IoC with AOP: for example, you could set an interceptor for any getXxxx(..) method, and create any wiring for the required component being returned by such method by means of AOP, the moment the method is called. The dependencies will be injected by means of get and set methods the same way Type 2 IoC does, so the contract for both implementations are the same, thus the components would be portable between AOP and non-AOP containers. The example Bill gave, using new Pojo(), was just an way of doing it, AFAIK it can be done exactly like Pico or Spring works now, but using AOP instead:

    <bind pointcut="execution(*->getTM(..))">
       <interceptor class="TMInjectorInterceptor"/>
    </bind>

    Regards,
    Henrique Steckelberg
  32. Michael,


    I am not Michael :)
    I think you can implement any type of IoC with AOP: for example, you could set an interceptor for any getXxxx(..) method, and create any wiring for the required component being returned by such method by means of AOP, the moment the method is called. The dependencies will be injected by means of get and set methods the same way Type 2 IoC does, so the contract for both implementations are the same, thus the components would be portable between AOP and non-AOP containers. The example Bill gave, using new Pojo(), was just an way of doing it, AFAIK it can be done exactly like Pico or Spring works now, but using AOP instead:<bind pointcut="execution(*->getTM(..))"> <interceptor class="TMInjectorInterceptor"/></bind>Regards,Henrique Steckelberg
    You can implement anything you want with AOP. IoC type 2 or even IoC type 1.
    The nice thing about it is that you have a freedom to choose how it will be implemented and if AOP will be used or not. My point was that the type of IoC proposed by Bill was taking away this choice from you. Again it is perfectly OK to do this. My only intention in this thread was to make an observation about this implication :)


    Michal
  33. I am not Michael :)
    Oops, sorry! :) Must remember to not type faster than I can think... ;)
  34. Implementing IoC with AOP[ Go to top ]

    Michael, I think you are not getting things right here: the components don't know _anything_ about how they are being wired, they don't depend on the container, they are completely container agnostic.
    Its true that componenst are always container agnostic. But it is ceratainly not true that components don't know how their dependencies will be injected. This is the part of the API to which both componet and container must conform.If you haveclass Foo(){ public Foo( Baa baa, Gaa gaa );}class Foo(){ private Baa baa; private Gaa gaa;}orclass Foo(){ public void setBaa( Baa baa); public void setGaa( Gaa gaa);}or (what Bill is prpposing)class Foo{ void some_method() { baa = new Baa(); }}
    Again and again and again I will repeat myself. AOP does not require a contract between the container and the component. You can inject dependencies on ANY class whatsoever and even within different contextual situations.

    What it does require is a contract between the aspect and the container. All four of the methods you described above could be implemented with any simple aspect and not even require a container!
    Those are cleary 4 different contracts (for both containers and components) and always you are making assumptions how the things will work.
    Again, no contract is required with AOP. You could inject dependencies on an existing object model that wasn't even designed to use a traditional IoC container.
    You can take the exact same components and deploy them on Pico, Spring or JBoss AOP, and they should all work, without having to change anything in the containers code at all. The only difference between the 3 deployment schemas will be the deployment descriptor files (XML or whatever), which are unique to each container, and not expected to be portable anyway. So your concept that AOP would make components harder to deploy is not an issue actually, the components _are_ portable between IoC containers, no matter if they use a pure java API approach or AOP or C code + JNI to wire them; and each container can use whatever IoC mechanism they want, regardless of other container's chosen mechanism.BTW: wouldn't it be time now that these non-portable descriptor files should be "standardized" for light frameworks (J3EE), following the "innovate-standardize" cycle so many propose these days, or is it too early for that?Regards,Henrique Steckelberg
    My only point was that if you __explicity_ require AOP or JNI for "wiring" components it makes the contract which must be implemented by any of those containers much more strict and difficult. Setter based dependency injection is much easier to implement then the fourth of the presented contracts. This contract is: container will manipualte the byte code of the component to inject dependencies. There is nothing in this contract per se if it will be implemented with AOP or not. The contract for Setter Dependecy Injection (called also IoC type 2) just states that your dependencies will be injected via setter methods. Isn't it less demending? It can be implement within 2 hours by avg. developer.I am not saying that AOP based dependecy injection is something super hard or impossiblt to implement. If you are using "fat" frameworks like JBoss-AOP or some better and proven alternatives like AspectJ it is actually quite easy to implement it.Michal
    Actually, it is very easy to implement dependency injection with "phat" JBoss AOP or with AspectJ, you are correct. You say IoC type 2 requires setter methods for dependency injection. You could use the same exact contract with AOP, except, with AOP you can do:

    POJO pojo = new POJO();

    And your dependencies will be injected. While with a traditional OOP IoC container you would have to do:

    POJO pojo = (POJO)IocContainer.create(POJO.class);

    or something like that.

    Now, could a traditional IoC container to context aware dependency injection? Like for example, if I'm allocating this object within the context of a transaction, I want different dependencies injected. Or, if I'm allocating this object within this method of a different class, I want different dependencies injected. THis is where you could do some interesting IoC.

    Bill
  35. Implementing IoC with AOP[ Go to top ]

    Again and again and again I will repeat myself. AOP does not require a contract between the container and the component. You can inject dependencies on ANY class whatsoever and even within different contextual situations.
    Sorry but I don't understand your sentence: "AOP does not require a contract between the container and the component."

    AOP like OOP is just a tool/methodology which can be used for implementing any contract. You will differetly advice picco components and diffetly spring components and diffrently avalon components. It's true that with AOP + sufficient metadata you can quickly support any of those contracts and you can even have separate contract for each component which are deployed into your container Contract is nothing more in this case then a hint how dependencies should be injected.

    But if I will send by email you an arbitrary component (POJO) you won't be able to use AOP to inject its dependencies without the knowledge of how it is implemented and how those dependencies should be injected.


    Michal
  36. Implementing IoC with AOP[ Go to top ]

    Again and again and again I will repeat myself. AOP does not require a contract between the container and the component. You can inject dependencies on ANY class whatsoever and even within different contextual situations.
    Sorry but I don't understand your sentence: "AOP does not require a contract between the container and the component."
    The whole point of IoC+AOP is to absolve the POJOs of any a-priori contract. An aspect acts as a patch that can be transparently applied, perhaps after POJO development ceased.
  37. Implementing IoC with AOP[ Go to top ]

    The whole point of IoC+AOP is to absolve the POJOs of any a-priori contract. An aspect acts as a patch that can be transparently applied, perhaps after POJO development ceased.
    But contracts still must be known for all components (pojos), don't they?
    AOP can just help (not always) to implement those contracts in a simpler way.


    Michal
  38. Implementing IoC with AOP[ Go to top ]

    But contracts still must be known for all components (pojos), don't they?
    Imagine an instance field persistence service. The container takes any POJO instance and writes it's public fields to a property file whenever a field's value changes. The POJO might have been developed without apriori awareness of any contract, and the container service would still work.
  39. Implementing IoC with AOP[ Go to top ]

    This isn't an agrument for or against containers, but rather to provide transparent IoC. So that you work with POJOs and not APIs. So that you can just do:POJO pojo = new POJO();And dependencies get automatically injected.
    I believe this is colloquially known as J3EE.
  40. Implementing IoC with AOP[ Go to top ]

    So that you can just do:

    POJO pojo = new POJO();

    And dependencies get automatically injected.
    That's great, but it's still nice to declare dependencies explicitly in the constructor for unit testing. I.e:

    POJO pojo = new POJO(mockDependency);

    I don't want to muck around with AOP in a unit test. If the only public constructor(s) declare the dependencies, then everything is nice an explicit.
  41. Virtual Mocks with AOP[ Go to top ]

    We could get radical and you could use Virtual Mocks using AOP.... so the mocking would occur as if by magic!

    "if the method is within the flow of a TestCase class with a test*() method... use the mock my friend!"

    :)
  42. Virtual Mocks with AOP[ Go to top ]

    We could get radical and you could use Virtual Mocks using AOP.... so the mocking would occur as if by magic! "if the method is within the flow of a TestCase class with a test*() method... use the mock my friend!":)
    You hit it exactly Dion. The thing is, with AOP, your objects don't give a crap where they're getting their injections from and you can hook any mechanism you want. AOP gives you more freedom.

    Bill
  43. Virtual Mocks with AOP[ Go to top ]

    Yeah, that'd be cool and all, but hardly explicit. I mean, a combination of hash maps and function pointers would give me total freedom too, why mess with explicit method and property names. Much more flexible, much more freedom, right?

    I assumed Dion was begin sarcastic. Yeah, it would work, but magic is hardly clear or explicit.

    In a unit test, I want to explicitly configure and pass in the mock. You often don't just have one mock class; often different ones for different tests. (Often the mocks are dynamically generated using dynamic proxies; an AOP framework would be great for that.) So it's desirable to have dependencies explicitly specified as constructor arguments. I don't want magic in a unit test; I want something simple and clear to debug.

    I don't know, maybe dependencies could be explicitly specified as attributes or some such. Doesn't seem much better or worse.

    Of course you could use AOP to do constructor dependency injection. Wouldn't be any better or worse than using a DI container I guess; just an implementation / configuration detail.
  44. Virtual Mocks with AOP[ Go to top ]

    Yeah, that'd be cool and all, but hardly explicit. I mean, a combination of hash maps and function pointers would give me total freedom too, why mess with explicit method and property names. Much more flexible, much more freedom, right? I assumed Dion was begin sarcastic. Yeah, it would work, but magic is hardly clear or explicit.In a unit test, I want to explicitly configure and pass in the mock. You often don't just have one mock class; often different ones for different tests. (Often the mocks are dynamically generated using dynamic proxies; an AOP framework would be great for that.) So it's desirable to have dependencies explicitly specified as constructor arguments. I don't want magic in a unit test; I want something simple and clear to debug.I don't know, maybe dependencies could be explicitly specified as attributes or some such. Doesn't seem much better or worse.Of course you could use AOP to do constructor dependency injection. Wouldn't be any better or worse than using a DI container I guess; just an implementation / configuration detail.
    I hope I am responding correctly to you, but, a key difference between JBoss AOP and let's say something like AspectJ, is that JBoss AOP aspects are applied at deployment time, and can be redeployed, undeployed at runtime. So if you have different mock objects in different situations, you could easily swap in and swap out different mock strategies.

    You talk about magic. IoC is magic in and of itself. The POJOs don't know how their dependencies are being injected no matter if you use a traditional OOP dependency injector or AOP.

    I think AOP gives you greater flexibility to do depency injection as you can do context based dependency injection with call side pointcut expressions or control flows. But I do agree with you on one point: It really largely is an implementation detail.

    Bill
  45. Virtual Mocks with AOP[ Go to top ]

    ...a key difference between JBoss AOP and let's say something like AspectJ, is that JBoss AOP aspects are applied at deployment time, and can be redeployed, undeployed at runtime. So if you have different mock objects in different situations, you could easily swap in and swap out different mock strategies. You talk about magic. IoC is magic in and of itself. The POJOs don't know how their dependencies are being injected no matter if you use a traditional OOP dependency injector or AOP.I think AOP gives you greater flexibility to do depency injection as you can do context based dependency injection with call side pointcut expressions or control flows. But I do agree with you on one point: It really largely is an implementation detail.Bill
    I agree Ioc containers are magic too; I don't like to use them in a unit test either. Typically you don't mess with the IoC container magic at all in a unit test; you just pass the mock object in to the constructor or setter method. The unit test doesn't depend on any IoC code or configuration. But of course you could use AOP to do constructor or setter injection, and not use any AOP stuff in the unit test either. I guess at this point I don't see any clear advantage to AOP IoC, but maybe not any disadvantage either. I could even imagine taking a Pico configuration script and using AOP to do DI behind the scenes. As long as I can write my application code test first, without using any AOP or IoC DI, and not have to change my application code to do the run-time IoC, I'm happy. I can do that now with Pico; I guess the Pico backend could be impleneted via AOP too.

    Steve
  46. Virtual Mocks with AOP[ Go to top ]


    The most valuable lesson that I have leaned about AOP came from Jonas Boner. He told me not to think about AOP as magic, and not to introduce AOP into an existing design to magically introduce functionality or patch code.


    AOP's main benefit is that you can vastly simplify an OO design by removing duplicated code and layer functionality on your object model. But the decision to use AOP must be taken as design time and all memebers of your development team must know in advance that AOP is to be used. It can also help to describe to new developers to your team how a system works with AOP, especially as there are less LOC's for them to catch up on!


    To solidify AOP development, we do need better tools that allow us to see the effects of point-cuts etc. Unfortunately it is a very segmented market at the moment. You have a growing number of dynamic proxy based frameworks and a smaller number of frameworks that work on instrumentation or post-compilation. Each framework has it's own quirks from what I've seen so either the AOP framework developers provide IDE support or we need greater standardisation. I'm not sure how well the AOP Alliance is doing in this regard, ie. common method of pointcut definition etc. Perhaps someone else could coment on that?
  47. I think Spring framework already has something similar to this approach, by means of "metadata-driven autoproxying" (http://www.springframework.org/docs/reference/aop.html#aop-introduction-spring-defn) in their AOP framework, which uses Attributes to define which classes or methods get intercepted. Can someone confirm this?

    Regards,
    Henrique Steckelberg
  48. IoC now in JBoss[ Go to top ]

    Our JMX microkernel has dependency injection, but lacks prototyping. It can inject dependencies that are other components. If those components have not been deployed yet, then the component will block its lifecycle until that component gets deployed. These are just some of the features of our JMX microkernel. Other's include:

    * classloading domains
    * interceptors
    * metadata
    * transparent remoting
    * GUI management console with graphing, snapshoting, and monitoring

    All this available in JBoss 3.2 land for awhile now. Many of our customers are using the JMX kernel alone to do define their services/components and of course our J2EE container is built on top of it.

    Bill
  49. implicit container?[ Go to top ]

    Isn't the code that knows what to IOC a container
    regardless of mechanism? You might as well get
    the other "benifits" as well.
  50. AOP/ Flow based programming[ Go to top ]

    Would the following be a sane thing to do?

    AOP instruments classes. But basically every function on class gets called from another class until you end up in some main() method: would it be possible to instrument classes dependent on the calling function? Or ..

    Somehow I've always been fascinated by the idea of flow based programming:

    http://www.jpaulmorrison.com/fbp/

    Would it be possible for instance using AOP. to instrument a function call to go through a proxy on the way out? Let me make this more clear. Say I call a function a.x() in a function b.y(). What I would want to happen is that the call to a.x() made from b.y() actually first goes through a remoting proxy before ending op in a.x(). When using proxies function calls are already objects, why not add routing using AOP? One could combine (work)flow concepts and OO programming.

    Sanne
  51. AOP/ Flow based programming[ Go to top ]

    Somehow I've always been fascinated by the idea of flow based programming...
    A flow diagram is easier on the brain than a text script.
    ...why not add routing using AOP? One could combine (work)flow concepts and OO programming.
    You don't need aspects for that.
  52. Have a look at Flow4j Eclipse for a great example of simple flow based programming.
  53. I've seen many comments here that IDE support for AOP is a must for the successful use of AOP in projects. And I fully understand the reasons that have been put forward.

    Yet I have a concern.

    We know that the power of Ant lies in its ability to script the development process, including unit testing, and thereby deliver greater productivity and quality, *without* the need for an IDE. IDEs are a nice-to-have in this model. They complement the build process by giving the developer convenient features like colour syntax highlighting, intellisense, class browsing, refactoring support, etc. But nowadays, we normally discourage developers from using the IDE's native build and deploy functions. We encourage them to drive these through Ant instead. In other words, we can afford to be IDE-agnostic. And I think that's A Good Thing.

    I'm concerned that the IDE-for-AOP sentiment means we're once again going to be tied to an IDE to be able to use a piece of functionality. Once a development team gets used to a particular vendor's IDE, they will be reluctant to move to another. This could very well mean that project teams will become 'sticky' with regard to the app server as well, because each app server vendor markets their own IDE as well.

    Can we think of a paradigm (not a graphical one) that will do what we're trying to get (i.e., an indication of all the components touched by a pointcut expression)?

    Apologies. Being from the old Unix school of thought, I always try and separate graphical presentation from an underlying process.

    Regards,
    Ganesh