Saturday 22 June 2019

AspectJ: Aspect Oriented Programming


In this tutorial series, you are going to learn.
a.   Introduction to Aspect Oriented Programming
b.   Installing AspectJ
c.    Aspectj: Hello World Application
d.   Troubleshooting

Introduction to Aspect Oriented Programming
Aspect oriented programming complements the Object Oriented programming by adding aspects to it. In OOP, class is the key unit, where as in AOP (Aspect Oriented Programming), aspect is the key entity.

AOP mainly addresses the cross cutting problems faced by industries while developing complex applications. By using Aspects, you can separate these cross cutting concerns from the core business logic.

What is cross cutting concern?
While developing any enterprise application, you can see logging, authorization, pooling, caching, monitoring and transaction management is everywhere.  Ideally logging, authorization is nothing to do with core business logic. By using Aspects, we can move these cross cutting concerns out of the core business logic.

Instead of integrating authorization checks in every API code, you can annotate a service method with a marker that tells who can call it, and let some AOP advice decide whether to allow the method call or not.

By implementing logging as AOP advice, you can change what gets logged by changing a join point.

Installing Aspectj
Below step by step procedure explains how to install Aspectj.

Step 1: Go to below location and download latest version of aspectj.

At the time of writing this article, 1.8.13 is the latest stable version of Aspectj.

Step 2: Go the the location of aspectj jar file and run below command.
java -jar <PATH_TO_DOWNLOADED_ASPECTJ_JAR>

When you ran above command, it opens gui window to install AspectJ 8 development kit.


Press Next.



It selects the jre installed in your machine. If you want to choose different jre, use the Browse button.



Press the button ‘Install’.


Once the installation is successful, you can able to see below window.



Once you press Next, it opens below window that shows important steps to perform while executing aspectj programs.


Add aspectjrt.jar to your classpath. And add aspectj bin to your system path.

Aspectj: Hello World Application
I hope you setup the aspecj in your system.


ResourceUtil.java

public class ResourceUtil{

	public void sendResource(String senderName, String receiverName){
		System.out.println("Sending resource from " + senderName + " to " + receiverName);
	}
}


Test.java

public class Test{

	public static void main(String args[]){
		ResourceUtil resourceUtil = new ResourceUtil();
		
		resourceUtil.sendResource("S01", "R01");
	}
}


Compile the classes using the command 'javac -classpath . Test.java'.

Run the classes using the command 'java -classpath . Test'

you can able to see below output.

Sending resource from S01 to R01

Now let’s try to add authorization logic to the ‘sendResource’ method. I created ‘AuthorizationUtil.java’ class, it checks whether the sender and receiver  are authorized to send and receive the information.

My program structure changed like below.

AuthorizationUtil.java    
public class AuthorizationUtil{

	public boolean amIAuthorizedToSend(String senderName){
		if("S01".equals(senderName)){
			System.out.println(senderName + " is authorized to send");
			return true;
		}
		throw new RuntimeException(senderName + " is not authorized to send");
	}
	
	public boolean amIAuthorizedToReceive(String receiverName){
		if("R01".equals(receiverName)){
			System.out.println(receiverName + " is authorized to receive");
			return true;
		}
		
		throw new RuntimeException(receiverName + " is not authorized to receive");
	}

}


ResourceUtil.java
public class ResourceUtil{

	public void sendResource(String senderName, String receiverName){
		/* Checking the authorization of sender and receiver */
		AuthorizationUtil authUtil = new AuthorizationUtil();
		authUtil.amIAuthorizedToSend(senderName);
		authUtil.amIAuthorizedToReceive(receiverName);
		
		System.out.println("Sending resource from " + senderName + " to " + receiverName);
	}
}


Test.java
public class Test{

	public static void main(String args[]){
		ResourceUtil resourceUtil = new ResourceUtil();
		
		resourceUtil.sendResource("S01", "R01");
	}
}


Compile the classes using the command 'javac -classpath . Test.java'.

Run the classes using the command 'java -classpath . Test'

