Port of schuchert.wikispaces.com


AspectJ_Example_1_PrintLayout

AspectJ_Example_1_PrintLayout


title: AspectJ_Example_1 —

Source files are here: AspectJEx1src.zip. If you need instructions on what do with these files, try here.

Predict the Output

This is the first of several exercise. If you’d like to get a feel for the general outline for each exercise, take a look here.

Code to Review

Examine the following 2 Java files. Your assignment is to predict the output based on these two files. —-

Main.java

package ex1;

public class Main {
	public static void main(String[] args) {
		MethodExecutionExample me = new MethodExecutionExample();

		me.noArgMethod();
		System.out.println("-------------");

		me.methodWithStringParam("Brett");
		System.out.println("-------------");

		me.methodCallingOtherMethod();
		System.out.println("-------------");

		MethodExecutionExample.staticMethod();
	}
}

MethodExecutionExample.java

package ex1;


public class MethodExecutionExample {
	public void noArgMethod() {
		System.out.printf("\tnoArgMethod\n");
	}

	public void methodWithStringParam(String param) {
		System.out.printf("\tmethodWithStringParam: %s\n", param);
	}

	public static void staticMethod() {
		System.out.printf("\tstaticMethod\n");
	}

	public void methodCallingOtherMethod() {
		System.out.printf("\tmethodCallingOtherMethod\n");
		noArgMethod();
	}
}

Predict the output

Before continuing on, please predict the output from these two files.


title: AspectJEX1ExpectedVersusActualOutput —

Expected Output

Did you guess the output would look something like this?

   noArgMethod
-------------
   methodWithStringParam: Brett
-------------
   methodCallingOtherMethod
   noArgMethod
-------------
   staticMethod

Actual Output

What if I told you the output was actually this (ignoring line wrapping)?

Entering: void ex1.MethodExecutionExample.noArgMethod()
	noArgMethod
Leaving void ex1.MethodExecutionExample.noArgMethod()
-------------
Entering: void ex1.MethodExecutionExample.methodWithStringParam(String)
	methodWithStringParam: Brett
Leaving void ex1.MethodExecutionExample.methodWithStringParam(String)
-------------
Entering: void ex1.MethodExecutionExample.methodCallingOtherMethod()
	methodCallingOtherMethod
Entering: void ex1.MethodExecutionExample.noArgMethod()
	noArgMethod
Leaving void ex1.MethodExecutionExample.noArgMethod()
Leaving void ex1.MethodExecutionExample.methodCallingOtherMethod()
-------------
Entering: void ex1.MethodExecutionExample.staticMethod()
	staticMethod
Leaving void ex1.MethodExecutionExample.staticMethod()


title: AspectJEX1FormTheory —

Assignment: Form a Theory

So here is your next assignment. Spend a few moments and try to figure out how to make that happen. Write down those ideas. Please do so before continuing.


title: AspectJEX1Possibilities —

Possibilities

Did you have any ideas? Here are some ideas I’ve heard some people mention:

  • Some kind of dynamic proxy
  • Some kind of inheritance thing
  • Something to do with reflection


title: AspectJEX1WhatIsHappening —

What Is Happening

Let’s take a step back. We just thought of ways this might have happened. When we did that, we were thinking in terms of “how” or implementation. Before we continue, let’s think of “what” is happening. You might think of this as “requirements” or “a use case”.

Assignment: Describe What

So your next assignment is to write down a description of what is happening. As you write your description, consider writing it without resorting to too much technological terminology. Please do so before continuing on to the next section.


title: AspectJEX1SoWhatIsHappening —

So What Is Happening?

Here are some descriptions I’ve heard some people mention:

  • Every time we call a method, we print something before the method runs, the method runs, then we print something after the method runs.
  • We intercept each method call and do something before and after it.
  • As we execute a method, we use reflection to get the name of the method; we print “Entering” followed by the method name. We then execute the method, which always prints something. Finally, we print “Leaving” and the method name.
  • We modify every method execution. Before and after the method execution we display the name of the method.


