Bug 93320 - aop.xml format should support aspectpath style rather than enumeration
Summary: aop.xml format should support aspectpath style rather than enumeration
Status: RESOLVED WONTFIX
Alias: None
Product: AspectJ
Classification: Tools
Component: Compiler (show other bugs)
Version: 1.5.0M3   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 1.5.0 M4   Edit
Assignee: Adrian Colyer CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-04-29 16:05 EDT by Ron Bodkin CLA
Modified: 2007-01-04 09:50 EST (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Ron Bodkin CLA 2005-04-29 16:05:44 EDT
I have found that using the current branched aop.xml format, which requires 
explicit enumeration of all aspects in the project, to be very brittle in the 
face of refactoring or adding new aspects. It would be much better if we could 
specify the equivalent of an aspect path (jar files or exploded classes 
directories) which will be scanned for aspects to apply. It would also be very 
useful to support an equivalent of inpath (i.e., to separate aspectpath, which 
specifies aspects that are applied but not woven, and inpath which can 
potentially include aspects and weave them).

I would be willing to work on code to do these things once the loadtime branch 
is merged into HEAD, if it would help.
Comment 1 Alexandre Vasseur CLA 2005-05-02 04:12:22 EDT
This is something appealing but lets take some things into consideration:
- aop.xml aims at integration in J2EE and alike, not standalone, and not compilation
- this means that the visible classes is only controlled by the runtime
underlying classloaders. What would be a valid aspectpath when aop.xml is in a
webapp ?
- adding path (aspectpath, inpath like) is dangerous, since we (AspectJ) cannot
ensure that those paths are part of the runtime classloader classpath, and thus
even we could weave those aspects, the weaved runtime would fail with "class not
found exception".

So how should we do it without further app server collaboration (f.e. aspect.jar
 and module just like J2EE has webapp and ejb-jar and ear modules.) ?
How many aspects per aop.xml do you already have / do you plan to have ?
Comment 2 Ron Bodkin CLA 2005-05-02 15:33:43 EDT
I think the issue is similar whether you enumerate all the aspects or just 
specify a path that holds them. I.e., whether one lists all the aspects that 
should be included from a jar, or just say add the jar to the weaving path, 
there is the same challenge in making sure the configuration is right (i.e., 
the right aspects are visible from the given classloader where they apply).

To me, a separate issue is that load-time weaving would be better if it only 
tried to weave visible classes, i.e., it checked whether a given classloader 
can see them, and wouldn't try to weave them if they're not visible. The 
branched code does this in a way (by throwing RTEs)... I made a small change 
to catch & not abort loading all aspects if one isn't found. Maybe I could do 
this better by somehow specifying the aop.xml for the ExtClassLoader, rather 
than a system-wide default that tries to weave into everything? Can this work?

I think this would be better than just having a bunch of special-cases. I 
patched Aj.preProcess to exclude a couple of cases that were common problems 
for me:

        if (loader == null
                || className == null || loader.getClass().getName().equals
("sun.reflect.DelegatingClassLoader") ||
                loader.getClass().getName().equals
("javax.management.remote.rmi.NoCallStackClassLoader") ) {


In addition, it would actually help a lot to be able to write pointcuts (or at 
least type patterns) for which classloaders should & should not weave a given 
set of aspects. If you are installing system-level aspects, it could be very 
helpful to exclude by classloader rather than by type being loaded...

To me, the way to do it is to require including any inpath or aspectpath 
entries to also be on the classpath that's visible to a given classloader. 
Then the aop.xml file for the given loader can reference the given path entry, 
i.e., it would be specified in the weaving configuration for the given loader 
NOT as an environment variable/system-wide default.

My use case is indeed focused on supporting weaving into VMs with non-trivial 
classloader hierarchies (including J2EE). I currently have about 5 aspects 
that I deploy but expect that to grow to about 20 and have already had to go 
back & remember to update the list of deployed aspects after refactoring.
Comment 3 Alexandre Vasseur CLA 2005-05-03 04:46:42 EDT
ha you are raising several issues in once..

1/ - aspect in aop.xml not found issue: yes, we will do fine grained error
reporting, all that handled in a proper way. Branch is an alpha.

2/ - special cases: yes there are some. f.e. a cglib proxy can be a class whose
name is "null" when passed thru this LTW chain, and thus should be skept. I had
some special case for JDK proxy as well in AW. If you know how to reproduce
scenario fot the one you spot (the 2 special classloaders) please attach that to
the issue.

3/ - you wrote "NOT as an environment variable/system-wide default.". Perhaps
the sample in the branch was confusing. LTW will allow multiple aop.xml to be
packaged in META-INF/aop.xml classpath entries. The "system wide" option is
usefull for testing mainly, it main not survive the GA.
So lets take a concrete scenario. I have a tomcat, whose installation path has
an aop.xml with aspect "A". Then I have a webapp.war, with a
webapp.war/classes/META-INF/aop.xml with aspect "B". The aspect class B can be
in the webapp or in the tomcat classpath, and the behavior will be as per
regular J2EE like packaging rules.
In such a case: tomcat classes will be presented to aspect A. Webapp classes
will be presented to aspect A and B.
Please go on with this sample to illustrate this "aspectpath" idea, and remember
off course that we - AspectJ - don't control at all the webapp classloader
classpath handling. This is only a Tomcat duty, and we don't want to interfere
with that. This means that if aspect B is not found from the webapp classloader,
we will issue a warning and go on (as per comment 1/).

4/ you wrote "My use case is indeed focused on supporting weaving into VMs with
non-trivial classloader hierarchies".
Your use case seems to perfectly apply to the idea of having several aop.xml.
You should split the big sole one you currently have and organize them as per
where you deploy each aspect in each classloader. This is precisely the use case
we have addressed thru AspectWerkz laod time weaving architecture for more than
2 years: how to address LTW in non trival classloader hierarchies, dealing with
system wide aspect and application deployed aspects.
A further iteration of LTW should demonstrate use of it under an OSGI based
classloader hierarchy. It should be trivial and will stay consistent with this
webapp scenario, I ll write about it later.



Comment 4 Ron Bodkin CLA 2005-05-03 12:52:41 EDT
Re: 2, I ran into the 2 special cases I mentioned in testing. I will try to 
narrow them down to self-contained test cases.

Re: 3, I know that aop.xml lets you specify configuration for a given 
classloader; I wanted to clarify that I recognized this in my request... I 
just managed to get the LTW to work by putting aop.xml on the VM's start up 
classpath instead of using the -Daj5.def option, which works much better (at 
least for now)! There was a small bug (apparently there's no leading / in the 
string for ClassLoader.getResources), so I will submit that & the patch... 

To take your example with my aspectpath proposal the root aop.xml look 
something like this:

Assuming A is weaving at the system-level (i.e., it weaves into bootstrap.jar):

<aspectj>
    <weaver options="-showWeaveInfo -proceedOnError -verbose"> 
        <include within="*..*"/>
        <exclude within="*..*CGLIB$*"/>
        <exclude within="$Proxy**"/>
    </weaver>
    <aspectpath>
        <!-- see here nested class with ".", "$" is accepted as well -->
        <entry jar="containsA.jar"/>
    </aspects>
</aspectj>

In the Webapp, aop.xml looks like:
<aspectj>
    <weaver options="-showWeaveInfo -proceedOnError -verbose"> 
        <include within="*..*"/>
    </weaver>
    <aspectpath>
        <entry jar="WEB-INF/lib/containsB.jar"/>
    </aspects>
</aspectj>

To me, the aop.xml for the root classloader should always apply (i.e.,
weaving should delegate in the same way that classloading does). Do I 
understand correctly, that you want to require the webapp aop.xml to 
*explicitly* include aspect A, rather than automatically weave it since it's 
woven in the parent's aop.xml? Is this necessary?

>Your use case seems to perfectly apply to the idea of having several aop.xml.
>You should split the big sole one you currently have and organize them as per
>where you deploy each aspect in each classloader. This is precisely the use 
case
>we have addressed thru AspectWerkz laod time weaving architecture for more 
than
However, I want to have a common policy so I deploy the same aspects to all 
the applications on a server, not have to configure each application to add a 
new aop.xml entry at deployment time... I don't think having more than one 
aop.xml is going to help in my case. Whether I list the one jar that has the 
aspects I'm weaving or enumerate all the aspects in the jar, I have to 
configure the same amount of information.

I agree about supporting OSGI too (we're actually planning to use it to allow 
dynamic plugins)...
Comment 5 Alexandre Vasseur CLA 2005-05-03 13:07:25 EDT
Yes, no need to list aspect A in webapp' aop.xml since A is listed in server
aop.xml. We do that.

The xml "<aspect exclude.." may allow you to "turn off" A in the webapp but I
don't think it is good , though it can help skeptical to turn off all the
aspects without looking around for aop.xml in the whole classloader hierarchy.

As per the xml "<entry jar=.." proposal, we are back to the question: if I find
an aspect in there, how can I make sure this given jar does belong to the
deployed app classpath ? That would mean we would 1/ look in the jar thru the
file system (thus we would require absolute path or ?? you don't tell me a lot
about that.), 2/ find all the aspects, and 3/ see if those are visible and not
already registered in the current weaver classloader. If the aspect is not found
in the current weaver classloader, this means you gave me a path that does not
belong to the webapp) so I will discard the aspect (with a warning lets say).
One question is then: if i pack my webapp in webapp.war as everyone does, what
will exactly be this path ?, and are you sure it works in any webapp container
(or actually any classloader based deployer) ?

To me I think it is much more an app server issue ie an app server impl. could
do that (f.e. put this jar in the weblogic-web.xml or weblogic-application.xml
of an ear and thus do what is needed for it to be part of the app classloader
classpath (precisely what we can't do), then invoke officially published AJ API
(back to aspectpath but in a controlled way)).
What do you think ? Someone can perhaps work on that for all the OSS container
around (webapp and ear) ?

For patch, that 'd be great but perhaps avoid submitting for stuff based on the
branch since I am in the middle of putting that LTW into head. I hope to have
something to play with in head shortly.
Comment 6 Ron Bodkin CLA 2005-05-03 13:34:35 EDT
Ok, I understand why my idea would be at least a bit messy: it would involve 
opening the given path entries up front in registerAspects, and then loading 
every type in the path, detecting which ones are aspects, and then adding 
those. That does seem heavyweight.

I now see why you want an explicit list of them. Here's an idea: what if there 
were a separate MANIFEST-INF/aspects.mf file you could reference as a resource 
from aop.xml, that AspectJ5 could generate when it builds. Then it would be 
easy to package up the aspects in a jar and pick them all up, without having 
the load-time weaver do all this redundant work...

A first step on this line could be a simple generator tool that takes a path 
and builds a list of aspects that are in it...

I thought that the aop.xml files follow delegation rules; I'm glad to hear it. 
I agree that using exclude to exclude parent classloader aspects is generally 
a bad idea.

If I we have a good way of specifying path entries, I'd want to be able to 
include something like webapp.war!WEB-INF/lib/trace.jar
Comment 7 Matthew Webster CLA 2005-05-05 12:33:38 EDT
I don’t believe there should be any significant change to the current aop.xml 
specification. What we should provide, perhaps in the AspectJ 5 Developer’s 
Notebook, is a detailed set of scenarios with the accompanying LTW 
configuration.  I also think we need a new compiler option (something that was 
discussed but didn’t make it into the documentation) that automatically 
generates an aop.xml containing the names of all the concrete aspects.

Using inpath and aspectpath with a batch compiler is fine because there is 
just one class loader, the configuration simple (JARs and classes on disk) and 
you control the whole process. The LTW configuration can make no assumptions 
about what class loaders are used, how they are arranged and how they are 
configured: an aspectpath makes no sense in an OSGi environment (I know, I 
tried it)! In fact the whole idea of a path makes no sense, we just have 
visibility: the need for inpath is avoided by scoping your aspects correctly, 
packaging aspect libraries in the right place WRT the target application 
and/or using include/exclude in aop.xml. I did some use case analysis when 
writing the specification with Alex (that also didn’t make it into the 
documentation) where I found several users of the system (aspect writer, 
application writer, sysadmin, …) all of whom can be different people. The way 
LTW is configured reflects this need.

Let me briefly describe 2 separate scenarios: one where an aspect, perhaps for 
problem diagnosis, is to be applied to all applications without their explicit 
knowledge, the other where an application selects the aspects it needs.

1.	Create an aspect library containing a concrete tracing aspect and the 
accompanying aop.xml that declares it. Add it to the runtime with sufficient 
visibility (i.e. high enough up the class loader hierarchy in a traditional 
system) that it will affect the applications but low enough that it won’t 
target the JDK or the middleware (unless you want it to). Use good old 
fashioned pointcuts to limit the scope. Keep it simple: one concrete aspect 
per library with accompanying function or group according to purpose.
2.	Create an aspect specific to a particular application either as a 
standalone or one that extends an abstract aspect already available in the 
runtime. You can use code-style or XML to define the concrete aspect. Package 
the aspect, perhaps in its own JAR, with the target application i.e. WAR/EAR 
file.

BTW I have successfully tried both scenarios in an OSGi environment with the 
current version of AspectJ LTW.
Comment 8 Alexandre Vasseur CLA 2005-05-30 05:30:12 EDT
closing, nothing to do there.
Comment 9 deng kun CLA 2006-11-07 19:27:16 EST
I don't understand how this bug can be closed just like that. 

I'm learning and trying to adopt AOP to my programming experience. Here is what happened when I tried to use contract4j aspect library with aop.xml. 

After several days of tweaking and testing, I found out that I need to enumerate all the aspects defined in contract4j to get it working with aop.xml!  
This is a little ridiculous! 

Shall I blame the guy who developed contract4j for not providing one single aspect  for his library? Shall I blame that aspect is so difficult for beginners to adapt?

Comment 10 Matthew Webster CLA 2006-11-08 04:39:11 EST
This report was closed because there were no posts for a month. The raiser failed to convince the AspectJ team that the enhancement was either sufficiently compelling or devoid of serious drawbacks. In fact Ron concedes this fact and makes another suggestion to automatically generate the list of aspects, something that has now been implemented in Bug 95516 and documented here http://www.eclipse.org/aspectj/doc/released/devguide/ajc-ref.html.
Comment 11 deng kun CLA 2006-11-08 05:16:44 EST
(In reply to comment #10)
> This report was closed because there were no posts for a month. The raiser
> failed to convince the AspectJ team that the enhancement was either
> sufficiently compelling or devoid of serious drawbacks. In fact Ron concedes
> this fact and makes another suggestion to automatically generate the list of
> aspects, something that has now been implemented in Bug 95516 and documented
> here http://www.eclipse.org/aspectj/doc/released/devguide/ajc-ref.html.
> 

thanks for explaining the reason why this bug is closed. I personally insist that this bug should be reopen. It's ok to call the fix an enhancement, and I believe it's a  very important enhancement. I am saying this in terms of my real learning experience.  

AspectJ should be made easier for those jave developers without a lot of experiences in aspect oriented programming. LTW is one giant step toward this end, but having to enumerate all aspects explicitly seem to be a joke. 

The contract4j aspect library contains more than 10 aspects. they are packaged in one jar file, I am not sure  whose responsibility is to unpack the jar file and find out what these aspects are, and put them into aop.xml. I am not sure the auto generate list of aspects is applicable as well, because I intended to use those aspects as blackboxes. Withe the java 5 annotation, when I compile my code and I don't even need those aspects on my build path.  In one word, I want to be unaware of the existence of aspects as much as possible!

Please give comments!  
Comment 12 Barry Kaplan CLA 2006-12-22 09:34:26 EST
Is there a reason why contract4j doesn't provide an aop.xml listing its aspects? 
Comment 13 Matthew Webster CLA 2006-12-22 11:30:06 EST
Comment #12

They do. If you download contract4j5_060.zip you will find an aop.xml.
Comment 14 Matthew Webster CLA 2006-12-22 12:32:29 EST
> thanks for explaining the reason why this bug is closed. I personally insist
> that this bug should be reopen. It's ok to call the fix an enhancement, and I
> believe it's a  very important enhancement. I am saying this in terms of my
> real learning experience.  
> AspectJ should be made easier for those jave developers without a lot of
> experiences in aspect oriented programming. LTW is one giant step toward this
> end, but having to enumerate all aspects explicitly seem to be a joke. 
> The contract4j aspect library contains more than 10 aspects. they are packaged
> in one jar file, I am not sure  whose responsibility is to unpack the jar file
> and find out what these aspects are, and put them into aop.xml. I am not sure
> the auto generate list of aspects is applicable as well, because I intended to
> use those aspects as blackboxes. Withe the java 5 annotation, when I compile my
> code and I don't even need those aspects on my build path.  In one word, I want
> to be unaware of the existence of aspects as much as possible!
> Please give comments!  

Could you please explain exactly what problem you are experiencing and then perhaps we can help you. 
Comment 15 deng kun CLA 2006-12-22 18:19:35 EST
an aop.xml is provided, however, it was not built into the jar file for some reason. I fixed the problem finally by adding it to that jar file. 


However,  perhaps you already have noticed, even in jdk6, javac starts to support "wildcard" style classpath.  I am not sure how you think of it. 
Comment 16 Matthew Webster CLA 2007-01-04 09:50:27 EST
(In reply to comment #15)
> an aop.xml is provided, however, it was not built into the jar file for some
> reason. I fixed the problem finally by adding it to that jar file. 
> However,  perhaps you already have noticed, even in jdk6, javac starts to
> support "wildcard" style classpath.  I am not sure how you think of it. 

I have read Mark Reinhold's blog entry. This feature seems little more than fluff for configuring the system classpath perhaps only when running from the commmand line. It may appear to make things easier for the user but addresses none of the serious issues described in this bug such as whether the configured classpath is visible to to application being woven or whether the classpath contains JARs not EARs, WARs or something more proprietary that AspectJ cannot read.