Motomine
Motomine

Reputation: 4504

How to convert annotation-based into native AspectJ syntax

I have some troubles with aspectj and its syntax. I have something written on a java file and I want to translate it to an .aj file because I think that is easier, but I can't find a tutorial to follow.

This is my code:

@Aspect
public class Aspect{

    @Pointcut("@annotation(annotationVariableName)")
    public void annotationPointCutDefinition(Annotation annotationVariableName){
    }

    @Pointcut("execution(* *(..))")
    public void atExecution(){}

    @Around("annotationPointCutDefinition(withTransactionVariableName) && atExecution()")
    public Object aroundAdvice(ProceedingJoinPoint joinPoint, Annotation annotationVariableName) throws Throwable {
        boolean parameter= annotationVariableName.parameter();
            Object returnObject = null;

            try {
                returnObject = joinPoint.proceed();
            } catch (Throwable throwable) {
                throw throwable;
            }
            return returnObject;
    }
}

Can anyone help me with this? Thank you!

Upvotes: 0

Views: 693

Answers (2)

kriegaex
kriegaex

Reputation: 67297

I have made up a little example MCVE relating to your comment about transaction management, so as to make the code and its log output a little clearer:

Annotation:

package de.scrum_master.app;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Transaction {
  boolean myFlag();
}

Driver application:

Please note that two methods bear the annotation, one does not.

package de.scrum_master.app;

public class Application {
  public static void main(String[] args) {
    Application application = new Application();
    application.doSomething();
    application.doSomethingElse();
    application.doSomethingWeird();
  }

  @Transaction(myFlag = true)
  public void doSomething() {
    System.out.println("Doing something");
  }

  public void doSomethingElse() {
    System.out.println("Doing something else\n");
  }

  @Transaction(myFlag = false)
  public void doSomethingWeird() {
    System.out.println("Doing something weird");
    throw new RuntimeException("oops");
  }
}

Aspect:

package de.scrum_master.aspect;

import org.aspectj.lang.SoftException;

import de.scrum_master.app.Transaction;

public aspect TransactionAspect {
  pointcut hasAnnotation(Transaction myAnnotation) : @annotation(myAnnotation);

  pointcut methodExecution() : execution(* *(..));

  Object around(Transaction myAnnotation) : methodExecution() && hasAnnotation(myAnnotation) {
    System.out.println(thisJoinPoint + " -> " + myAnnotation);
    boolean parameter = myAnnotation.myFlag();
    System.out.println("Transaction start");
    try {
      Object result = proceed(myAnnotation);
      System.out.println("Transaction commit\n");
      return result;
    } catch (Exception e) {
      System.out.println("Transaction roll-back\n");
      // Native AspectJ advices must not return checked exceptions, only runtime exceptions.
      // So we soften the caught exception, just in case.
      throw new SoftException(e);
    }
  }
}

Console log:

execution(void de.scrum_master.app.Application.doSomething()) -> @de.scrum_master.app.Transaction(myFlag=true)
Transaction start
Doing something
Transaction commit

Doing something else

execution(void de.scrum_master.app.Application.doSomethingWeird()) -> @de.scrum_master.app.Transaction(myFlag=false)
Transaction start
Doing something weird
Transaction roll-back

Exception in thread "main" org.aspectj.lang.SoftException
    at de.scrum_master.app.Application.doSomethingWeird_aroundBody3$advice(Application.java:22)
    at de.scrum_master.app.Application.doSomethingWeird(Application.java:1)
    at de.scrum_master.app.Application.main(Application.java:8)
Caused by: java.lang.RuntimeException: oops
    at de.scrum_master.app.Application.doSomethingWeird_aroundBody2(Application.java:23)
    at de.scrum_master.app.Application.doSomethingWeird_aroundBody3$advice(Application.java:17)
    ... 2 more

By the way, if you are fine with anonymous pointcuts, there is no need to declare them separately. You can just do it this way:

Aspect variant with anonymous pointcut:

package de.scrum_master.aspect;

import org.aspectj.lang.SoftException;

import de.scrum_master.app.Transaction;

public aspect TransactionAspect {
  Object around(Transaction myAnnotation) : execution(* *(..)) && @annotation(myAnnotation) {
    System.out.println(thisJoinPoint + " -> " + myAnnotation);
    boolean parameter = myAnnotation.myFlag();
    System.out.println("Transaction start");
    try {
      Object result = proceed(myAnnotation);
      System.out.println("Transaction commit\n");
      return result;
    } catch (Exception e) {
      System.out.println("Transaction roll-back\n");
      // Native AspectJ advices must not return checked exceptions, only runtime exceptions.
      // So we soften the caught exception, just in case.
      throw new SoftException(e);
    }
  }
}

Upvotes: 1

cookie_monster
cookie_monster

Reputation: 131

Personally I found the following programmer guide useful myself although it's not really a tutorial : https://eclipse.org/aspectj/doc/next/progguide/index.html. Click on Pointcuts to get the basics of converting your pointcuts, advice is also covered on that page although it doesn't detail "around" advice but there is an example of that under production aspects

A quick search for a tutorial throws up the following (I haven't used this) : http://o7planning.org/en/10257/java-aspect-oriented-programming-tutorial-with-aspectj

Upvotes: 0

Related Questions