Community
Participate
Working Groups
Suppose a class is weaved with an advice from an aspect, and then packaged in a jar file. The aspect is coming from an aspect library, for example a tracing library, which is evolved independently from the current project. Later, a new version of the library arrives, and the aspect is not there anymore, for example it has changed name, or another refactoring took place, but anyway the aspect class file is missing in the new library. I have LoadTimeWeaving in place, so I would expect that replacing the old jar with the new one is enough to have my classes weaved properly. Moreover, in a Maven (or Ivy, or any other system managing transitive dependencies) system, it could be that the class actually weaved is not even mine, I could have no source code for it, and using the new version of the aspect library can (read: will) happen automatically. Unfortunately however, LTW does not properly reweave the class removing references to the mow missing aspect. Instead it throws a ClassNotFoundException. This is not, in my opinion, the expected behavior. Moreover, it is highly misleading, beacause I have no direct dependency on the aspect library classes, it could not even be one of my dependencies at all if I'm using Maven or Ivy that will resolve a transitive dependency to the new version of the library. I would expect the LTW system to threat a missing Aspect class as one of the possible situations where reweaving is necessary.
The stack trace follows : SEVERE: defineClass Message: error at it/semeru/asteappalti/site/BaseTemplate.java::0 type org.apache.magma.inlineadmin.AddMenuToDefaultTemplate is needed by reweavable type it.semeru.asteappalti.site.BaseTemplate org.aspectj.bridge.AbortException: type org.apache.magma.inlineadmin.AddMenuToDefaultTemplate is needed by reweavable type it.semeru.asteappalti.site.BaseTemplate at org.aspectj.weaver.tools.WeavingAdaptor$WeavingAdaptorMessageHolder.handleMessage(WeavingAdaptor.java:596) at org.aspectj.weaver.World.showMessage(World.java:636) at org.aspectj.weaver.bcel.BcelWeaver.processReweavableStateIfPresent(BcelWeaver.java:1352) at org.aspectj.weaver.bcel.BcelWeaver.weave(BcelWeaver.java:1133) at org.aspectj.weaver.tools.WeavingAdaptor.getWovenBytes(WeavingAdaptor.java:394) at org.aspectj.weaver.tools.WeavingAdaptor.weaveClass(WeavingAdaptor.java:281)
Also see http://www.nabble.com/Re%3A-Compiling-and-not-weaving-p19972150.html and relative thread.
review reweaving
> This is not, in my opinion, the expected behavior. I think what the user expects depends upon the environment they find themselves in. If the code is working because it was woven with an aspect and then sometime later someone else wants to reweave your code but the previously used aspect is not around (perhaps it was in another jar you haven't added to the aspectpath), the code could go wrong due to a failure to weave - and just ignoring this problem may hit you later, hence the current design of reweaving. It tells you up front that regardless of what new aspects you want to weave in, we have lost one that was used previously and that may impact the functionality of the code. Better to fail up front than later with some wierd problem. > Moreover, it is highly misleading, beacause I have no direct dependency on the > aspect library classes, it could not even be one of my dependencies at all if > I'm using Maven or Ivy that will resolve a transitive dependency to the new > version of the library. The message should be indicating that when reweaving of type X was attempted, that type was previously woven by an aspect A and now A could not be found. The messages are on a type by type basis. The fact that when A is brought into the mix affects your other new files is due to the problem of us not supporting scoped weaving where an aspect can be considered to only affect a subset of the files that the weaver is currently processing. Ideally if you pick up a jar that you want to weave with something else, any aspect dependencies it had should be brought into the weaver but scoped to only reweave the contents of that jar, but this doesn't happen right now, there is no infrastructure for it. --- However, the opposite point of view is that the user knows what they are doing and knows it can be safely ignored. My view right now is that this is a choice that the user makes explicitly, they take control and configure ltw to say 'i know better than you and i know these things can be ignored'. So I'm making it a configurable xlint rather than a hard failure for now. So a 'power user' can turn it down to warning or ignore level. This is similar to the configurability of the cantFindType message - a power user can turn it off if they truly believe they know better than the compiler but the default action for your average user is to tell them there is probably going to be a problem. Right now I don't have any testcases for reweaving whilst removing aspects, so please provide feedback on how this works out for you. The xlint is: missingAspectForReweaving and will be in the next dev build.
Configurable xlint is all i plan to do in the immediate timeframe. This may come up again when looking at an OSGi environment and how aspects are exposed across bundles.