Note for 2.0.x

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.

Introduction

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

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:

  • The first three methods are for deployment of annotation defined aspects only and the last three for XML defined aspects (that can have annotations as well, if so then the XML definition will override the annotation definition, but apart from that they will merge).


  • As you can see all methods returns a DeploymentHandle, read more about that in the section about deployment handles below.


  • The class loader passed to the method is the class loader that you want the aspect to be deployed in. If no class loader is specified then it will use the loader that loaded the aspect class. (Note: the algorithm will not handle importing classes from one class loader to another so they need to be in the same hierarchy.)


  • It is recommended that you pass a DeploymentScope to the deploy method if you want predictable and safe deployment. For details, see the section on deployment scopes below.

Hot undeployment

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:

  • You can undeploy an aspect by just specifying the aspect's class. This means that the aspect will be undeployed from the class loader that has loaded the aspect class.


  • If you specify a class loader then the aspect will be undeployed from the class loader that is specified.


  • If you specify a 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.


  • If an aspect that is being undeployed can not be found (e.g. is not deployed or is already undeployed) then nothing happens. No error is triggered.

Deployment scopes

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");
                

Deployment handles

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);