Showing posts with label AOP. Show all posts
Showing posts with label AOP. Show all posts

Wednesday, July 29, 2015

The archive: xxx hibernate3-3.2.3.GA.jar which is referenced by the classpath, does not exist.

This is recent error came with running a maven project in the eclipse.
I just copied one of the mkyoung test projects on AOP declarative transaction and it gave me the error when trying to run the main method.

error
=================================================

The archive: C:/Users/xxxFolder/.m2/repository/hibernate/hibernate3/3.2.3.GA/hibernate3-3.2.3.GA.jar which is referenced by the classpath, does not exist.

=================================================

Initially pom.xml was refeerenced with

<dependency>
<groupId>hibernate</groupId>
<artifactId>hibernate3</artifactId>
<version>3.2.3.GA</version>
</dependency>


where as this could not found i changed to

                <dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate</artifactId>
<version>3.2.3.ga</version>
</dependency>

And the above issue comes as i did not create dependency file and when i import the project to the eclipse , it still use old dependency file.

So it better to build the dependency file again.

Solution
----------

Just delete ".classpath"  file and ".project" file from the folder and create again by running commad

mvn clean eclipse:eclispe

This will create brand new  ".classpath"  file and ".project" file and issue will be sorted.

Reference project :
http://www.mkyong.com/spring/spring-aop-transaction-management-in-hibernate/


Tuesday, March 24, 2015

Spring AOP - Understanding Proxy

AOP proxy is one of few Terminolgies comes with AOP. I have used basic code structure to explain and test the concepts. It's given with

http://cgenit.blogspot.com/2015/03/aop-basic-application-code-and.html

Here we have basically given spring.xml - configuration and dependency modules with pom.xml.
Business logic explanation code contains Aspect , Advice , Pointcut

with this we are going to introduce you the new concept of  "Proxy".

In simple Proxy is defined as an "Object created by the AOP framework in order to implement the Aspect contract.( Aspect contract include advice method execution  and related details pointcut etc..)"

So Proxy can be viewed in the OOP encapsulation point of view as well.

So basic coding structure , we have two object Triangle, Circle and ShapeService to get the instance of Circle and Triangle.
To test we have "AppMain.java" where it get the bean of  "shapeService " from ApplicationContext and get the circle or Triangle instance from  "shapeService " bean.

For implementation of proxy, we change the flow and we introduce a new class "FactoryService" class and we use that to get the beans.
We implement getBean method accepting beantype as parameter in the "FactoryService.java" .
You can give the name of the bean and get the bean as you need. If no matching bean found for the requested type "NULL" oblect will be return from the FactoryService.
This is a implementation of Factory design pattern.
Below is the code.

FactoryService.java
-------------------------------------------------------------------------------------------------

package org.aop.service;

import org.aop.model.Circle;
import org.aop.model.Triangle;

public class FactoryService {

public Object getBean(String beanType) {
if ("shapeService".equalsIgnoreCase(beanType)) {
return new ShapeService();
}
if ("circle".equalsIgnoreCase(beanType)) {
return new Circle();
}
if ("triangle".equalsIgnoreCase(beanType)) {
return new Triangle();
}

return null;
}

}

-------------------------------------------------------------------------------------------------


Now we have to change our main method.
We are not going to define a bean in the Context and this straight away access the Factory and get the whatever the instance/object we need.
First we create instance on factory and from factory we get the shapeService bean.

So we comment the lines where we used context as we are not going to use in AppMain.java.

--------------------------------------------------------------------------------------------------
// ApplicationContext ctx = new ClassPathXmlApplicationContext(
// "spring.xml");

// you need to cast if not use second parameter ShapeService.class
// ShapeService shapeService = ctx.getBean("shapeService",
// ShapeService.class);
-----------------------------------------------------------------------------------------------

and write new line

-----------------------------------------------------------------------------------------------
FactoryService factoryService = new FactoryService();
ShapeService shapeService = (ShapeService) factoryService
.getBean("shapeSerivce");

-----------------------------------------------------------------------------------------------

This is the same thing as previously accessing with context.

So new Test class will look like below.

AppMain .java
-----------------------------------------------------------------------------------------------
package org.aop.main;

import org.aop.service.FactoryService;
import org.aop.service.ShapeService;

public class AppMain {
public static void main(String[] args) {
// ApplicationContext ctx = new ClassPathXmlApplicationContext(
// "spring.xml");

// you need to cast if not use second parameter ShapeService.class
// ShapeService shapeService = ctx.getBean("shapeService",
// ShapeService.class);

FactoryService factoryService = new FactoryService();
ShapeService shapeService = (ShapeService) factoryService
.getBean("shapeService");
shapeService.getCircle();
}

}

-----------------------------------------------------------------------------------------------


Now to get verified whether the getter is called we just add sysout inside the getter on ShapeService.
System.out.println("ShapeService::getCircle called.");

new circle class will be

ShapeService.java   sysout is highlighted.
-----------------------------------------------------------------------------------------------
package org.aop.service;

import org.aop.aspect.Loggable;
import org.aop.model.Circle;
import org.aop.model.Triangle;

