Since release 1.0 AspectWerkz support to
AspectSystem alongside the deployed applications and the container
in which those are deployed. As described
here, you need to write an
AOP XML deployement descriptor for your aspects, that declares the
Aspects to use, and defines or refines the pointcuts (where to do) and advices (what to do), no matter your Aspects are using an annotations based
definition or a full XML defintions, or both.
aop.xmlfile, you need to remember that the declared Aspects will affect the classes visible from the
ClassLoaderthat can access this file. For example if you package this file in
application.war/WEB-INF/aop.xml, it will affect all web-application classes, third parties libraries from
application.war/WEB-INF/lib/and all JSPs. If you want to affect all JVM classes, you can use the JVM option
-Daspectwerkz.definition.file=path/aop.xml, or better have one or more
META-INF/aop.xmlfile(s) accessible from the JVM regular classpath. It is thus possible to organise your aspects alongside all your deployed applications, while allowing some interesting schemes: a tracing Aspect deployed at the JVM level will affect all deployed applications, while Aspects deployed within the application itself will only affect this application. If you plan to use offline mode, you need to post process your application as many time as you have aop.xml files, and still packaged the aop.xml file(s) alongside the application and/or at a JVM wide level, depending on what you want to achieve. To summarize, you have to remember that an
WEB-INF/aop.xmlfile will affect the classes loaded by the classloader(s) that have this aop.xml file in their path. The JVM wide aop.xml file will affect the system classloader and all child classloaders.
You should be familiar with the way Java handles ClassLoader isolation to fully understand how to deploy your own Aspects.When you are invoking a
mainmethod of a Class, this class is loaded (and lives) in the System ClassLoader. All classes belonging to a path specified with a
-classpathJVM option will live in this ClassLoader. If this class is using
java.*classes, those have been loaded (and live) in Extension ClassLoader or Bootstrap ClassLoader. The
java.lang.Objectcan be seen and used by your main Class since the System ClassLoader is by convention a child of the Extension ClassLoader which is himself a child of the Boot ClassLoader. This relation looks like this:
When you are using an application server, there are usually many other classloaders. A simple view is to say that there is one classloader per deployed application (that's why you don't need to add your war file in the JVM classpath right ?). In fact the picture is a bit more complex to allow JSPs changes while the application is running etc. Those application ClassLoaders are child of upper ClassLoaders like the System ClassLoader, but if you deploy two war files, they cannot share classes unless thoses classes are in an upper ClassLoader. If we deploy two war file in a Tomcat we will end-up in the following (simplified) organization:Boot ClassLoader (JRE / JDK classes) | Extension ClassLoader (JRE extension, like SSL security etc, in jre/ext directory) | System ClassLoader (your main Class, and all the -cp / -classpath jars and classes)
Boot ClassLoader (JRE / JDK classes) | Extension ClassLoader (JRE extension, like SSL security etc, in jre/ext directory) | System ClassLoader (the Tomcat main Class, and all the -cp / -classpath jars and classes) | Some Tomcat specific ClassLoader (does not really matters) | | First.war ClassLoader Second.war ClassLoader | | WEB-INF/lib WEB-INF/lib and WEB-INF/classes and WEB-INF/classes ClassLoader ClassLoader for Second.war | | | | | JSP ClassLoader(s) JSP ClassLoader(s)
For J2EE / EJB based application, the schemes is a bit more complex but follows the same model.
Although this kind of organization is mainly J2EE oriented, some Swing based application are using ClassLoader parent-child relation to allow for example plugin life cycles etc.
The single idea you need to remember is that AspectWerkz deployed Aspects thru aop.xml files have the scope of the ClassLoader that has this file in its path and all its child ClassLoader(s).
Three specific paths are used:
-Daspectwerkz.definition.file=path/aop.xml, it impacts all JVM classes (except boot classloader for convenience). Note that it is not mandatory to name the file aop.xml
WEB-INF/aop.xml, it will impact the classes of the web application including JSPs. It is mandatory to name the file aop.xml
META-INF/aop.xml, it will impact the classes that can see this file. It is mandatory to name the file aop.xml
path/META-INF/aop.xmlin the JVM classpath (
-cp path/;...) to have the same scope as the JVM wide defined one.
META-INF/aop.xmlfile, it will aslo have the same scope.
aop.xmlfile. With this model, it is thus possible to package a tracing aspect in a jar file, with a
META-INF/aop.xmlfile (with a pointcut for all public method execution f.e.) and just add it to your classpath to allow a very simple generic tracing !
aop.xml file can declare several
Aspect Systems for convenience. All will have the same weaving scope. The goal is mainly to
have a well organized namespace for organizing your aspects.
precedence will follow the order of the
<system> elements in the XML file.
Each system must have a unique id within a ClassLoader hierarchy, as defined with
system idis using the application name and a path as a mnemonic, allthough it could be any string.
<aspectwerkz> <system id="First.war/WEB-INF/FirstSystem"> <package name="examples"> <aspect class="caching.CachingAspect" deployment-model="perInstance"/> </package> </system> <system id="First.war/WEB-INF/SecondSystem"> <aspect class="examples.trace.TracingAspect" deployment-model="perJVM"/> </system> </aspectwerkz>