Discussions

Bill Burke is busy. He has just released RC1 for JBoss AOP, which has new features such as a new $template feature. He also has written a new article, Aspect-Oriented Annotations, which discusses his vision of how AOP and annotations can combine (which has been a hot topic).

EJB Evolution

As AOP matures along with the EJB specification, what I really hope happens is that the annotations defined in the EJB specification will be usable in any context as new adjectives to the Java language, rather than their limited constricted use within session beans. Imagine a truly stateless bean being just a set of static methods on a plain Java class.

public MySessionBean{ @Tx(TxType.REQUIRED) public static doSomething() {...}}Anyways, this talk of AOP and EJB is probably for EJB 4.0.

As AOP matures along with the EJB specification, what I really hope happens is that the annotations defined in the EJB specification will be usable in any context as new adjectives to the Java language, rather than their limited constricted use within session beans.

Certainly there should be common annotations usable effectively as additions to Java, but they should be defined in JSR-250 (Common Annotations for the Java Platform), not the EJB specification.

As AOP matures along with the EJB specification, what I really hope happens is that the annotations defined in the EJB specification will be usable in any context as new adjectives to the Java language, rather than their limited constricted use within session beans.

Certainly there should be common annotations usable effectively as additions to Java, but they should be defined in JSR-250 (Common Annotations for the Java Platform), not the EJB specification.

Rod, I think you missed the point of my statement there. The point is not about defining common annotations, but rather, that these annotations start having the feel that they are part of the Java language, rather than part of a framework or container architecture.

This is where AOP + Annotations come in. Down the road, a mature AOP platform integrated tightly and shipped with the JDK will add a LOT of flexibility and power to library/framework/middleware developers, and provide the ease of use that users demand. JBoss AOP is working to speed this evolution.

Then you can use it within doclet tags. The Annotation Compiler compiles the doclet tag and embeds the annotation within the .class file just like JDK 1.5 compiler does. (Follows the same JDK 5.0 bytecode format).

Bill, could you point me at an example how the following trick can be done in JBossAOP with minimum configuration/tagging etc:At runtime create instrumented (singleton) instance of a class that wraps every public declared method in the given class in a method interceptor. That interceptor makes sure that a Hibernate/iBatis session/connection is associated with ThreadLocal variable of CallContext, or creates new one. Today I do this trick with cglib and it does not require any configuration/annotation/extra interfaces/etc. What I do today:

And interceptor wraps such code into appropriate try-catch and start/commit/rollback logic. DBConnectionInstrumenter creates of returns singleton instance of a given DAO class.

Advantages: - works great for DAO objects;- all code in Java, so IDE checks syntax and helps writing code (versus pure JAssist where all the interceptor code is a string);- no extra compilation steps, no need for special classloaders etc.; - no problems with debugging, debugger simply steps into interceptor code;Disadvantages of my approach: - limited applicability and flexibility; So, I would like to know how could I migrate to more powerful framework without sacrificing simplicity and transparency I enjoy today?

That does not look very appealing, no examples, no introduction...Anyway I looked at sources and my cglib based approach seems more convenient, it does not require java (1.)5. And cglib comes with Hibernate...But, I _would like_ to use some AOP framework, I do not have many objections against bytecode modification, just want a transparent, easy maintainable solution.

That does not look very appealing, no examples, no introduction...Anyway I looked at sources and my cglib based approach seems more convenient, it does not require java (1.)5.

JBoss AOP works on 1.4 and 1.5. Annotation support is available too for both 1.4 and 1.5 (see above). Your cglib based approach is a fine solution. The JBoss AOP solution gives you more flexibility though because you have full control over where you ant hibernate session demarcation. See caller side expressions as well as how we use annotations to define transaction boundaries.

Sorry I did not make myself clear, my critique was about Wilkosz, not about JBossAOP. JBossAOP is very appealing but I am very cautious about classloader based solutions, especially when it involves messing up with system wide classloaders.Your example is fine and if it was possible to do something like this:MyDAO dao = AOPEngine.instrumentInstanceOfClass( MyDAO.class );without touching classloaders I would be completely satisfied and happy.

Offtopic: At this moment classloader related issues is major source of problems therefore something should be done about it at Java spec level IMO.

Sorry I did not make myself clear, my critique was about Wilkosz, not about JBossAOP. JBossAOP is very appealing but I am very cautious about classloader based solutions, especially when it involves messing up with system wide classloaders.Your example is fine and if it was possible to do something like this:MyDAO dao = AOPEngine.instrumentInstanceOfClass( MyDAO.class );without touching classloaders I would be completely satisfied and happy.Offtopic: At this moment classloader related issues is major source of problems therefore something should be done about it at Java spec level IMO.

Sorry to repeat myself, but JBoss AOP can do AOP with classloaders, or there is a precompiler so that you can weave in the aspects at compile time and not require special classloaders.

You are sort of right though about the classloaders. I'm currently looking into java.lang.instrument of JDK 1.5. I'll get back to you on how it goes. There's also a lot of tricks you can do with JMangler with JDK 1.4 and lower.