public class ShapeService {

private Circle circle;
private Triangle triangle;

@Loggable
public Circle getCircle() {
System.out.println("ShapeService::getCircle called.");
return circle;
}

public void setCircle(Circle circle) {
this.circle = circle;
}

public Triangle getTriangle() {
return triangle;
}

public void setTriangle(Triangle triangle) {
this.triangle = triangle;
}

}


-----------------------------------------------------------------------------------------------


IF you run the main method the output will be as follows.

Output
=========================================================
ShapeService::getCircle called.
=========================================================


Now let's write new plain method "loggingAdvice" inside Aspect "LoginAspect"

-------------------------------------------------------------------------------------------------

public void loginAdvice() {
System.out.println("Logging from the advice.");
}
-------------------------------------------------------------------------------------------------

Now we need to execute this method whenever the shapeService "getCircle" is called.

How to do that.
We need to create a proxy object. Proxy must be type of ShapeService object.
So we create a new class extends ShapeService class.

Let's create a new class "ShapeServiceProxy.java" and extends it from ShapeService.java

ShapeServiceProxy .java
-------------------------------------------------------------------------------------------------
package org.aop.service;

public class ShapeServiceProxy extends ShapeService {

}

-------------------------------------------------------------------------------------------------

So Proxy is almost same object as ShapeService, as i have not included any method or override any method.
Now you can use Proxy Object instead of "shapeService" inside the factory.

FactoryService .java
-------------------------------------------------------------------------------------------------

package org.aop.service;

import org.aop.model.Circle;
import org.aop.model.Triangle;

public class FactoryService {

public Object getBean(String beanType) {
if ("shapeService".equalsIgnoreCase(beanType)) {
return new ShapeServiceProxy();
}
if ("circle".equalsIgnoreCase(beanType)) {
return new Circle();
}
if ("triangle".equalsIgnoreCase(beanType)) {
return new Triangle();
}

return null;
}

}

-------------------------------------------------------------------------------------------------

So let's add a method to Proxy , override getter.
Here inside the Override method , you call super method. So nothing is changed.

So why we do that.

If you can remember the Around advice , this is like that.
This proxy object method is called before the Target "shapeService" getCircle method and you can do whatever you need.

I think now you can understand AOP with respect to OOP very well.

ShapeServiceProxy .java  new proxy with override getter.
-------------------------------------------------------------------------------------------------
package org.aop.service;

import org.aop.model.Circle;

public class ShapeServiceProxy extends ShapeService {

@Override
public Circle getCircle() {
return super.getCircle();
}
}
-------------------------------------------------------------------------------------------------


Now let's add loginAdvice method before the "getCircle" method called.
So the new method , override method inside proxy will looks like below.


ShapeServiceProxy .java  new proxy with override getter and with adding advice method.
-------------------------------------------------------------------------------------------------
package org.aop.service;

import org.aop.aspect.LoginAspect;
import org.aop.model.Circle;

public class ShapeServiceProxy extends ShapeService {

@Override
public Circle getCircle() {
new LoginAspect().loginAdvice();
return super.getCircle();
}
}

-------------------------------------------------------------------------------------------------

So every time , getCircle method called, loginAdvice method will be called Before the getCircle method.
Note : Before
If you can understand , now you can decide when to add the loginAdvice, 
eg : Bfore , After, Around, After Returning or After Throwing 

Now let;'s run the main method.

Output
=========================================================
Logging from the advice.
ShapeService::getCircle called.
=========================================================

So now you will understand how simple is that and definitely give you a idea about how AOP works inside spring background and how proxy encapsulates AOP work.

Monday, March 23, 2015

Spring Aspect Oriented Programming , AOP - writting custom Annotation

Basic Scenario
This is to describe on How to write a simple annotation.
I am writing custom annotation with name "Loggable" and I will use it with the "myArroundAdvice" which is Advice with type "Around" written in the LoginAspect.java

basic code for project is described in
http://cgenit.blogspot.com/2015/03/aop-basic-application-code-and.html

Let's write custom annotation.
If you using eclipse , you can select annotation and give name "Loggable" and it will create Loggable custom annotation.
Else simply you can create a class with name "Loggable" , and put "@interface" before name "Loggable"  as shown in below code

package I have used is same package "org.aop.aspect".  You can have your own package.

So we have defined custom annotation. Then how to use it.
So in the advice , give the path to custom annotation, in the place where you give the poincut.

----------------------------------------------------------------------------------------

@Around("@annotation(org.aop.aspect.Loggable)")
public Object myArroundAdvice(ProceedingJoinPoint proceedingJoinPoint) {
// advice code here
}

----------------------------------------------------------------------------------------

put the annotation in the place you need to do the Logging or execute advice.
Here we are going to add the Logging to "getCircle" method in the ShapeService object
So we add the annotation above the "getCircle" method as shown in below

-----------------------------------------------------------------------------------
@Loggable
public Circle getCircle() {

return circle;
}
-----------------------------------------------------------------------------------

Once you run the project . you will get below output.

Output - custom annotation
=================================================
Circle set name =Circle name
Before advice.
After Returning.
After Finally.
Circle set name =dummy name
====================================================

Final coding as below


Loggable .java
----------------------------------------------------------------------------------------
package org.aop.aspect;

public @interface Loggable {


}

