This section describes the difference between an advice and an advice instance. Advice is a design-time concept whereas Advice Instance is a run-time concept. An advice defined at design-time in an aspect XML file, has a configuration that includes a reference to a point cut. At run-time, one advice instance is created for every join point that is selected by the point cut. Unless Scoping is specified this is the default behavior. For details refer to,
Scopes.
Figure 3 shows an advice that gets instantiated and injected before all activities. Since the process has three activities, three advice instances are actually created at run-time.
At run-time, the TIBCO ActiveMatrix BusinessWorks engine may not always create three DocumentLogger instances.. This mainly depends on the scope attribute of the
DocumentLogger class.
If the scope is "Application", only one java object instance of DocumentLogger is actually created at run-time per TIBCO ActiveMatrix BusinessWorks application. This is very important to understand since it represents the key difference between an advice instance and an advice implementation instance.
The instance of the advice implementation (such as the object of the java class that provides the implementation of the advice) is not the same as the advice instance. Three advice instances may in fact share the same advice implementation java object instance.
Figure 4 shows two advice instances sharing the same advice implementation instance.
Advice implementations (i.e. Java classes) can define configuration properties. These properties provide a way for advices to configure the execution of their associated Java class. This is very useful especially when different advices that share the same implementation, want to execute it using different parameter values. For details about how advice implementations can define configuration properties, refer
Advice Implementation Properties.
For each configuration property defined in the advice implementation there can be a value set in the advice configuration. If an advice implementation property is not set in an advice, the default value that is specified in the java class, if exists, is used.
Each advice has a <properties> element that contains these property values.
<activity where = "Before">
<implementation.java className = "com.tibco.bw.poa.samples.JMSPropertyChangerWithConfig"/>
<property name = "propertyToModify">Bar</property>
<property name = "propertyToModifyValue">BarValue1</property>
In this case, the advice implementation (i.e. the JMSPropertyChangerWithConfig java class) defines two configurable member variables:
These two properties are visible and configurable from an advice, in this case Advice1. The
@name attribute of the
<property> element
must match the name of the advice implementation property. If a match is not found, the BW Engine throws an
AspectException at the time the engine gets initialized.
<activity where = "Before">
<implementation.java className = "com.tibco.bw.poa.samples.JMSPropertyChangerWithConfig"/>
<property name = "propertyToModify">Bar</property>
<property name = "propertyToModifyValue">BarValue2</property>
<activity where = "Before">
<implementation.java className = "com.tibco.bw.poa.samples.JMSPropertyChangerWithConfig"/>
<property name = "propertyToModify">Abc</property>
<property name = "propertyToModifyValue">Xyz</property>
Advices get injected in processes based on the point cuts that are associated with them. At run-time multiple advices can be injected in the same join point. Sometimes, the order in which these advices get executed is very important and needs to be controlled by the Aspect Developer. The BW engine executes the advices in a specific order, which is computed based on a priority order associated with each advice.
Executing of advices also depends on the process execution flow; which decides the availablity of input or output XML document which is to be used by the advice.
Since the advices that are injected in a specific join point can be specified either in the same or in different aspect files, the priority order of an advice is computed based on:
1.
|
The value of the @order attribute that is specified on the aspect that defines the advice.
|
The optional @order attribute that can be specified on an aspect is used to establish a priority order between different aspects that are applied to a BW project. All advices defined in the same aspect share the same
@order attribute value. This value can range between 1 and 255. The lower the number the higher the priority of the aspect. If the
@order attribute is not specified, 255 is used by default, which means that the aspect has the lowest priority.
|
Although the @order attribute is xsd:unsignedByte, 0 is an invalid value. A validation error is thrown if used.
|
The order in which the advices are specified in an aspect file is very important. The BW engine uses this order to execute the advices that are run when a specific event occurs. This is true regardless of the event (for example, before executing an activity, after an activity returns successfully, and so on). For example, if a target activity throws an exception and there are "after" advices as well as "after throwing" advices injected after the target activity, the order in which these advices execute is influenced by the order in which they appear in the aspect file.
Figure 5 shows two aspect definitions - Aspect-1 and Aspect-2, each one defining a few "
Before" advices. The order of Aspect-1 is "2" and the order of "Aspect-2" is 1, which means that Aspect-2 has a higher priority order than Aspect-1.
Assume that the order in which these advices appear in the aspect definitions is exactly the other in which they are shown in this diagram (For example, A is before B, C is before D, and D is before E).
Figure 6 shows that after evaluating the point cuts associated with these advices, the BW Engine injects these two aspects before a specific activity of a process.
Since Aspect-2 has a higher priority than Aspect-1, all its "Before" advices will execute before the advices defined in Aspect-1. The order of execution of the advices defined in the same aspect is given by the order in which they appear in the aspect XML file. Therefore, the order in which these advices get executed is shown in
Figure 7.
The advices that are injected in a specific join point execute always in sequence. As shown in
Advice Ordering, the order in which these advices execute is computed based on the way the aspects are configured as well as the type of the join point.
It is important to note that an advice always has access to the XML Document as well as the Process Context that is available in the join point where it is injected. The Process Context can provide access to other XML documents that were contributed by the previous activities (such as activities that executed before the join point).
•
|
The XML Document that is passed to a "Before" advice is the same XML Document that had been passed to the target activity, if the advice was not injected in the process. The advice can alter the document but it cannot change its structure. The XML Document that is produced by the advice must be valid against the same schema (such as the schema of the input element), which is defined by the target activity. The same rule applies to all the subsequent advices that are inserted in the same join point. This means that all the XML Documents that flow through all the " Before" advices that are injected in the same join point share the same schema. This is shown Figure 8.
|
In Figure 8, the File-Read-Activity's input type is T1. The advices that are injected before this activity receive at run-time the XML Documents, that are valid against the same schema (such as, they are instance of T1).
•
|
The XML Document passed to an "After Returning" advice is the XML Document that is generated by the target activity, if the activity has an output type or it is a null object otherwise. The advice can alter the document but it cannot alter its structure. The XML document that is produced by the advice must be valid against the same schema (such as, the schema of the output type), which is defined by the target activity.
|
Since an activity can report multiple exception types, an "After Throwing" advice has to support multiple XML schema types, which usually makes it difficult to develop. If an advice is interested in a particular exception type, it can use the
@exceptionType attribute to specify its
QName. The value of this attribute has the following format:
In such cases, the advice is executed only when an exception instance of that type is thrown by the target activity. All the subsequent advices that are inserted in the same join point follow these rules. The "
After Throwing" advices should not throw back the exception that is passed to them. Instead, they should return the exception message when they finish executing.. If an exception is thrown by an "
After Throwing" advice, the engine treats it as any other exception thrown by other types of advices.
Figure 10 shows an example of two "
After Throwing" advices.
•
|
The XML Document that is passed to an "After" advice represents either the output of the target activity or one of its exceptions. The advice can alter the document (for example, change the output message, change the exception message, and so on) but it cannot alter its structure. The XML document produced by the advice must be valid against either the schema of the output XML document or the schema that describes the exception thrown by the activity. This basically means that the same type of document that is passed to an " After" advice is passed to any other subsequent " After" advices that might run in the same join point. While writing an " After" advice a developer should be careful since it needs to handle different semantics (for example, successful returns as well as multiple exception types).
|
An "After" advice cannot use the
@exceptionType attribute to register its interest in a particular exception type. If an exception is thrown by an "
After" advice, the BW engine treats it as any other exception thrown by other types of advices.
Figure 11 shows an example of two "
After" advices.
Any exception thrown by an advice is propagated as a RuntimeException and handled by the BW engine as thrown by the target activity. The engine processes it based on the business logic defined in the process containing the target activity.
This section describes the structure of an aspect JAR and the deployment process of
aspect libraries.
An aspect JAR is a JAR file that contains a file with the "
.AMF" (Aspect Manifest File) extension in the
META-INF folder.
There can be only one file with the ".AMF" extension in that folder.
The Aspect Manifest File contains information about where all the aspects are located inside the aspect JAR file. These locations can be specified in two ways:
•
|
By specifying a folder name inside the JAR file. All aspects that are part of that folder will be loaded by the BW engine. The BW engine will not locate aspects in the subfolders. The root folder is specified using "" (which is an empty string).
|
•
|
By specifying the full name (like including the folder location) of an individual aspect inside the JAR file.
|
The AMF file is an XML file that must be valid against the Aspect Manifest File XML Schema. When loading an aspect JAR file, the BW engine validates the Aspect Manifest File against this schema. If validation errors are found, the BW engine throws an
AspectException.
<aspectsFolder>...</aspectsFolder>*
A JAR file that contains aspects but does not contain an Aspect Manifest File, is not recognized by the BW engine as an aspect JAR. Hence none of the aspects defined in that JAR are loaded by the BW engine.
<aspectsFolder>auditAspects</aspectsFolder>
Then only Aspect1.bwaspect and
Aspect2.bwaspect are loaded by the BW engine. The aspects specified in the ExternalMessages folder are not loaded.
<aspectsFolder>auditAspects</aspectsFolder>
<aspectsFolder>auditAspects/ExternalMessages</aspectsFolder>
all the aspects defined in this aspect JAR are loaded by the BW engine. The same behavior could be accomplished by specifying some or even all of the aspects individually. For example, the following manifest file would have the same result as the previous one:
<aspect>auditAspects/Aspect1.bwaspect</aspect>
<aspect>auditAspects/Aspect2.bwaspect</aspect>
<aspectsFolder>auditAspects/ExternalMessages</aspectsFolder>
Multiple aspect JARs can be deployed in a BW Engine. When the engine starts up, all these aspect JARs are loaded and their aspects are weaved into the BW Project.
Same in the case of folders specified inside aspect JARs, the BW engine does not look at sub-folders when loading aspect JARs. The engine loads only the JARs that are part of this top level folder.
The engine writes out information about all advices that are woven in the TIBCO ActiveMatrix BusinessWorks project. For each process, the engine analyses the advices that are configured to be woven and skips the ones that cannot be woven due to product limitations. After finishing weaving of a process, the engine logs out all advices that were skipped. For more information about the advices that cannot be skipped, read the release notes or contact TIBCO Support.