Thanks, you got it right. Am I mistaken, or your example assumes using AOP classloader?Is it possible not to mess with classloaders? With cglib (proxy based approach) original class and modified one are almost the same for many practical uses, which seems to be a bit more convenient

The difference being is that you can define at deploy time where your Hibernate Session boundaries are and configure them differently per application.Bill

Yeap, my approach is not flexible and based on assumption that DAO object is roughly equal to SessionBean where all methods are defined as transactional ( of course transaction gets propagated if one dao calls another). That is why I am looking for more powerful and flexible AOP framework, but because I have tasted simplicity and transparency of proxy based solution I am dreaming about similar easiness for the same use case...

There's just as must complexity with a proxy based solution like Spring as with something like JBoss AOP or AspectJ or AspectWerkz. You still have to write an interceptor, still have to write a descriptor.

Class-weaving solves a lot of problems which are impossible with proxy-based solutions. In particular, caller side interception, field interception (see JBossCache), constructor interception, and the annotation stuff in my OnJava article.

Also, these proxy-based AOP solutions force you into a certain development model (working with interfaces, factories, and referencing container code). Weaved AOP frameworks like JBoss AOP, AspectJ, and AspectWerkz do not require a special coding style to apply your aspects. Nor do they require you to interact with a framework within your application code.

Proxy AOP does have its place though in remoteness when clients need to talk to a remote object. This is why we use proxies in our AOP remoting framework. You also have to be very careful when serializing weaved-AOP because you may not have the same class format on the other end.

There's just as must complexity with a proxy based solution like Spring as with something like JBoss AOP or AspectJ or AspectWerkz. You still have to write an interceptor, still have to write a descriptor.

True, from a deployment perspective. Although with a proxy-based framework the effect on what's going on in your app is a bit less far-reaching and uses less complex mechanisms. There's no need to mess with the class loader, so no potential conflict with app server mechanisms.

Class-weaving solves a lot of problems which are impossible with proxy-based solutions. In particular, caller side interception, field interception (see JBossCache), constructor interception, and the annotation stuff in my OnJava article.

True, class-weaving can do a lot more. (Although with class-weaving there are potential issues about class loader-wide byte code modification.) However, proxy weaving works very well for most of the typical AOP applications in J2EE applications, such as declarative transaction management and security, and a whole lot more besides, when given a true pointcut model. For example, I seldom find use for field interception, and would use AspectJ if I did. Btw, Spring AOP has offered annotation-driven transactions for months (using Commons Attributes, but we can also support Tiger, and will before it's GA).

Our strategy is to integrate seamlessly with AspectJ, by far the most mature class-weaving solution, to provide the option of seamless use of class-based aspects if and where appropriate. Thus in Spring 1.1 you can configure AspectJ aspects using DI, like any other object. Adrian Colyer (AspectJ lead) has blogged about this several times: http://www.aspectprogrammer.org/blogs/adrian/2004/07/spring_is_here.html.

...proxy-based AOP solutions force you into a certain development model (working with interfaces, factories, and referencing container code). Weaved AOP frameworks like JBoss AOP, AspectJ, and AspectWerkz do not require a special coding style to apply your aspects. Nor do they require you to interact with a framework within your application code.

Every point in this paragraph is wrong.

- With Spring, as with DynAOP, you can proxy either interfaces or classes. (Not that using interfaces is a bad idea, however.)- You don't need to work with factories in application code, and it doesn't "force you into a certain development model". Neither advised code or advice needs to reference container code. In fact, you can implement the AOP Alliance MethodInterceptor interface and have zero dependency on Spring APIs in interceptors.- Your application code does not need to "interact with a framework"

- You don't need to work with factories in application code, and it doesn't "force you into a certain development model". Neither advised code or advice needs to reference container code. In fact, you can implement the AOP Alliance MethodInterceptor interface and have zero dependency on Spring APIs in interceptors.- Your application code does not need to "interact with a framework"RgdsRod

I just want to echo what Rod just said. We have been using a proxy-based AOP framework for two years now and have the same experience as Rod outlines. DI makes utilization of proxied services totally transparent.

To go one step further, the majority of our interceptors do not even import any AOP framework API's, which the JBoss interceptors have to do (like the invocation stuff).

The only place that really *needs* to access factory API's in our framework is when you are creating new objects, either from scratch or from stringified id's. That doesn't happen *that* often though, and can also be hidden behind application factories if you really want to.

Actually, field interception is perhaps the *least* useful "extra" thing that weaving can do that proxies cannot. To me, the most useful thing is to be able to intercept *constructor* invocations. That's really great, it gets the "container" out of the picture entirely....

Since I am a great fan of being able to instantiate any object, in any tier, just by calling new Foo(), I'm not very keen on the requirement that proxy-based AOP frameworks have for instantiation via the container.

Funny to hear myself arguing *for* bytecode stuff in the context of AOP, when in other contexts (persistence) I am against it! ;-)