----------------------------------------------------------------------------------------

Below is the new Advice. You may have some unused imports, that's cause i have ommited some codes to ease of explanation. Don't worry about that. Just remove those.

LoginAspect .java
----------------------------------------------------------------------------------------
package org.aop.aspect;

import org.aop.model.Circle;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

import org.aspectj.lang.annotation.Pointcut;

@Aspect

public class LoginAspect {
@Around("@annotation(org.aop.aspect.Loggable)")
public Object myArroundAdvice(ProceedingJoinPoint proceedingJoinPoint) {
Object returnValue = null;
try {
System.out.println("Before advice.");
returnValue = proceedingJoinPoint.proceed();
System.out.println("After Returning.");
} catch (Throwable e) {
System.out.println("After Throwing.");
}

System.out.println("After Finally.");
return returnValue;

}
}
----------------------------------------------------------------------------------------

ShapeService .java
----------------------------------------------------------------------------------------
package org.aop.service;

import org.aop.aspect.Loggable;
import org.aop.model.Circle;
import org.aop.model.Triangle;

public class ShapeService {

private Circle circle;
private Triangle triangle;

@Loggable
public Circle getCircle() {
// circle = null;
// circle.getName();
return circle;
}

public void setCircle(Circle circle) {
this.circle = circle;
}

public Triangle getTriangle() {
return triangle;
}

public void setTriangle(Triangle triangle) {
this.triangle = triangle;
}

}
----------------------------------------------------------------------------------------

AppMain .java
----------------------------------------------------------------------------------------

package org.aop.main;

import org.aop.service.ShapeService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AppMain {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"spring.xml");

// you need to cast if not use second parameter ShapeService.class
ShapeService shapeService = ctx.getBean("shapeService",
ShapeService.class);


shapeService.getCircle().setName("dummy name");
}

}


----------------------------------------------------------------------------------------


You can check the exception also.
To get a exception and check what;s happen when an exception , just remove commented two lines in the "getCircle" method in the ShaepService.java
This will make null pointer exception

------------------------------------------------------------------------------------
@Loggable
public Circle getCircle() {
circle = null;
circle.getName();
return circle;
}
------------------------------------------------------------------------------------


Output - custom annotation with Nullpointer exception
=================================================
Circle set name =Circle name
Before advice.
After Throwing.
After Finally.
Exception in thread "main" java.lang.NullPointerException
at org.aop.main.AppMain.main(AppMain.java:18)
====================================================

You can see that in output Line number 3 , it's printing  After Throwing. .

If you need to see the what's happening with the ProceedingJoinPoint , you can print that just using sysout.

so if you add a sysout to advice . It's highlighted in the below code inside advice.

LoginAspect .java
------------------------------------------------------------------------------------

package org.aop.aspect;

import org.aop.model.Circle;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class LoginAspect {


@Around("@annotation(org.aop.aspect.Loggable)")
public Object myArroundAdvice(ProceedingJoinPoint proceedingJoinPoint) {
Object returnValue = null;
try {
System.out.println("Before advice.");
System.out.println(proceedingJoinPoint);
returnValue = proceedingJoinPoint.proceed();
System.out.println("After Returning.");
} catch (Throwable e) {
System.out.println("After Throwing.");
}

System.out.println("After Finally.");
return returnValue;
}


}

------------------------------------------------------------------------------------


So the new output will be

Output - custom annotation with Nullpointer exception and with sysout proceedingJoinPoint
=================================================
Circle set name =Circle name
Before advice.
execution(Circle org.aop.service.ShapeService.getCircle())
After Throwing.
After Finally.
Exception in thread "main" java.lang.NullPointerException
at org.aop.main.AppMain.main(AppMain.java:18)

====================================================

you can see it's printing the joinpoint of the execution, where we have applied our custom annotation.
I have highlighted in  the output.
execution(Circle org.aop.service.ShapeService.getCircle())

Also you can see what happens if you remove the "proceedingJoinPoint.proceed();" from the advice. So let's comment that line and see what will happen.

So new Advice will look like below

LoginAspect .java  Note: proceedingJoinPoint.proceed();  is commented.
-----------------------------------------------------------------------------------------------
package org.aop.aspect;

import org.aop.model.Circle;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class LoginAspect {


@Around("@annotation(org.aop.aspect.Loggable)")
public Object myArroundAdvice(ProceedingJoinPoint proceedingJoinPoint) {
Object returnValue = null;
try {
System.out.println("Before advice.");
// System.out.println(proceedingJoinPoint);
// returnValue = proceedingJoinPoint.proceed();
System.out.println("After Returning.");
} catch (Throwable e) {
System.out.println("After Throwing.");
}

System.out.println("After Finally.");
return returnValue;
}



}


------------------------------------------------------------------------------------------------

Output - commenting "proceedingJoinPoint.proceed();"
=================================================
Circle set name =Circle name
Before advice.
After Returning.
After Finally.
Exception in thread "main" java.lang.NullPointerException
at org.aop.main.AppMain.main(AppMain.java:18)

====================================================

Note : you are getting a NullPointerException.


Friday, March 20, 2015

AOP basic application code and configuration