title: AspectJEX1Explained —

Example 1 Explained

Capturing method execution is often what people first think of when considering AOP.

In this example, we intercept each method called on a class called MethodExecutionExample. Before each method call we print a message, we call the method and then print another message after returning from the method.

Aspect oriented Programming is about two things: Where, What.

What: What is it you want to do that is different from the normal program flow? Initially this is the easier part of the equation. It can get quite difficult but for this example it is trivial; print a message before and after a method execution.

Where: Where to you want to change the normal program flow. This is often the most difficult part of the equation. This is the skill to hone first. In this first example we simply pick out all public methods on a class. However, in my experience, the “where” is almost always as hard as or harder than the “what.”

Main.java is simply a driver and MethodExecutionExample.java is a simple class with some methods on it. In both cases, they are just Plain Old Java Objects (POJOs).

I did not show you three things:

  • MethodExecutionAspect.java
  • aop.xml
  • The Java Virtual Machine is configured to give AspectJ a chance to modify classes as the VM loads them

MethodExecutionAspect.java

01: package ex1;
02: 
03: import org.aspectj.lang.ProceedingJoinPoint;
04: import org.aspectj.lang.annotation.Around;
05: import org.aspectj.lang.annotation.Aspect;
06: import org.aspectj.lang.annotation.Pointcut;
07: 
08: @Aspect
09: public class MethodExecutionAspect {
10:     @Pointcut("execution(* ex1.MethodExecutionExample.*(..))")
11:     void allMethods() {
12:     }
13: 
14:     @Around("allMethods()")
15:     public Object reportMethodExecution(ProceedingJoinPoint thisJoinPoint)
16:             throws Throwable {
17:         System.out.printf("Entering: %s\n", thisJoinPoint.getSignature());
18:         try {
19:             return thisJoinPoint.proceed();
20:         } finally {
21:             System.out.printf("Leaving %s\n", thisJoinPoint.getSignature());
22:         }
23:     }
24: }

Interesting Lines

Lines Description
8 This class is an AspectJ aspect class. It will need to be registered in the aop.xml file to take effect.
10 Define a pointcut. This is where the aspect applies. In this case it applies to execution of methods of any access level (the first *), in the class ex1.MethodExecutionExample, with any name (the second *) taking any parameters (..).
11 Give the pointcut a name, any name. The empty method has code placed into it that represents the pointcut. It is used later on line 14.
14 Around the exeuction of a pointcut do something. Around logic replaces the method. The around takes care of everything, including calling the original code. This around logic applies to all joinpoints captured by the pointcut called allMethods().
15 This is the method that replaces the underlying method execution (all methods in the class ex1.MethodExecutionExample). It takes one parameter, a ProceedingJoinPoint, which is automatically provided by AspectJ. (More on what parameters can go here later.)
19 Call proceed() on “thisJoinPoint” to actually perform the original method execution.

aop.xml

01: <aspectj>
02: 	<aspects>
03: 		<aspect name="ex1.MethodExecutionAspect"/>
04: 	</aspects>
05: 	<weaver>
06: 		<include within="ex1.*"/>
07: 	</weaver>
08: </aspectj>

Interesting Lines

Lines Description
3 Register ex1.MethodExecutionAspect as an apsect to apply to this VM
6 Only apply the registered aspects with classes whose package starts with ex1.

Note, this file needs to be in a directory called META-INF in the classpath. Here’s an easy way to make this happen in eclipse:

  • Create a folder called META-INF under a source directory
  • Create a file called aop.xml in that folder
  • Cut and paste the contents


title: AspectJVMConfigurationBlackMagic —

VM Configuration: Black Magic

This section describes the black magic that actually binds the MethodExecutionAspect class to the MethodExecutionAspect class. You can safely skip it but it is here just in case you are interested in what’s happening.

