Since release 1.0 AspectWerkz support to
configure several
AspectSystem
alongside the deployed applications and the container
(application server)
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.xml
file, you need to remember that the declared Aspects will affect
the classes visible from the ClassLoader
that 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.xml
file(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
META-INF/aop.xml
or
WEB-INF/aop.xml
file 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 amain
method of a Class, this class is loaded (and lives) in the
System ClassLoader. All classes belonging to a path specified
with a
-cp
or
-classpath
JVM option will live in this ClassLoader.
If this class is using
java.lang.Object
and other
java.*
classes, those have been loaded (and live) in
Extension ClassLoader
or
Bootstrap ClassLoader.
The
java.lang.Object
can 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:
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)
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 (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.xml
in the JVM classpath (
-cp path/;...
) to have the same scope as
the JVM wide defined one.
META-INF/aop.xml
file, it will aslo have the same scope.
aop.xml
file.
With this model, it is thus possible to package a tracing aspect in a jar file, with a
META-INF/aop.xml
file (with a pointcut for all public method execution f.e.)
and just add it to your classpath to allow a very simple generic tracing !
A single
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.
The
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 id="some/system">
system id
is 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>