Actually, field interception is perhaps the *least* useful "extra" thing that weaving can do that proxies cannot. To me, the most useful thing is to be able to intercept *constructor* invocations. That's really great, it gets the "container" out of the picture entirely....

Funny that you should mention that, because constructor interception is next on my list of "Stuff I Don't Need In AOP". Why? Well, in my app Java instances are instantiated in basically three places. First of all, you have the services, but since I'm using DI through Pico to do service dependency management I might just as well implement any such interception using ComponentAdapter's in Pico. Second, there's the object model instances (=persistent). But, in a persistent model the actual Java instances are not really the same as the objects (objects are persistent logical entities and have a "long" lifetime, whereas instances runtime thingies that are transient and have a "short" lifetime), so to do stuff when they are instantiated is not really meaningful. And if I wanted to then again, Pico is doing the actual instantiation in my case so I'd just implement it with ComponentAdapter's. For actual object lifecycle interception, like managing the rules of what happens during a create/remove/clone (e.g. managing aggregated objects and such), I have a Lifecycle interface which all such objects must implement. But to intercept those methods is then just like any other method. Lastly, aspects(/advice/interceptors) are instantiated, but this is (again) done by using Pico in order to allow them to easily access services (e.g. my TransactionalInterceptor requires a TransactionManager so it's constructor receives one from Pico).

So, overall there's no need for constructor interception in the kind of app I'm doing, where everything is services+persistent objects and DI is used for dependencies. Or at least I haven't been able to find any such need. YMMV.

Use cases(non-exhaustive) for each advantage. Those marked by X are ones I've actually implemented/used* Constructor interception - dependency injection(X)

Why is it better to do this using AOP rather than something like Pico or Spring?

- factory pattern(X)

Why is it better to do this using AOP rather than something like Pico or Spring?

- pooling

Why is it better to do this using AOP rather than something like Pico or Spring?

- resource control (semaphoring)

