Community
Participate
Working Groups
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.
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 ?
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.
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.
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)...
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.
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
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.
closing, nothing to do there.
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?
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.
(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!
Is there a reason why contract4j doesn't provide an aop.xml listing its aspects?
Comment #12 They do. If you download contract4j5_060.zip you will find an aop.xml.
> 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.
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.
(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.