Section 31.3. APPLICATION AWARENESS USING ASPECT ORIENTATION


31.3. APPLICATION AWARENESS USING ASPECT ORIENTATION

Application-aware platforms pose interesting challenges to the application designer. For example, intercepting the communication between devices translates into dynamically adding crosscutting functionality for all incoming and outgoing messages for various communication protocols (remote invocations, web services, etc.). The case is similar for expressing coordinated processing, where the body of a large number of application methods must be bracketed at runtime with transactional functionality. Similarly, fine granularity logging may require recording the state of each robot; this task implies capturing the changes to a large number of fields and propagating updates to a nearby database.

Building an application-aware network using traditional software development techniques is hampered by the lack of support for (1) expressing crosscutting concerns and (2) expressing run-time extensions. In previous work [18, 19, 21, 23], we argued that aspect-oriented programming can make this task significantly easier to solve. In particular, we have identified the following requirements to an AOP platform to be suitable for application awareness:

  • Extending the functionality of a running application by dynamically injecting the behavior appropriate to the current location (or networking environment)

  • Extending multiple applications running on separate nodes of a network (e.g., to ensure they can later interoperate)

  • Gracefully dealing with new nodes entering or leaving the network by dynamically applying extensions addressing crosscutting changes

  • Making adaptations secure by providing the appropriate protection from malicious services that may use application awareness as a trapdoor for getting access to sensitive local data

With these requirements in mind, we propose dynamic AOP as the most appropriate way to design application awareness. Dynamic AOP is the ability of an AOP platform to weave and unweave aspects to/from applications at runtime without interrupting operations. Dynamic AOP allows one to model the extensions (e.g., as described in the production hall scenario) as aspects.

31.3.1. Design Alternatives for Dynamic AOP

In a Java-based application, the application code passes several stages before being executed. First, the sources are compiled, and corresponding class files are produced. Class files are loaded at runtime into the Java Virtual Machine (JVM). Loading implies that the code is verified for well-formedness and then transformed into a JVM-internal format. In a further, optional, step, the code is compiled using a Just-In-Time (JIT) compiler into the native language of the current host where it is executed.

Depending on when weaving is done, we distinguish between compile-time weaving (see Figure 31-2 (a) ), load-time weaving (see Figure 31-2 (b) ), or JIT-time weaving (see Figure 31-2 (c) ). Compile-time weaving currently offers extended support for application development [4]. However, load-time and JIT-time weavers are more appropriate for expressing run-time changes, as these weavers provide "late" binding of aspects and application classes and allow extending an already running application. In addition, they do not require the source code of the original application. Load-time platforms like JAC [16] and Hyper/J [32] and run-time weavers like PROSE [21] offer preliminary support for this type of adaptation.

Figure 31-2. (a) Compile-time weaving, (b) Load-time weaving, and (c) JIT-time weaving.


Since most of the modern JVMs [29, 30] use a JIT compiler, let us consider in more detail a JIT-time weaver (Figure 31-2c) that instructs the JIT-compiler to insert advice code when transforming the bytecode into native code. Figure 31-3 (a) illustrates how the weaving process works. We consider weaving the advice defined by an aspect A through the code of an application class C that declares two methods foo and bar. For simplicity, we consider the case that A specifies the weaving of the code print("enter") before all executions of C.foo. When translating C's bytecode into native code, the JIT compiler adds the code for print("enter") (in bold characters in the figure) at the beginning of the code corresponding to foo.

Figure 31-3. (a) Full-code weaving and (b) Stub weaving.


So far, we have implicitly assumed that the actual advice code is woven at the matching join points. We denote this approach as full code weaving and the corresponding weavers full-code weavers. What happens if an aspect A must be woven after the bytecode-loading and JIT-ing is over? JIT-time weavers would have to recompile all classes and methods that contain affected join points. Similarly, load-time weavers would have to unload and reload all classes containing join points for A. To avoid this problem, a dynamic weaver can add minimal hooks (or stubs) instead of the advice code. Stubs must be woven at all potential join points in C's code (such as field changes, method boundaries, exception throws and handlers, etc.). Figure 31-3 (b) illustrates this situation. Unlike in Figure 31-3 (a), only two lines of code have been added to at the beginning of the native code corresponding to foo. Every time foo is called, the weaver component is notified (step 1). When this happens, the weaver checks whether any advice must be executed and eventually executes all advices corresponding to the reached join point (step 2). This approach is taken, for example, by JAC [16] and Handiwrap [5]. We denote this second type of weavers as stub weavers. Stub weavers may lead to a significant increase of the resulting code size (since code is added at locations where no advice is needed). Stub weavers are less efficient than full-code weavers because executing advice goes through at least one layer of indirection. However, they have the advantage of avoiding recompilation or reloading of the application code by providing minimal hooks at all potential points.

The trade-offs between the various types of weavers are presented in Table 31-1. Given the various design alternatives (e.g., full-code weaving vs. stub weaving, load-time weaving vs. JIT-time weaving), we can use this table to choose the most appropriate weaver for a given type of application. Based on this information, we now demonstrate how to build a weaver that can address application awareness.

Table 31-1. Properties of Various Weaver Types

Full-Code Weavers

Stub Weavers

Reduced code size

Large code size

Mix advice and base code

Advice and base code separate

Load-Time Weavers

JIT-Time Weavers

Portable

Less portable

Less efficient

Efficient

May require reload

May require re-compile




Aspect-Oriented Software Development
Aspect-Oriented Software Development with Use Cases
ISBN: 0321268881
EAN: 2147483647
Year: 2003
Pages: 307

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net