These examples work on a Java 5 VM. The Java 5 VM has a new command line option, javaagent. You can provide a so-called Java Agent Jar on the command line. When the VM starts up, it will look at the provided Jar file’s manifest. The manifest describes a class to hook into the Java Classloader. When there is a registered Java Agent, the following happens during class loading:

  • The class loader finds a class
  • The class loader retrieves the class’ byte codes into memory
  • The class loader passes the byte codes to the Java Agent
  • The Java Agent can make arbitrary changes to the byte codes
  • The Java Agent returns the byte codes to the class loader
  • The class loader then defines and initializes the class.

The Java Agent provided by AspectJ will modify classes based on the aop.xml file. Our aop.xml file mentions MethodExecutionExample. When the Classloader finds that class on disk, it retrieves it, passes it to the AspectJ Java Agent, which changes all of the methods to have calls into MethodExecutionAspect and then returns the modified class back to the class loader.

More Details

We’ve used several terms: joinpoint, pointcut, aspect.

Joinpoint
What is a joinpoint? It is a place in code that can be uniquely identified and somehow modified. Java VM’s execute bytecodes. A joinpoint, therefore, is a Java bytecode. Not all bytecodes can be uniquely identified. Not because they are not somehow look-up-able, but because the designers of AspectJ made a decision about where they will allow aspects to apply. This decision is the joinpoint model.
Pointcut
A pointcut is simply a collection of joinpoints. In our first example, the execution of all methods in a class called ex1.MethodExecutionExample. We’ll see more of these later. A pointcut is how you define what.
Aspect
An aspect is something that describes where to do what. In our first example, we used a joinpoint for where and what AspectJ refers to as advice for the what.
Advice: Bad Name?
Advice is the metaphor that AspectJ uses to describe what should happen when a pointcut is encountered. Ask your self this question, when given advice (or giving), it is always followed? Because it IS in AspectJ.


title: AspectJEX1ApplyYourself —

Apply Yourself

Here is a series of exercises you can try yourself to confirm what you’ve learned so far. Doing these assignments should really solidify your understanding of this first example.


Stateful Aspect

Track the number of times MethodExecutionAspect.reportMethodExecution() is called. Display this information as well as what it currently displays.

Challenge:

How many instances of MethodExecutionAspect are there? How can you tell? Make a theory. Test your theory by extending this assignment somehow.


Pointcut Changes

Change the pointcut to select only one particular method. Verify that your change worked.

Challenge: Use JUnit plus your knowledge from section 7.5.1 to programmatically test your pointcut.


Whole New Class

Create a simple Java Bean style class. Call it Address. Add the following attributes:

  • addressLine1
  • addressLine2
  • city
  • state
  • zip

Add setters and getters for each of these attributes. Write a pointcut to select all of the methods starting with “set” and bind that pointcut to a SetMethodAspect class you create. Your SetMethodAspect. method() should simply display a message: “Calling setter: ” where is the name of the setMethod.

Challenge:

Use string manipulation/regular expressions to convert the name of the method into the name of the attribute and print that instead.


Challenge:

Monopoly® Output Currently, the provided Monopoly® source code produces game output in the Game.play() method. Remove that output and instead write a method interceptor to display the same output. You’ll have to figure out which method to write and how to get access to the information you need.

Assessment:

Does doing this make sense? Is this a cross-cutting concern? How might you apply this kind of idea in a realistic situation?


title: AspectJEX1AssignmentApplications —

Assignment: Applications

Write down at least three places where you think intercepting method execution might be a useful technique. Please do so before moving on.


title: AspectJEX1ApplicationsOfMethodExecution —

Applications of Method Execution

Here are some things I’ve heard people mention:

  • Automated logging
  • Enforcing security at a method level
  • Copying method execution to a second target automatically


title: AspectJEX1AssignmentIssues —

Assignment: Issues

Write down at least three problems and/or concerns with this technique. Please do so before moving on.


title: AspectJEX1IssuesConcerns —

Issues/Concerns

Here are some issues/concerns I’ve heard people mention:

  • Performance might be slow
  • We’re changing things under people’s eyes
  • This can be done using regular OO techniques


Comments

" Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.