I have made a simple maven project to test and describe AOP concepts.
POM files and spring.xml configuration files and Two Objects Circle.java and Trinagle.javab with the service class ShapeService.java. Aspect is done inside LoginAspect.java and Application test main method coded with the AppMain.java

Those configuration and base class files are shown below.
Each scenario i will be using thise main basic application and alter the code to test specific Aspect concepts.
In each i will be point out changes i do with respect to the base code.

POM.XML  this include more dependencies , more than needed

----------------------------------------------------------------------------------------

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <groupId>com.test</groupId>
 <artifactId>AOP</artifactId>
 <version>0.0.1-SNAPSHOT</version>
 <name>AOP</name>
 <description>Aspect Oriented Programming</description>

 <properties>
  <jdk.version>1.6</jdk.version>
  <spring.version>3.2.8.RELEASE</spring.version>
  <spring.security.version>3.2.3.RELEASE</spring.security.version>
  <jstl.version>1.2</jstl.version>
  <javax.servlet.version>3.1.0</javax.servlet.version>
  <mysql.connector.version>5.1.30</mysql.connector.version>
 </properties>

 <dependencies>
  <!-- Spring 3 dependencies -->
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-core</artifactId>
   <version>${spring.version}</version>
  </dependency>

  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-web</artifactId>
   <version>${spring.version}</version>
  </dependency>

  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-webmvc</artifactId>
   <version>${spring.version}</version>
  </dependency>

  <!-- spring jdbc -->
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-jdbc</artifactId>
   <version>${spring.version}</version>
  </dependency>

  <!-- Spring Security -->
  <dependency>
   <groupId>org.springframework.security</groupId>
   <artifactId>spring-security-web</artifactId>
   <version>${spring.security.version}</version>
  </dependency>

  <dependency>
   <groupId>org.springframework.security</groupId>
   <artifactId>spring-security-config</artifactId>
   <version>${spring.security.version}</version>
  </dependency>

  <!-- AOP -->
  <dependency>
   <groupId>org.aspectj</groupId>
   <artifactId>aspectjrt</artifactId>
   <version>1.7.3</version>
  </dependency>
 
  <dependency>
   <groupId>org.aspectj</groupId>
   <artifactId>aspectjweaver</artifactId>
   <version>1.6.11</version>
  </dependency>

  <!-- connect to mysql -->
  <dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
   <version>${mysql.connector.version}</version>
  </dependency>


 </dependencies>
</project>
----------------------------------------------------------------------------------------

spring.xml  - bean definition
----------------------------------------------------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
 xsi:schemaLocation="http://www.springframework.org/schema/beans
 http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
 http://www.springframework.org/schema/aop
 http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">

 <aop:aspectj-autoproxy />

 <bean name="triangle" class="org.aop.model.Triangle">
  <property name="name" value="Traingle name"></property>
 </bean>

 <bean name="circle" class="org.aop.model.Circle">
  <property name="name" value="Circle name"></property>
 </bean>

 <bean name="shapeService" class="org.aop.service.ShapeService"
  autowire="byName"></bean>

 <bean name="loginAspect" class="org.aop.aspect.LoginAspect"></bean>

</beans>
----------------------------------------------------------------------------------------

Circle.java
----------------------------------------------------------------------------------------
package org.aop.model;

public class Circle {

 private String name;

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

}

----------------------------------------------------------------------------------------
Triangle.java
----------------------------------------------------------------------------------------
package org.aop.model;

public class Triangle {
 private String name;

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }
}

----------------------------------------------------------------------------------------
ShapeService .java
----------------------------------------------------------------------------------------
package org.aop.service;

import org.aop.model.Circle;
import org.aop.model.Triangle;

public class ShapeService {

 private Circle circle;
 private Triangle triangle;

 public Circle getCircle() {
  return circle;
 }

 public void setCircle(Circle circle) {
  this.circle = circle;
 }

 public Triangle getTriangle() {
  return triangle;
 }

 public void setTriangle(Triangle triangle) {
  this.triangle = triangle;
 }

}

----------------------------------------------------------------------------------------
LoginAspect .java
----------------------------------------------------------------------------------------
package org.aop.aspect;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class LoginAspect {

 @Before("execution(public String getName())")
 public void loginAdvice() {
  System.out.println("Login advice run::get method called");
 }

}

--------------------------------------------------------------------------------------------------------------------------
AppMain .java
--------------------------------------------------------------------------------------------------------------------------
package org.aop.main;

import org.aop.service.ShapeService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AppMain {
 public static void main(String[] args) {
  ApplicationContext ctx = new ClassPathXmlApplicationContext(
    "spring.xml");

  // you need to cast if not use second parameter ShapeService.class
  ShapeService shapeService = ctx.getBean("shapeService",
    ShapeService.class);

  System.out.println(shapeService.getTriangle().getName());
 }

}

------------------------------------------------------------------------------------------------------------

Pointcut with args()

There can be errors difficult to catch if you do not define the pointcut precisely specially with the args(name)

we are using args() to catch the JoinPoint with argumets.

Eg: we write a Pontcut to catch setter for Circle.java

----------------------------------------------------------------------------------------
package org.aop.service;

import org.aop.model.Circle;
import org.aop.model.Triangle;

public class ShapeService {

 private Circle circle;
 private Triangle triangle;

