Search code examples
osgiaspectjmodularitybnd

Aspectj, how to use ajc in a modular way


I am trying to use the Aspectj compiler ajc in a modular (OSGi setting). The standard way ajc seems to be used is to take aspects & java code and turn it into one a JAR with all classes and resources in the -inpath, -aspectpath, and -sourceroots.

I am trying to weave aspects an OSGi executable JAR from bnd. This executable jar contains a set of bundles that need to be woven. However, in a modular system, the boundary is quite important. For one, the manifest often contains highly relevant information to that bundle or one of the many extenders. Flattening all the classes into a big blog won't work.

I am therefore weaving each bundle separately. However, then the output is cluttered with the aspects. I'd like to import these to keep the aspect modules proper modules. However, using the annotation programming model, I notice that ajc is modifying the aspect modules, so I need to rewrite those as well. This is fine, but since I weave each bundle separately, I have the question if the weaving of the aspect could depend on what gets other modules woven? That is, does the modification of the annotated aspect depend on the classes that it is woven in?

The other issue is what happens to resources with the same name? Since my -inpath is only one JAR (the bundle), I notice I end up with the correct manifest (META-INF/MANIFEST.MF) in the output. However, if the -inpath consists of many bundles, what will the manifest be? Or any other resource that has the same path and thus overlaps?

Last issue is external dependencies. I understand acj wants to see the whole world and include this whole world into the output JAR. However, I must exclude external dependencies of a bundle. Is there a way to mark JARs as: use, but do not include. A bit like the maven 'provided' scope?

Summary:

  • Does the modification of an @Aspect annotated class depend on the targets that is applied to?
  • Can I compile the @Aspect annotated classes into separate JARs?
  • How to handle the external dependencies that will be provided in the runtime and thus must be excluded from the output JAR.
  • What are the rules around overlapping resource paths in the -inpath and -sourceroots?

UPDATE In the mean time I've made an implementation in Bndtools.


Solution

  • Does the modification of an @Aspect annotated class depend on the targets that is applied to?

    If you want to be 100% sure you have to read the AspectJ source code, but I would assume that an aspect's byte code is independent of its target classes, because otherwise you could not compile aspects separately and also not build aspect libraries.

    Can I compile the @Aspect annotated classes into separate JARs?

    Absolutely, see above.

    How to handle the external dependencies that will be provided in the runtime and thus must be excluded from the output JAR.

    If I understand the question correctly, you probably want to put them on the class path during compilation, not on the inpath.

    What are the rules around overlapping resource paths in the -inpath and -sourceroots?

    Again, probably you have to look at the source code. If I was you I would simply assume that the selection order is undefined and make sure to not have duplicates in the first place. There should be Maven plugins helping you with filtering the way you want the result to be.


    bndtools seems to have close ties to Eclipse. So does AspectJ as an Eclipse project. Maybe you can connect with Andy Clement, the AspectJ maintainer. He is so swamped with his day-time job though, he hardly ever has any free cycles. I am trying to unburden him as much as I can, but OSGi is one of my blind spots and I hardly know the AspectJ source code. I am rather an advanced user.