Can you explain what this is? (I don't get it)

- stat monitoring (X)

Can you explain what this is? (I don't get it)

* field interception

- new field types (see my article)

So you could have a class/aspect where one field is threadlocal, one is coupled to the user session, one is coupled to the classloader, and yet another field is coupled to the application. Sounds like it might get a tad confusing. We allow a single aspect instance to be per-thread or per-session or similar, but I'm not sure I want to mix models for the different fields in an instance.

- per thread dependency injection (see my article)

Why is it better to do this using AOP rather than something like Pico or Spring?

- CMR for Hibernate

Yeah, that could be a good thing to have.

- transparent transactional state (JBossCache)

Don't need field interception for this.

- transparent replication (JBossCache)

I found that once you get into AOP your perspective on replication gets a little more "interesting". It's not only about state anymore, since it is also important to consider side-effects of changes. Hence, it is more relevant to replicate invocations rather than data changes.

- fine grain HTTP Session replication

This is based on per-instance AOP'fying of objects at runtime if I remember correctly. I personally think that's a really bad idea.

- fine grain SFSB replication (by fine grain, I mean only the state that has changed)

Sure, but this is so low-level that you could easily implement it without AOP techniques.

Why is it better to do this using AOP rather than something like Pico or Spring?

Transparency, transparency, transparency.

- transparent transactional state (JBossCache)

Of course you do. If your object has business methods that change the internal state of the object. With JBossCache, object references are maintained. Downlaod JBossCache and try out the demo.

We allow a single aspect instance to be per-thread or per-session or similar, but I'm not sure I want to mix models for the different fields in an instance.

You most definately would want a PER_JOINPOINT model as well. The @Threadbased example in my article is just a small example. You may want to have an aspect that maintains state for a particular joinpoint.

I found that once you get into AOP your perspective on replication gets a little more "interesting". It's not only about state anymore, since it is also important to consider side-effects of changes. Hence, it is more relevant to replicate invocations rather than data changes.

Of course you do. If your object has business methods that change the internal state of the object. With JBossCache, object references are maintained. Downlaod JBossCache and try out the demo.

Great. But you still don't need field interception to do this.

You most definately would want a PER_JOINPOINT model as well. The @Threadbased example in my article is just a small example. You may want to have an aspect that maintains state for a particular joinpoint.

Perhaps. There's a whole bunch of different kinds of models you might want. I think we have something like 8-10 right now. But you didn't address the actual concern I have: won't it be confusing to have this on a per-field basis if one class uses a lot of different models at the same time?

Sounds very inefficient and unscalable to me.Bill

It's been working quite well the past years we've been using it, but in our case we were more concerned with getting the right results and semantics rather than the best performance. We tried a couple of more "standard" approaches in the beginning, such as shuffling state, but it didn't produce the correct results. Replicating invocations, much like what Prevayler does, is a much safer way to do it, and you also have the added bonus of being able to do per-method security checks. You can't do that if you're into data shuffling for replication.

It's been working quite well the past years we've been using it, but in our case we were more concerned with getting the right results and semantics rather than the best performance. We tried a couple of more "standard" approaches in the beginning, such as shuffling state, but it didn't produce the correct results. Replicating invocations, much like what Prevayler does, is a much safer way to do it, and you also have the added bonus of being able to do per-method security checks. You can't do that if you're into data shuffling for replication.

One more thing, it can actually be much more efficient to replicate method invocations. For example, one of the most common operations in our product is that a page is published. In terms of changing state that is a rather expensive operation: the previously published page, which typically is an object graph with 10-100 objects, must be deleted and each object has 10-15 persistent aspects. Then a new copy is created. In total it could mean making 200-3000 changes in the database. If I were to use state replication it would mean that I would have to send 200-3000 changes to each replica. Now, since I use method invocation replication instead it is enough to replicate one method call to a service object: "publish(Version,Page)". That replicated invocation will ensure that all the appropriate changes are made, and will also trigger reindexing in the search engine on the replicas. That is both more efficient and scalable than if a state transfer method had been used.

Actually, field interception is perhaps the *least* useful "extra" thing that weaving can do that proxies cannot. To me, the most useful thing is to be able to intercept *constructor* invocations. That's really great, it gets the "container" out of the picture entirely....Since I am a great fan of being able to instantiate any object, in any tier, just by calling new Foo(), I'm not very keen on the requirement that proxy-based AOP frameworks have for instantiation via the container.Funny to hear myself arguing *for* bytecode stuff in the context of AOP, when in other contexts (persistence) I am against it! ;-)

I am "enemy" in this case. There is no major difference, but "factory" is more clear than "magic" for "managed" object.

Field interception looks exotic as I understand it is designed for some kind of "transparence" too.

...proxy-based AOP solutions force you into a certain development model (working with interfaces, factories, and referencing container code). Weaved AOP frameworks like JBoss AOP, AspectJ, and AspectWerkz do not require a special coding style to apply your aspects. Nor do they require you to interact with a framework within your application code

What Bill Says seems to be correct , I mean if I am using an Proxy type AOP I need to get it throught the "Light Weight Container" , that is presicely I am doing in Spring? Ofcourse the dependency is minimum or I would say it does not matter. Yes the AOP approach of Jboss does not have that line also but you have additional steps as Compilations and then assuming all goes well in the Classloaders .The compatibility across the Class Loader sensitive applications can be the Risk , this includes the deployment in the Applicaiton Server also .- With Spring, as with DynAOP, you can proxy either interfaces or classes. (Not that using interfaces is a bad idea, however.)- You don't need to work with factories in application code, and it doesn't "force you into a certain development model". Neither advised code or advice needs to reference container code. In fact, you can implement the AOP Alliance MethodInterceptor interface and have zero dependency on Spring APIs in interceptors.- Your application code does not need to "interact with a framework"Rod , I have been digging spring code from the one month and have understood what I have pointed to Bills Post .RegardsVicky

I merely made the point that I believe that use for field interception in application, rather than framework code, is limited: if you want to assume that my view is commercially motivated, it saves time discussing it. I could equally accuse you of commercial motivation, but it's a rather low debating tactic, don't you think? Doesn't it occur to you that the capabilities of Spring AOP reflect what I believe to be most valuable in typical applications, rather than that the usage patterns I advocate are based on Spring's functionality? Field interception could be supported within the Spring AOP API, with a different proxy generation implementation (the choice of DPs or CGLIB is actually not baked into the core API), but we haven't prioritized it because we don't believe it's advisable in most cases, and we advise users to choose AspectJ in such cases.

"Just because Spring cannot do it"--well, in combination with AspectJ, as I pointed out, I suspect that Spring is far more powerful than JBoss AOP, but the point is not what particular implementations are capable of, but what is wise usage practice in typical applications today.

well, in combination with AspectJ, as I pointed out, I suspect that Spring is far more powerful than JBoss AOP, but the point is not what particular implementations are capable of, but what is wise usage practice in typical applications today.

Rod,

Well, if you're gonna play that silly game of Spring + XXX is more powerful than YYY....

Combine JBoss microkernel and JBoss AOP and I know you have something more powerful than Spring and AspectJ.

I'm looking forward to looking at that--it sounds very interesting, and someone mentioned it to me last week. A blog would help. I think Jonas is also talking at JAOO next month, so I look forward to meeting him.

I merely made the point that I believe that use for field interception in application, rather than framework code, is limited: if you want to assume that my view is commercially motivated, it saves time discussing it.

I am again echoing Rod's experiences in this regard. We've been doing loads of aspects the past two years in our app, and I've never felt the need to have field interceptors. Whenever there's a need for "field-stuff" (or similar) I put it on the get/set accessors instead, which I always have anyway. I suppose you could reason that you might want to ditch the get/set methods and go straight for the fields. I never had that urge, but YMMV.

I merely made the point that I believe that use for field interception in application, rather than framework code, is limited: if you want to assume that my view is commercially motivated, it saves time discussing it.

I am again echoing Rod's experiences in this regard. We've been doing loads of aspects the past two years in our app, and I've never felt the need to have field interceptors. Whenever there's a need for "field-stuff" (or similar) I put it on the get/set accessors instead, which I always have anyway. I suppose you could reason that you might want to ditch the get/set methods and go straight for the fields. I never had that urge, but YMMV.

Doing field interception with proxy-based using get/set methods is limited because you would not be able to intercept changes to an Object's state that are done interally intra-class within business methods and write truly generic aspects.

Doing field interception with proxy-based using get/set methods is limited because you would not be able to intercept changes to an Object's state that are done internally intra-class within business methods and write truly generic aspects.

Bill

Are you actually advocating usage of aspects that intercept business logic within business methods? In my opinion this is the most dangerous misuse of AOP. Business logic is very liquid and tends to change frequently  any usage of aspects there will quickly become impractical and unmaintainable.

Are you actually advocating usage of aspects that intercept business logic within business methods?

The answer is yes.

I am with Bill, I think that it is OK for business objects to know that they will be weaved and rely on that. For example my DAO objects expect that somebody( aspect/proxy/factory) will assign connection/session to the ThreadLocal variable and will properly deal with exception handling. That is very handy and allows cleaner code.

Cannot make any sense of the examples provided on this page. Just a bunch of mangled java code piled within html tags all in one huge blob inside of a scrollable text box. Even after getting $10 mils you still can't produce professionally looking documentation.

But back to annotations... I agree that annotations like @transacted which actually serve to attach generic yet orthogonal middleware functionality to business logic do make sense. I was actually referring to one business logic unit intercepting another.

Doing field interception with proxy-based using get/set methods is limited because you would not be able to intercept changes to an Object's state that are done interally intra-class within business methods and write truly generic aspects

Oh, I know. Just saying that so far I haven't found a need for it. There's lots of *possible* stuff in, for example, AspectJ that I just haven't found a need for.

I believe that Darwinism is a fairly useful thing to understand these kinds of situations. You can either be a generalist, like AspectJ, or you can be a specialist, like our framework is. Ours is specialized on doing business-logic intensive, client/server, persistent, scalable, yada yada. AspectJ just isn't very good at those sorts of things, by design. My (admittedly limited) impression of Spring is that it has evolved from needs similar to ours: you have a particular problem domain, and you create a framework that solves problems within that domain perfectly, and problems outside of that domain not-so-perfectly. Knowing where you fit in the grand scheme of evolutionary progress is the key to ensuring survival.

There's no need to mess with the class loader, so no potential conflict with app server mechanisms.

Rod, please stop the FUD on bytecode weaving to promote your own commercial product. Thanks Alex for expanding on the maturity of bytecode weaving.

It was probably noticed that I am not a big fan of Spring, but here Rod is technically correct: in the current state of affair proxy based solutions are 'safer' and really cover many useful scenarios ( see Rickard's port).Why safer? Lets explore what happens in the line:MyClassmc = ClassEnhancerFactory.getInstanceOf( MyClass.class);

MyClass gets loaded by some classloader and variable mc has type of someClassloaderInstance.MyClass, and we do not care what classloader it was;ClassEnhancerFactory creates a proxy class of type MyClass$EnhancedBy-blah-blah;JVM assigns object of type MyClass$EnhancedBy-blah-blah to the variable of type MyClass;

It is really nice and clean because this trick works without any messing with classloaders. It was pointed out that classloaders 'matured' but I just do not feel this way. Partially because I am too scared of past experiences, partially because classloader spec is too vague and fragile IMO, partially because I am pissed of by implementation details screwing language semantic ( classloader _instance_ at runtime defines_namespace: so two instances of the same class, from the same package, inside the same application, loaded by two classloaders from the same physical location will be treated as different classes)

Side note: I do not like AspectJ because it alters Java syntax with no good reasons, as AspectWerkz and JbossAOP demonstrate all aspectization can be easily achieved via comments and metadata.

Aspect compiler: when we are talking about separate step to weave classes before deploying on server I cannot help myself but think that is no different that doing simple (good old) source code generation and then compiling it.

Just thoughts:Theoretically an AOP could be no different than extended macro language that allows applying Macroses(Aspects) to the source code on textual level.

As a developer I like ability to apply cross-cutting aspects to my code, but if there was an extended Xdoclet that would allow using metadata constructions like: ( my.package.* exec (public * ) apply MyMethodInterceptor ) I would favor that solution because it could be:-classloader safe;-zero overhead (no reflection);-easy to debug (debugger steps into source);-no need for special program to know which aspects were applied(just glance at generated source);

It was probably noticed that I am not a big fan of Spring, but here Rod is technically correct: in the current state of affair proxy based solutions are 'safer' and really cover many useful scenarios ( see Rickard's port).Why safer?

If by safer you mean, easier to implement and less to worry about as a AOP framework implementer? Then yes, you are correct. Again, take a look at Alex's posts and JDK 5.0's java.lang.instrument API. Also, JMangler is a good tool too for pre-5.0 JDKs. All those approaches require no special classloaders.

Besides, you can do precompilation with frameworks like JBoss AOP, AspectJ, and AspectWerkz.

Besides, you can do precompilation with frameworks like JBoss AOP, AspectJ, and AspectWerkz.Bill

Bill, it really helps to read posts and not to jump for an answer.Exactly because all the frameworks you have mention do precompillation I talked about theoretical enhanced Xdoclet that will do aspectization upon source, and not bytecode.

Besides, you can do precompilation with frameworks like JBoss AOP, AspectJ, and AspectWerkz.Bill

Bill, it really helps to read posts and not to jump for an answer.Exactly because all the frameworks you have mention do precompillation I talked about theoretical enhanced Xdoclet that will do aspectization upon source, and not bytecode.

This is a good discussion...I hope you don't mind me arguing. I want to debunk some of the common misconceptions about JBoss AOP and bytecode weaving in general.

Just thoughts:Theoretically an AOP could be no different than extended macro language that allows applying Macroses(Aspects) to the source code on textual level.

As a developer I like ability to apply cross-cutting aspects to my code, but if there was an extended Xdoclet that would allow using metadata constructions like: ( my.package.* exec (public * ) apply MyMethodInterceptor ) I would favor that solution because it could be:-classloader safe;-zero overhead (no reflection);-easy to debug (debugger steps into source);-no need for special program to know which aspects were applied(just glance at generated source);

If you think about it , the java->aopc-on-bytecode->bytecode would be equalivalent to java->xdoclet-java->bytecode except the middle format is bytecode vs. Java. As a developer you don't see the in-between format. Just like in C/C++ you don't look at object (.o, .obj) files.

AspectJ used to do code generation rather than weaving. You'll have to ask them why they switched...As far as JBoss AOP, we do bytecode weaving because it is so freakin easy with Javassist that it would with code generation. Try out the tutorial at www.javassist.org to see how.

JBoss AOP does not use Java reflection and its overhead is equalivalent to AspectJ's thisJoinPoint. The extra thisJoinPoint overhead allows us to hot deployment of aspects, per instance AOP, and to easily pass contextual information between aspects.

...As a developer you don't see the in-between format. Just like in C/C++ you don't look at object (.o, .obj) files.

There is a difference IMO: .o, .obj files are linear functions of source code and there is no real need to look at them ( except for compiler developers), when whole point of AOP is non-linear dependency of executable code on source + some metadata (kind of C++ templates) . It is very possible to define logger Aspect for everything in common place and then set log level to INFO and then keep wondering why system works sssooo slowly with no apparent reasons ( sorry I do not read bytecode). With source level aspektization it is immediately visible.

As far as JBoss AOP, we do bytecode weaving because it is so freakin easy with Javassist that it would with code generation. Try out the tutorial at www.javassist.org to see how.JBoss AOP does not use Java reflection and its overhead is equalivalent to AspectJ's thisJoinPoint. The extra thisJoinPoint overhead allows us to hot deployment of aspects, per instance AOP, and to easily pass contextual information between aspects.

I have played with Javassist and I would agree that it is kind of easier to develop an AOP based on Jassist for aop developers, and it also works with classes without source.But as a lazy business side developer a do not think it is easier for me because with Jassist I have to pass java source code as a string to Jassist, something like ctMethod.addBefore( System.out.println(\before  + mName + \));Seems powerful, but it means that I do not have IDE help in form of code-completion, syntax checking etc.And with bytecode modification what debugger will show me when I step into weaved method? So I guess my arguments:-classloader safe; -easy to debug (debugger steps into source);-no need for special program to know which aspects were applied(just glance at generated source); are still valid for any AOP that does not do code generation or isnt proxy based.

I have my concerns and fears about AOP and I would like somebody address them, or explain that it is all not that bad, etc.

It was probably noticed that I am not a big fan of Spring, but here Rod is technically correct: in the current state of affair proxy based solutions are 'safer' and really cover many useful scenarios ( see Rickard's port).Why safer? ..[..] It is really nice and clean because this trick works without any messing with classloaders. It was pointed out that classloaders 'matured' but I just do not feel this way. Partially because I am too scared of past experiences, partially because classloader spec is too vague and fragile IMO, partially because I am pissed of by implementation details screwing language semantic ( classloader _instance_ at runtime defines_namespace: so two instances of the same class, from the same package, inside the same application, loaded by two classloaders from the same physical location will be treated as different classes)

Frankly, the paranoia about byte code mangling and class loaders is pretty humorous. The JVM uses both of them and that doesn't seem to scare anybody ;-)

Seriously, though .. the Java ClassFile structure is so well defined that any reasonably capable engineer could safely implement "byte code manipulation." Think about the "byte code manipulation" solutions that you use every day, like JAVAC, Jikes, JAVAP, various obfuscators, Eclipse, etc. It's everywhere, whether you realize it or not.

As for ClassLoaders, the design / implementation in the JDK may suck (and I'm not even going to mention the JBoss ClassLoaders ;-), but using (or even implementing) a ClassLoader as part of a solution isn't rocket science anymore either.

All that said, if proxy-based solutions work for you, then great. Just please don't dismiss an entire approach to a technology because you're personally a bit scared of how it works.

This argument makes little sense. Bytecode injection and proxying are not mutually exclusive. It's like arguing whether inheritance or composition is better--it depends on the situation. Ideally AspectJ would support proxying as a third type of weaving (caller and callee side injection being the other two). In the mean time I'll have to use both AspectJ and dynaop.

Of course. What I was saying is that we should not irrationally attempt to suppress a perfectly valid technical approach such as bytecode manipulation.

Sorry about that, Cam. My comment was meant for the rest of the thread, not you. I obviously have no problem with bytecode manipulation. Proxying is bytecode manipulation. I wish more people would use it in place of build time tools (like EJB compilers).

A vendor market called application performance management solution, all bytecode instrumentation based.The JRockit VM that supports it in a native way (no tweak at classloader level) since apprx 2 years.I call that maturity. Not my fault if Sun fans had to wait for J2SE 5 to have it.

Side note 1: AspectJ moved from source level weaving to bytecode level weaving a while ago, because you cannot reach AOP obliouvness goal at source level.

Side note 2: modern AOP frameworks do not make use of reflection at all.

Uuu, how harsh. Just because SPREADING FUD is your style of doing business and promoting JBOSS (fake posts, remember you...) it doesn't mean that when someone doesn't agree with you does the same thing.

I am sure Rod won't spread any FUD to promote Spring JUST BECAUSE IT DOESN't NEED it. Spring is already soo soo very used. It has promoted itself through being a quality product that serves it's purpose.

"FUD wars - /fuhd worz/ Political posturing, intended to create FUD, engaged in by hardware and software vendors ostensibly committed to standardisation but actually willing to fragment the market to protect their own shares"

TSS is the best place for FUD, it can help to sell any toy as product("simple" vs, "complex"). Any thread on TSS is FUD, but it is very interesting too see byte code stuff as a weapon in FUD war :) Doe's it become popular ? As less you use this stuff as better, It is workaround for JAVA langue limitations. I hope you believe me.

This could be a useful capability, but it does have the downside that interception will be class loader wide. It's useful to have the capability for per-proxy advice, so that instances of the same class can be advised differently in different contexts. This is especially useful for existing code--e.g. a third party DataSource that has different advice in different usages.

http://computing-dictionary.thefreedictionary.com/FUD"FUD wars - /fuhd worz/ Political posturing, intended to create FUD, engaged in by hardware and software vendors ostensibly committed to standardisation but actually willing to fragment the market to protect their own shares"TSS is the best place for FUD, it can help to sell any toy as product("simple" vs, "complex"). Any thread on TSS is FUD, but it is very interesting too see byte code stuff as a weapon in FUD war :) Doe's it become popular ? As less you use this stuff as better, It is workaround for JAVA langue limitations. I hope you believe me.

This makes things more flexible , you are talking of the Dynamic Weaving (I call this a Dynamic AOP ).Anyway I am in a process to analyse the performance test for both the Proxy AOP and the Weaving Approach AOP(Runtime/Compile Time).Hey guys if you have some test to prove the framework for better performance why dont you put here , at end I would select the AOP framework which suits my requirement definetly the performance will be the criteria , addition to that I would look for some Standardizarion . Terminology seems to be different among the frameworks , so some standards have to be set , let the implementation be different , the best will move ahead .RegardsVicky

Performance is tunable thing, I do not think new language features are usefull, but standard API for this stuff (advanced reflection) is, It can be implemented in many ways and many ways can be implemented on top of it ("static" or "dynamic"). There are a lot of use cases for this stuff and looks like people want it.

...proxy-based AOP solutions force you into a certain development model (working with interfaces, factories, and referencing container code).

Objects are advised only if obtained from a factory or constructed programmatically, but since, with the use of an IoC container, dependencies are normally expressed using DI in pure Java, getting proxies from a factory is transparent to application code.

For other cases, we provide a cross platform mechanims that allows to have the same level of feature. It is a bit more complex than that, but for example we support IBM JRE 1.3 to enable AOP in WebSphere.

Messing with classloaders for bytecode instrumentation and AOP integration has reach a proven maturity and a standard. I guess that as JBoss just did, other AOP framework or bytecode based framework will align and make use of JSR-163/JVMTI.

Last, as Bill quotes, he will provide Annotation defined aspect support in JBoss 1.0 soon. We provide this syntax in AspectWerkz since the early days, thanks to a great idea from Ron Bodkin.For now, it is some javadoc tags, but as J2SE 5 Annotations are out, the same will be achieved in the month to come, meaning that an Aspect will be just a regular java source snip.

Though someone could define some more structures in the XML to allow deployment time definition or refinement of annotations defined aspects.

Conclusion: all the sparkling ideas used and implemented by various AOP frameworks like AspectJ, AspectWerkz and JBoss have started to gain consistency with J2SE 5 Annotations and other JSRs.As Bill explains in his (good) article, AOP and Annotations is getting to be a perfect fit, not only to plug AOP in your apps but to write your owns aspect.From this little comparison, it seems that the competition/mimics between AOP frameworks tends to reach a stage where a standardization would make sense, although it has implicitly started by the use of new J2SE 5 features.

If you're running inside JBoss, JBoss AOP would not need this step because our microkernel has pluggable archive formats, our pluggable Deployer architecture. In JBoss you can write a deployer that understands how to unpack an archive and load the services it defines. You get automatic hot deployment and JBoss classloader integration. This is how our EJB 3.0 pluggable Deployer works. The deployer iterates through all classes in the library looking for annotated EJB 3.0 classes. Javassist is used to look for the annotations so that we don't have to actually load the class. We have an AOP deployer and will extend it for the annotated aspects when 1.0 comes out. BTW, JBoss Microkernel is a full blown IOC container, mature (2 years old), and provides a rich set of functionality beyond basic IOC.

Alex,

For standalone Apps, I currently cannot figure out a way to remove the minimal XML step. First I thought about doing a ClassLoader.getResources("META-INF/manifest.mf"); This would give me URLs of all jars in the classpath then I could iterate through these archives. This didn't work though. What I think I'll do is provide an ASPECT_PATH system property you have to define and reuse some of the Deployer code.

I do understand the value of the JBoss AOP integration within the JBoss deployer, though I think that it is a good strategy to keep a piece of XML.

First it allows late binding. A use case I have is that I ship (as a vendor) some aspects and some gui for them etc, with most of the things defined in annotations. Then the end-user (and thus my vendor doc) needs just to know the aspect full qualified class name and the given pointcut name, to define them at deployment time.

Second, even in EJB 3 I think we will still see some *minimal* (but still) deployment descriptors. For exemple - if I remember, for JBoss EJB 3 prototype showned at JavaOne you had to name the ejb3 classes in a specific way, since crawling all resources and grabbing annotations from bytecode of .class files to see if we have an ejb(3) or not is a cost expensive operation.

That beeing said, and considering that annotation defined aspects are sort of "annotated java class that as a result needs a specific deployment phase" - just as en ejb(3) -, it makes sense to have a META-INF/aop.xml. This can be usefull for tools at developpment time as well - to force the exclusion of an aspect without having to remove it, or alter it source code.

Last the minimal xml is elegant to declare aspect precedence, else it has to be in one of the aspect instead (and we are back with the build time vs deploy time requirement).

I see a replacement of the xml when we will have a full dynamic behavior, where we don't need anything at the startup time and we can add/remove everything at runtime.

Bill,I do understand the value of the JBoss AOP integration within the JBoss deployer, though I think that it is a good strategy to keep a piece of XML.First it allows late binding.

Good point. XML definately is useful! Still, a lot of users hate XML and we should try and make AOP a transparent as possible. JBoss application server integration will still give you the late binding option, without the XML.

For exemple - if I remember, for JBoss EJB 3 prototype showned at JavaOne you had to name the ejb3 classes in a specific way

Untrue. You have to name the JAR files a certain way (foobar.ejb3). Well....you don't actually HAVE to name the jar files a certain way, but it slows down boot-time 100% (twice as slow). Still, considering we'd have to iterate through every .jar file, this is quite fast!

since crawling all resources and grabbing annotations from bytecode of .class files to see if we have an ejb(3) or not is a cost expensive operation.

Not very slow at all, Javassist is very fast, and all you're looking for is the @Aspect tag, @Entity, @Stateless, etc... If you name the jar files in a certain way (foobar.aop or foobar.ejb3), then the cost is VERY small as you only have to iterate through those jars that actually have aspects/EJB3s.

Take a look at the ejb3 deployer to see how easy (and performant) this is to implement using Javassist. Here's example code:

Thanks for these insights, Bill. Especially the part: "Next we will define the aspect class that will encapsulate the resolving of the TransactionManager. This aspect will be specific to the JBoss application server, but you could define different implementations per vendor." shows that not everything coming from the professional open source guys is evil. Boy, you wouldnt have heard this from Microsoft. There is nothing that is preventing us from avoiding vendor lock-in but our own incompetence. In my opinion we should be really grateful that there are companies that are funding open source. From day to day Im more impressed which sophisticated software evolves from open source engagement. For me a great part of this is JBoss, of which Im a pretty happy user. Keep on the great work. And hey, this is Jan Prill, Gruenebergstraße 38, 22763 Hamburg not employed by or married with JBoss Inc., which  Im pretty sure about this - has learned from the astroturfing-story. Everybody of us has the right to learn from mistakes.

That all sounds very well indeed, but what about standards? I mean, considering the Annotations part - everything is clear, but what about cross-cutting? To be able to employ the new paradigma it is still necessary to stick to some or other AOP framework (either JBoss or any other). but supposing I would like to use my Aspects, my Annotations and other stuff without JBoss (or what is more likely in some other container)? So the question is: is there any standard-movement in this direction, I mean some JCP that will define cross-cutting synthax?

TechTarget provides technology professionals with the information they need to perform their jobs - from developing strategy, to making cost-effective purchase decisions and managing their organizations technology projects - with its network of technology-specific websites, events and online magazines.