 public Circle getCircle() {
  return circle;
 }

 public void setCircle(Circle circle) {
  this.circle = circle;
 }

 public Triangle getTriangle() {
  return triangle;
 }

 public void setTriangle(Triangle triangle) {
  this.triangle = triangle;
 }

}

----------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------
package org.aop.model;

public class Circle {

 private String name;

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

}

----------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------
public class AppMain {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"spring.xml");

// you need to cast if not use second parameter ShapeService.class
ShapeService shapeService = ctx.getBean("shapeService",
ShapeService.class);


shapeService.getCircle().setName("dummy name");
}

}

----------------------------------------------------------------------------------------

----------------------------------------------------------------------------------------
package org.aop.aspect;

import org.aop.model.Circle;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class LoginAspect {



@Before("argumentMethods(name)")
public void secondAdvice(String name) {
System.out.println("Second advice executed."+ name);
}



@Pointcut("args(name)")
public void argumentMethods(String name) {
}

}


----------------------------------------------------------------------------------------

As shown above we have pointcut argumentMethods

----------------------------------------------------------------------------------------
@Pointcut("args(name)")
public void argumentMethods(String name) {
}
----------------------------------------------------------------------------------------

it is used in the advice = secondAdvice

----------------------------------------------------------------------------------------
 @Before("argumentMethods(name)")
 public void secondAdvice(String name) {
 System.out.println("Second advice executed."+ name);
 }
----------------------------------------------------------------------------------------

If any case we forget include parameter "name", there will be exception.It's exception in initializing the beans. Because of this simple thing, all initialization fails.

eg: we remove the name parameter from advice method
Note : parameter  missing name in the secondAdvice
----------------------------------------------------------------------------------------
 @Before("argumentMethods(name)")
public void secondAdvice() {
System.out.println("Second advice executed.");
}
----------------------------------------------------------------------------------------

exception will be
----------------------------------------------------------------------------------------
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'triangle' defined in class path resource [spring.xml]: Initialization of bean failed; nested exception is java.lang.IllegalArgumentException: warning no match for this type name: name [Xlint:invalidAbsoluteTypeName]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:529)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:296)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:293)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:628)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
at org.springframework.context.support.ClassPathXmlApplicationContext.(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.(ClassPathXmlApplicationContext.java:83)
at org.aop.main.AppMain.main(AppMain.java:9)
Caused by: java.lang.IllegalArgumentException: warning no match for this type name: name [Xlint:invalidAbsoluteTypeName]
at org.aspectj.weaver.tools.PointcutParser.parsePointcutExpression(PointcutParser.java:301)
at org.springframework.aop.aspectj.AspectJExpressionPointcut.buildPointcutExpression(AspectJExpressionPointcut.java:209)
at org.springframework.aop.aspectj.AspectJExpressionPointcut.buildPointcutExpression(AspectJExpressionPointcut.java:196)
at org.springframework.aop.aspectj.AspectJExpressionPointcut.checkReadyToMatch(AspectJExpressionPointcut.java:185)
at org.springframework.aop.aspectj.AspectJExpressionPointcut.getClassFilter(AspectJExpressionPointcut.java:166)
at org.springframework.aop.support.AopUtils.canApply(AopUtils.java:208)
at org.springframework.aop.support.AopUtils.canApply(AopUtils.java:262)
at org.springframework.aop.support.AopUtils.findAdvisorsThatCanApply(AopUtils.java:294)
at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.findAdvisorsThatCanApply(AbstractAdvisorAutoProxyCreator.java:118)
at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.findEligibleAdvisors(AbstractAdvisorAutoProxyCreator.java:88)
at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.getAdvicesAndAdvisorsForBean(AbstractAdvisorAutoProxyCreator.java:69)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:359)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:322)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:409)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1518)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:521)
... 11 more


Join Point and Pointcut

Here we try to understand few keywords used in aspect oriented programming, AOP.
Joinpoint, PointCut and Advice

Aspect
This is a cross cutting concern over the object model in the program which can be used to modularization.
eg :Logging , Transaction Management , Security

JoinPoint
Point where we apply our aspect concept. Or Point during the execution of method.
JoinPoint term used from Object perspective , or in simple term used to show where our aspect concept

PointCut
The predicate which matches the JoinPoint is called Pointcut.

Advice
Action done by Aspect in the Joint is called Advice.

To give you more understanding.
Let's take Java, OOP class Circle.java with one attribute name. It has getter and setter.
We need to apply logging to getName and SetName
Two methods are show below with bold letters.

getName() and setName(String name) are tow JoinPoints.
Note : JoinPoint is in the Java OOP class
--------------------------------------------------------------------------------------

package org.aop.model;

public class Circle {

private String name;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
System.out.println("Circle set name =" + name);
}

}

----------------------------------------------------------------------------------------------


The  to make logging. We are not using OOP.
now we are in AOP. So define Aspect.
Our Aspect name is "LogginAspect"
to make it Aspect, we annotate with @Aspect
So here after, The Aspect is taken care with the Spring FrameWork.
This is form of modularization.

LoginAspect.java
----------------------------------------------------------------------------------------------
package org.aop.aspect;

import org.aspectj.lang.annotation.Aspect;


