Dynamic AOP requires AspectWerkz native library in
PATH
to be able
to work when you are not using Java 5. This is not needed when running Java 5 and the -javaagent startup option.
This means that to make use of the any dynamic feature, such as runtime deployment
or undeployment, you need to have the AspectWerkz native library (*.dll, *.so or *.jnilib) in your
PATH
.
These can be found here.
This is not needed when running Java 5.
AspectWerkz
supports both hot deployment and hot undeployment of aspects.
It utilizes HotSwap (Java 1.4) or JVMTI (Java 5) to redefine your application at runtime.
New aspects can be added to the running system and old ones can be redefined or removed at runtime.
All these services are accessed from the
org.codehaus.aspectwerkz.transform.inlining.deployer.Deployer
class, which has a rich
set of services.
Hot deployment of aspects is done using one of the
Deployer.deploy(..)
methods.
Here is the API for deployment of aspects (see details below):
DeploymentHandle deploy(Class aspect) DeploymentHandle deploy(Class aspect, ClassLoader deployLoader) DeploymentHandle deploy(Class aspect, DeploymentScope scope, ClassLoader deployLoader) DeploymentHandle deploy(Class aspect, String xmlDef) DeploymentHandle deploy(Class aspect, String xmlDef, ClassLoader deployLoader) DeploymentHandle deploy(Class aspect, String xmlDef, DeploymentScope scope) DeploymentHandle deploy(Class aspect, String xmlDef, DeploymentScope scope, ClassLoader deployLoader)
Details on the deployment API:
DeploymentHandle
, read more about
that in the section about deployment handles below.
DeploymentScope
to the
deploy
method if you want predictable and safe deployment. For details, see the section on deployment
scopes below.
Hot undeployment of aspects is done using one of the
Deployer.undeploy(..)
methods.
Here is the API for undeployment of aspects (see details below):
void undeploy(Class aspect) void undeploy(Class aspect, ClassLoader loader) void undeploy(DeploymentHandle deploymentHandle)
Details on the deployment API:
DeploymentHandle
then all join points that where affected by
the deployment event defined by the handle will be reverted to the state they where in
before the deployment occured. This means that
you need to keep track of order and
dependencies etc. e.g. f.e. rollback all changes in the correct order etc.
The use of deployment scopes give you more predictable and safer deployment.
They are needed due to the fact that no JVMs today support schema redefinition when redefining your classes.
This means that you have to define a special kind of pointcut that we call deployment scope, which will prepare you application and advise the points that you are interested in doing hot deployment on later.
You can then retrieve a handle to this deployment scope by getting the actual instance of the abstraction and then use this to narrow down the scope of the deployment so you are sure that you will not try to deploy the aspect at points in your code that will not be affected. Hence you are garantueed that your aspect will be deployed at valid points in your code.
Definition
You define the deployment scope just as regular pointcuts, in its own aspect or in the same aspect as the rest of your code:
@Expression("execution(String *.toString())") DeploymentScope toString;
<deployment-scope name="toString" expression="execution(String *.toString())"/>
Runtime retrieval
You can then retrieve the instance of the
DeploymentScope
like this:
DeploymentScope scope = SystemDefinition.getDefinitionFor(loader, systemId).getDeploymentScope("toString");
All
deploy(..)
methods returns a
DeploymentHandle
which is a handle to
the specific deployment event. You can use this handle to revert the changes made by the deployment,
In other words, it allows you to undeploy the aspect you deployed and be sure that it will be
undeployed exactly the way it was deployed, same class loader, same deployment scope etc.
You retrieve it from one of the
deploy(..)
methods and can later use it when
undeploying the aspect:
// deploy aspect DeploymentHandle handle = Deployer.deploy(..); // store the handle somewhere ... // retrieve the handle from storage DeploymentHandle handle = ... // undeploy using handle Deployer.undeploy(handle);