IntelliJ IDEA + AspectJ

spam picture spam · May 20, 2017 · Viewed 7k times · Source

I am trying to use AspectJ in sample project in IntelliJ IDEA. I have an experience with Spring AOP, but this is first time I am using AspectJ, and cannot make it work.

I am trying to do as described here: https://www.jetbrains.com/help/idea/2017.1/aspectj.html

My build.gradle:

apply plugin: 'java'

repositories
{
    mavenCentral()
}

dependencies
{
    compile "org.projectlombok:lombok:+"

    compile "org.aspectj:aspectjrt:+"
    compile "org.aspectj:aspectjweaver:+"
    compile "org.aspectj:aspectjtools:+"
}

buildscript
{
    repositories
    {
        maven
        {
            url "https://maven.eveoh.nl/content/repositories/releases"
        }
    }

    dependencies
    {
        classpath "nl.eveoh:gradle-aspectj:+"
    }
}

project.ext
{
    aspectjVersion = '+'
}

apply plugin: 'aspectj'

My aspect:

package aspects;

import lombok.SneakyThrows;
import lombok.experimental.FieldDefaults;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;

import java.util.Arrays;

@Aspect
@FieldDefaults(makeFinal = true)
public aspect LoggingAspect
{
    Journal journal = Journal.INSTANCE;

    pointcut all(ProceedingJoinPoint proceedingJoinPoint) : execution(* * set*(..) );

    around() : all(ProceedingJoinPoint proceedingJoinPoint)
    {
        System.out.println("asd");
    }

    @SneakyThrows
    @Around("execution(* * repository.*.*(..))")
    public Object log(ProceedingJoinPoint proceedingJoinPoint)
    {
        journal.write(proceedingJoinPoint.getThis().getClass().getCanonicalName());
        journal.write("\n");

        String arguments = Arrays
            .stream(proceedingJoinPoint.getArgs())
            .map(o -> o.getClass().getCanonicalName() + " " + o.toString())
            .reduce(new StringBuilder(), StringBuilder::append, StringBuilder::append)
            .toString();

        journal.write(arguments);
        journal.write("\n");

        long start = System.currentTimeMillis();

        Object result = proceedingJoinPoint.proceed();

        journal.write(result.toString());
        journal.write("\n");

        journal.write(String.valueOf(System.currentTimeMillis() - start));
        journal.write("\n\n");
        journal.flush();

        return result;
    }
}

Sample class:

package repository;

import java.io.Serializable;

public class Task implements Serializable
{
    private static final long serialVersionUID = 1L;

    enum Status {NEW, IN_PROGRESS, FINISHED};

    private Integer id;
    private String description;
    private Employee assignee;
    private Employee reporter;
    private Status status;

    public Task(final Integer id, String description, final Employee assignee, final Employee reporter) {
        this.id = id;
        this.assignee = assignee;
        this.reporter = reporter;
        this.description = description;
        this.status = Status.NEW;
    }

    public Employee getAssignee() {
        return assignee;
    }

    public void setAssignee(Employee assignee) {
        this.assignee = assignee;
    }

...
}

I have IntelliJ IDEA Ultimate 2017.2 and it hints correctly that all methods (getters and setters) are my point-cuts. It also hints me that for advice "log" in my aspect there are multiple point-cuts. However, it does not hint about "all" advice.

I have installed (in newest version) plugins like: - AspectJ Support - AspectJ weaver - Spring AOP/@AspectJ

Gradle dependencies automatically created libraries for this project so I did not duplicate it.

I have enabled: Build > AspectJ weaving.

Settings > Build, Execution, Deployment > Compiler > Java Compiler:

Use compiler: ajc

Path to Ajc compiles: /home/me/.gradle/caches/modules-2/files-2.1/org.aspectj/aspectjtools/1.8.10/5c5957ee4615bde33b54ce965f5b85b8827b97d5/aspectjtools-1.8.10.jar

Command line parameters: empty

Generate debug info: checked

Delegate to javac: chcecked

Enable annotation processing options: checked

Project builds and compiles without problem. It runs like there was never any aspect, particularity nothing from aspect is printed out and no temporary files are created, and all methods runs fine (although in my "all" advice that is around I have not processed joint point).

When I create breakpoints in first lines of any advice and run project with debugger nothing is caught.

What am I missing?

Answer

spam picture spam · May 25, 2017

After wasting even more hours, I found out that I have mixed two distinct AspectJ sytnax together.

One that is just about aspects (like "public aspect LoggingAspect"), and second one that are regular Java annotations (like "@Aspect" or "@Around").

When I have replaced "public aspect LoggingAspect" with "public class LoggingAspect" it worked. It was very hard to find out, because everything still compiles without problem.

Hope it helps somebody someday or at least in future version of ajc they will add more verbose compiler output.