@Aspect
public class LoginAspect {

}

----------------------------------------------------------------------------------------------


We have defined the Aspect, LoginAspect
Now we need to define the what we need to do(Advice) in the JoinPoint(The method we are going to add logging - logging is the action we are doing)

We define Advice inside the Aspect.
Aspect can have more than one advice.
Let's define our Advice in the Aspect - LoginAspect
To define Advice, we define a method.
As we need to add a log statement let's name it as loginAdvice
so the Advice method would like

----------------------------------------------------------------------------------------------
public void loginAdvice() {
System.out.println("Login advice run::get method called");
}

----------------------------------------------------------------------------------------------

Above shows the whole body of the advice.
To go through from the beginning, once again

public  - access modifier - access for whole world
void - return type - no return
loginAdvice() -  name of the advice "loginAdvice" with no parameters. we can have parameters if needed
Inside the method , you have sysout , the logging part

System.out.println("Login advice run::get method called");


But we have a problem

Now we have the JoinPoint - The Circle.java  - two methods
Aspect - LoginAspect.java
inside LoginAspect.java we have defined the method loginAdvice 
But with this Advice does not become complete. Still incomplete

How the Advice know the methods it should apply the advice.
In simple, how the advice bind to the JoinPoint.

We need to give the Joinpoint to advice, or we need to tell the advice
hey.. this is where you need to do your work.

We have to give it as pattern, as are going to apply the advice to all methods

Note: We are using aspectj dependency, not spring aspect. aspectj has more options, where we can add aspects/advice not only to methods , but also to fields
eg: Circle has attribute "name" and a getter and a setter
with aspectj ,  you can trace all three, including the attribute/filed "name".
If you use spring aspect, then you can't take attribute/filed "name"


So let's back in to our scenario.
We need to tell the advice, this is your method-JoinPoint you need to look at and do the work

The predicate , or the pattern is called the ''Pointcut"

There are various ways to write the Pointcut using pattern.

To match all the methods, our predicate will be

"within(org.aop.model.Circle"

This tell the Advice, to match all the methods within the Circle object.

But when we need to program the advice, we have to tell the type of the advice
That is Before, After  etc.
Before  - Advice runs before at JoinPoint
After - Advice runs after exit anyway at JoinPoint
After Returning - Advice runs after JoinPoint normal completion
After Throwing - Advice runs when method exit throwing an exception
Around - Advice runs surrounding the JoinPoint

In our case, we decide to run the Advice Before at the JoinPoint

So our Advice will look like below

----------------------------------------------------------------------------------------------
@Before("within(org.aop.model.Circle)")
public void loginAdvice() {
System.out.println("Login advice run::get method called");
}

----------------------------------------------------------------------------------------------

Note:

@Before  - type of the advice - tell run before at the JoinPoint , this is part of Advice

"within(org.aop.model.Circle)"  - this is the PointCut , it is given withing quotes.

So after all your Aspect will look like below


----------------------------------------------------------------------------------------------
package org.aop.aspect;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;


@Aspect
public class LoginAspect {

@Before("within(org.aop.model.Circle)")
public void loginAdvice() {
System.out.println("Login advice run::get method called");
}

}

----------------------------------------------------------------------------------------------

So if you run the program, output will be as below

========================================================
Circle set name =Circle name
Login advice run::get method called
Circle name
========================================================


Output has three lines

Line 1 : Circle set name =Circle name
    This comes as a result of the bean definition. We are setting value for name in the circle object


 <bean name="circle" class="org.aop.model.Circle">
  <property name="name" value="Circle name"></property>
 </bean>

and we have a sysout defined inside the setter method in Circle.java

public void setName(String name) {
this.name = name;
System.out.println("Circle set name =" + name);
}

Line 2 : Login advice run::get method called

This line come from the Aspect. This is what we have applied
our loginAdvice method or as a result of the action from the loginAdvice
above code line/ log statement (here we have used sysout) added

@Before("within(org.aop.model.Circle)")
public void loginAdvice() {
System.out.println("Login advice run::get method called");
}


As we have defined Advice as Before , it executes before at the JoinPoint "public String getName() "
To make sure we have called the getName , we are printing the output if it-this print after the advice action in line 3

Line 3: Circle name

This is coming from our main method. we execute getName and print the output.


Out Main method / test code

AppMain .java
----------------------------------------------------------------------------------------------
package org.aop.main;

import org.aop.service.ShapeService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AppMain {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"spring.xml");

// you need to cast if not use second parameter ShapeService.class
ShapeService shapeService = ctx.getBean("shapeService",
ShapeService.class);


System.out.println(shapeService.getCircle().getName());

}

}

----------------------------------------------------------------------------------------------
POM.XML  this include more dependencies , more than needed