you can able to see below output.

S01 is authorized to send
R01 is authorized to receive
Sending resource from S01 to R01

As you closely observe, ‘sendResource’ method of ResourceUtil class, it is tightly coupled with authorization checks inaddition to core business logic.

         public void sendResource(String senderName, String receiverName){
                  /* Checking the authorization of sender and receiver */
                  AuthorizationUtil authUtil = new AuthorizationUtil();
                  authUtil.amIAuthorizedToSend(senderName);
                  authUtil.amIAuthorizedToReceive(receiverName);
                 
                  System.out.println("Sending resource from " + senderName + " to " + receiverName);
         }

What if there are 100 methods that require authorization checks, before executing actual business logic. You will end up in keeping the same authorization checks everywhere.

By using aspects, you can move these cross cutting tasks outside of core business logic.

Find the below working application.

Step 1: Define AuthorizationUtil class.

AuthorizationUtil.java
public class AuthorizationUtil{

	public boolean amIAuthorizedToSend(String senderName){
		if("S01".equals(senderName)){
			System.out.println(senderName + " is authorized to send");
			return true;
		}
		throw new RuntimeException(senderName + " is not authorized to send");
	}
	
	public boolean amIAuthorizedToReceive(String receiverName){
		if("R01".equals(receiverName)){
			System.out.println(receiverName + " is authorized to receive");
			return true;
		}
		
		throw new RuntimeException(receiverName + " is not authorized to receive");
	}

}


Step 2: Define ResourceUtil class.

ResourceUtil.java
public class ResourceUtil{

	public void sendResource(String senderName, String receiverName){		
		System.out.println("Sending resource from " + senderName + " to " + receiverName);
	}
}


Step 3: Define the security aspect like below.

SecurityAspect.aj
public aspect SecurityAspect{

	private AuthorizationUtil authorizationUtil = new AuthorizationUtil();
	
	pointcut secureAceess()  : call(* ResourceUtil.sendResource(..));

	before() : secureAceess(){
		System.out.println("Checking the authorizations of sender and receiver");
		
		String senderName = (String)thisJoinPoint.getArgs()[0];
		String receiverName = (String)thisJoinPoint.getArgs()[1];
		
		authorizationUtil.amIAuthorizedToSend(senderName);
		authorizationUtil.amIAuthorizedToReceive(receiverName);
	}

}


Step 4: Define Test class like below.



Test.java
public class Test{

	public static void main(String args[]){
		ResourceUtil resourceUtil = new ResourceUtil();
		
		resourceUtil.sendResource("S01", "R01");
	}
}


Compile the java class using below command
ajc -source 5 SecurityAspect.aj *.java

Run the java classes using below command
java -classpath . Test

C:\Users\krishna\Documents\Study\aspectj\examples>ajc -source 5 SecurityAspect.aj *.java

C:\Users\krishna\Documents\Study\aspectj\examples>java -classpath . Test
Checking the authorizations of sender and receiver
S01 is authorized to send
R01 is authorized to receive
Sending resource from S01 to R01

Explanation
How to declare aspect?
It is just like class in java. Aspect is defined using the keyword ‘aspect’. You can define an aspect in either .aj file (or) in .java file.

What is pointcut?
By using pointcuts, we can specify the points that we want to add extra checks like authorization.

Trouble Shooting
java.lang.NoClassDefFoundError: org/aspectj/lang/NoAspectBoundException
While running the aspectj applications, I got the error ‘java.lang.NoClassDefFoundError: org/aspectj/lang/NoAspectBoundException’.

I resolved the above error by placing ‘aspectjrt.jar’ in the classpath.

I placed the jar file in ‘<JAVA_HOME>\jre\lib\ext’.

classpath error: unable to find org.aspectj.lang.JoinPoint
When I am trying to run an aspect application, I an ending up with the error ‘classpath error: unable to find org.aspectj.lang.JoinPoint’.

I get rid of the error by adding ‘aspectjrt.jar’ file to my project classpath.



You may like


No comments:

Post a Comment