----------------------------------------------------------------------------------------

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <groupId>com.test</groupId>
 <artifactId>AOP</artifactId>
 <version>0.0.1-SNAPSHOT</version>
 <name>AOP</name>
 <description>Aspect Oriented Programming</description>

 <properties>
  <jdk.version>1.6</jdk.version>
  <spring.version>3.2.8.RELEASE</spring.version>
  <spring.security.version>3.2.3.RELEASE</spring.security.version>
  <jstl.version>1.2</jstl.version>
  <javax.servlet.version>3.1.0</javax.servlet.version>
  <mysql.connector.version>5.1.30</mysql.connector.version>
 </properties>

 <dependencies>
  <!-- Spring 3 dependencies -->
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-core</artifactId>
   <version>${spring.version}</version>
  </dependency>

  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-web</artifactId>
   <version>${spring.version}</version>
  </dependency>

  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-webmvc</artifactId>
   <version>${spring.version}</version>
  </dependency>

  <!-- spring jdbc -->
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-jdbc</artifactId>
   <version>${spring.version}</version>
  </dependency>

  <!-- Spring Security -->
  <dependency>
   <groupId>org.springframework.security</groupId>
   <artifactId>spring-security-web</artifactId>
   <version>${spring.security.version}</version>
  </dependency>

  <dependency>
   <groupId>org.springframework.security</groupId>
   <artifactId>spring-security-config</artifactId>
   <version>${spring.security.version}</version>
  </dependency>

  <!-- AOP -->
  <dependency>
   <groupId>org.aspectj</groupId>
   <artifactId>aspectjrt</artifactId>
   <version>1.7.3</version>
  </dependency>

  <dependency>
   <groupId>org.aspectj</groupId>
   <artifactId>aspectjweaver</artifactId>
   <version>1.6.11</version>
  </dependency>

  <!-- connect to mysql -->
  <dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
   <version>${mysql.connector.version}</version>
  </dependency>


 </dependencies>
</project>
----------------------------------------------------------------------------------------

spring.xml  - bean definition , this include Triangle and ShapeService
----------------------------------------------------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
 xsi:schemaLocation="http://www.springframework.org/schema/beans
 http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
 http://www.springframework.org/schema/aop
 http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">

 <aop:aspectj-autoproxy />

 <bean name="triangle" class="org.aop.model.Triangle">
  <property name="name" value="Traingle name"></property>
 </bean>

 <bean name="circle" class="org.aop.model.Circle">
  <property name="name" value="Circle name"></property>
 </bean>

 <bean name="shapeService" class="org.aop.service.ShapeService"
  autowire="byName"></bean>

 <bean name="loginAspect" class="org.aop.aspect.LoginAspect"></bean>

</beans>
----------------------------------------------------------------------------------------
Triangle.java
----------------------------------------------------------------------------------------
package org.aop.model;

public class Triangle {
 private String name;

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }
}

----------------------------------------------------------------------------------------
ShapeService .java
----------------------------------------------------------------------------------------
package org.aop.service;

import org.aop.model.Circle;
import org.aop.model.Triangle;

public class ShapeService {

 private Circle circle;
 private Triangle triangle;

 public Circle getCircle() {
  return circle;
 }

 public void setCircle(Circle circle) {
  this.circle = circle;
 }

 public Triangle getTriangle() {
  return triangle;
 }

 public void setTriangle(Triangle triangle) {
  this.triangle = triangle;
 }

}

----------------------------------------------------------------------------------------

Continue Story..............

We have not defined the pointcut seperately.
we can define sperate Pointcut  with annotation @Pointcut

so our Pointcut will look like below

----------------------------------------------------------------------------------------
@Pointcut("within(org.aop.model.Circle)")
public void allCircleMethods() {
}

----------------------------------------------------------------------------------------

Note : we had to make dummy method. we need dummy method to hold the PointCut. we will be using the name of the dummy method name in the Pointcut to reference the Pointcut.
So new advice will look like

----------------------------------------------------------------------------------------
@Before("allCircleMethods()")
public void loginAdvice() {
System.out.println("Login advice run::get method called");
}

----------------------------------------------------------------------------------------

So after change Our Aspect will look as

----------------------------------------------------------------------------------------
package org.aop.aspect;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class LoginAspect {

@Before("allCircleMethods()")
public void loginAdvice() {
System.out.println("Login advice run::get method called");
}


@Pointcut("within(org.aop.model.Circle)")
public void allCircleMethods() {
}

}
---------------------------------------------------------------------------------------



Now to get a more better Idea, understanding we can use the JoinPoint provided by the aspecj and see the actual joint point.
We can define parameter for advice of type JoinPoint and print it. This will call toString() and print method -JoinPoint matching Pointcut

New Aspect and Out will be as follows

---------------------------------------------------------------------------------------
package org.aop.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class LoginAspect {

@Before("allCircleMethods()")
public void loginAdvice(JoinPoint joinPoint) {
System.out.println(joinPoint);
}

@Pointcut("within(org.aop.model.Circle)")
public void allCircleMethods() {
}

}

---------------------------------------------------------------------------------------

OutPut
====================================================

Circle set name =Circle name
execution(String org.aop.model.Circle.getName())
Circle name

====================================================

Note :
at Line 2 , it is printing the value of JoinPoint , we have change the advice to print the JoinPoint , instead of just sysout.

We can see the target object as well, it will the Circle object

---------------------------------------------------------------------------------------
package org.aop.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class LoginAspect {

@Before("allCircleMethods()")
public void loginAdvice(JoinPoint joinPoint) {
System.out.println(joinPoint.getTarget());
}


@Pointcut("within(org.aop.model.Circle)")
public void allCircleMethods() {
}

}
---------------------------------------------------------------------------------------

OutPut
====================================================

Circle set name =Circle name
org.aop.model.Circle@3f130f01
Circle name

====================================================



Line 2: Target object Circle is printed.



As above shown, you can get the target object from getTarget() and you can cast to needed Object and use it as needed in side advice.

eg : we are using Circle object
it will look as follows

---------------------------------------------------------------------------------------
@Before("allCircleMethods()")
public void loginAdvice(JoinPoint joinPoint) {
Circle circle =(Circle)joinPoint.getTarget();
              //do something
}
---------------------------------------------------------------------------------------


Thursday, March 19, 2015

Write few Pointcuts with wild cards

We are using same code in
http://cgenit.blogspot.com/2015/03/create-simple-maven-app-to-test-and.html with some modifications

We have made a simple applicatioon to test and run the AOP concept.
Here we have taken the logging aspect as a cross cutting concern.
Created LoginAspect.java and made it aspect using @Aspect and written advice using
@Before("execution(public String getName())")
The two object classes we have used is Circle and Triangle, where both having simple attribute name with getter and setter.
So we need to log it whenever the getter called.
We have created ShapeService class to get the object, for better standard way to present.
AppMain.java is used to test the application.

Pom.xml and spring.xml does not have any changes
We are changing LoginAspect.java - @Aspect class and test code changes with AppMain.java

Now here 
1. We won't to write a PointCut to execute logging for all the methods in the Circle object.
We are writing
@Pointcut("execution(* * org.aop.model.Circle.*(..))")
for any access modifier
any return type
only Circle class
all the methods
with any parameter

@Pointcut("execution(* * org.aop.model.Circle.*(..))")

public void allCircleMethods(){}


But this is not much readable , we have better way of writing this
more readable way. using  within

I have commented other methods
-------------------------------------------------------------------------------

package org.aop.aspect;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class LoginAspect {

// @Before("allGetters()")
// public void loginAdvice() {
// System.out.println("Login advice run::get method called");
// }
//
// @Before("allGetters()")
// public void secondAdvice() {
// System.out.println("Second advice executed.");
// }


@Before("allCircleMethods()")
public void allCircleAdvice() {
System.out.println("All circle executed.");
}


// @Pointcut("execution(public * *get*())")
// public void allGetters(){}

@Pointcut("within(org.aop.model.Circle)")
public void allCircleMethods(){}



}






--------------------------------------------------------------------------------

--------------------------------------------------------------------------------
package org.aop.main;

import org.aop.service.ShapeService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AppMain {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"spring.xml");

// you need to cast if not use second parameter ShapeService.class
ShapeService shapeService = ctx.getBean("shapeService",
ShapeService.class);

System.out.println(shapeService.getTriangle().getName());
System.out.println(shapeService.getCircle().getName());
}


}

--------------------------------------------------------------------------------
output Now : Note = No advice run for Triangle
===============================================================
Traingle name
All circle executed.
Circle name



===============================================================


2. Modify for all methods in the package 
just replace Circle with star


@Pointcut("within(org.aop.model.*)")

public void allCircleMethods(){}

output Now : Note =  advice run for Triangle
===============================================================
All circle executed.
Traingle name
All circle executed.
Circle name




===============================================================


3. There are few matches with Pointcut
eg: args()

4. You can combine Poincuts
First let's look at output before combining
we are running only get method for Circle.

--------------------------------------------------------------------------------
package org.aop.aspect;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class LoginAspect {

@Before("allGetters()")
public void loginAdvice() {
System.out.println("Login advice run::get method called");
}

@Before("allGetters()")
public void secondAdvice() {
System.out.println("Second advice executed.");
}

@Before("allCircleMethods()")
public void allCircleAdvice() {
System.out.println("All circle executed.");
}

@Pointcut("execution(public * *get*())")
public void allGetters() {
}

@Pointcut("within(org.aop.model.Circle)")
public void allCircleMethods() {
}


}


--------------------------------------------------------------------------------

--------------------------------------------------------------------------------
package org.aop.main;

import org.aop.service.ShapeService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AppMain {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"spring.xml");

// you need to cast if not use second parameter ShapeService.class
ShapeService shapeService = ctx.getBean("shapeService",
ShapeService.class);

// System.out.println(shapeService.getTriangle().getName());
System.out.println(shapeService.getCircle().getName());
}


}

--------------------------------------------------------------------------------

output Now : 
===============================================================
Login advice run::get method called
Second advice executed.
All circle executed.
Login advice run::get method called
Second advice executed.
Circle name


===============================================================


Now combine with &&

@Before("allGetters() && allCircleMethods()")
public void loginAdvice() {
System.out.println("Login advice run::get method called");

}


output after combinig with && 
===============================================================
Second advice executed.
All circle executed.
Login advice run::get method called
Second advice executed.
Circle name


===============================================================

Now combine with ||
@Before("allGetters() || allCircleMethods()")
public void loginAdvice() {
System.out.println("Login advice run::get method called");

}


output after combinig with || 
===============================================================
Login advice run::get method called
Second advice executed.
All circle executed.
Login advice run::get method called
Second advice executed.
Circle name


===============================================================