Hot questions for Using AspectJ in intellij idea

Top Java Programmings / AspectJ / intellij idea

Question:

I'm using the ajc compiler in IntelliJ, as well as the aspectj-maven-plugin, where I declare the following exclusions:

        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>aspectj-maven-plugin</artifactId>
            <version>1.8</version>
            <executions>
                <execution>
                    <goals>
                        <goal>compile</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <excludes>
                    <exclude>**/EmployeeAccessAspect.java</exclude>
                </excludes>
                <complianceLevel>1.8</complianceLevel>
                <showWeaveInfo>true</showWeaveInfo>
                <verbose>true</verbose>
            </configuration>
        </plugin>

When I compile using mvn compile, everything is fine and the EmployeeAccessAspect aspect is correctly ignored.

However, if I Make the project in IntelliJ, it will just weave all the aspects that it finds (and totally ignore the maven exclusions).

I can always hack the ajc compiler options or aspect path to achieve what I want, but it would make me change two places if I have to exclude an aspect for some reason.

Is there any way to make the maven plugin and the ajc compilation in sync? I am using IntelliJ 15.


Answer:

I can confirm that

  • it does not work in IDEA,
  • JetBrains knows about it at least since 2013,
  • I have commented on this issue,
  • what you want does work in Eclipse (AspectJ is an Eclipse project, so the IDE support there is considerably better).

There is not much more I can say about it other than it is a known issue which is not considered a bug, but a new feature by JetBrains (see the ticket type there).

Question:

I have the following aspect:

@Aspect
public class DefaultStringAspect {

    @Around(value = "execution(* org.apache.commons.lang3.StringUtils.defaultString(..))")
    public Object defaultString(ProceedingJoinPoint pjp) {
        return "DEF";
    }  
}

This aspect is applied to a classpath library. It works fine with maven configuration below:

           <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>aspectj-maven-plugin</artifactId>
                ..
                <configuration>
                   ..
                    <weaveDependencies>
                        <weaveDependency>
                            <groupId>org.apache.commons</groupId>
                            <artifactId>commons-lang3</artifactId>
                        </weaveDependency>
                    </weaveDependencies>
                </configuration>
            </plugin>

When I try to build the project from IntelliJ IDEA, the aspect is not applied. The aspect itself is compiled, but woven dependencies are not. I've tried to adjust ajc command line options taken from maven's debug output and add them to IntelliJ:

-showWeaveInfo -verbose -classpath ... -inpath ... -d ...

but this didn't work for me. Any other ideas how to force IntelliJ to use the same ajc configuration as maven?


Answer:

Delegate IDE build/run actions to Maven as a workaround (File | Settings | Build, Execution, Deployment | Build Tools | Maven | Runner):

Question:

I am at a loss ... I have followed the steps from Intro to AspectJ, but when I try to compile the samples with ajc, I get a "ajc: advice defined in learning.AccountAspect has not been applied [Xlint:adviceDidNotMatch]" warning on my before, around and after advices. Here is my full code:

Account.java

package learning;


public class Account {
    int balance = 20;

    public boolean withdraw(int amount) {
        if (balance < amount) {
            return false;
        }
        balance = balance - amount;
        return true;
    }
}

AccoutnAspect.aj

package learning;

public aspect AccountAspect {
    final int MIN_BALANCE = 10;

    pointcut callWithDraw(int amount, Account acc) :
            call(boolean Account.withdraw(int)) && args(amount) && target(acc);

    before(int amount, Account acc): callWithDraw(amount, acc) {
    }

    boolean around(int amount, Account acc) :
            callWithDraw(amount, acc) {
        if (acc.balance < amount) {
            System.out.println("Insufficient funds");
            return false;
        }
        System.out.println("Withdrawal approved");
        return proceed(amount, acc);
    }

    after(int amount, Account balance) : callWithDraw(amount, balance) {
    }
}

AccountTest.java

package learning;

import org.junit.Before;
import org.junit.Test;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

public class AccountTest {
    private Account account;

    @Before
    public void before() {
        account = new Account();
    }

    @Test
    public void given20AndMin10_whenWithdraw5_thenSuccess() {
        assertTrue(account.withdraw(5));
    }

    @Test
    public void given20AndMin10_whenWithdraw100_thenFail() {
        System.out.println(account.balance);
        assertFalse(account.withdraw(100));
        System.out.println(account.balance);
    }
}

I have general understanding of AOP and decent experience in C# flavor of AOP, PostSharp, but I can't wrap my head around the AspectJ implementation. Could someone shed some light on what obvious point am I missing?


Answer:

Thanks for the MCVE. I cloned it and found the problem. As I said in my previous comment...

The problem must be in your build or IDE setup, not in AspectJ.

... you had a build management problem, to be more precise your Maven POM was wrong. You configured AspectJ Maven in the <pluginManagement> section but forgot to actually add the plugin to your Maven module in the <plugins> section like this:

    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>aspectj-maven-plugin</artifactId>
        </plugin>
    </plugins>

Maybe you should learn some Maven basics first. BTW, the tutorial you were reading differs from what you did in your POM, thus the problem.

Furthermore, the plugin version RELEASE does not work, you really need to set a real version number like 1.11. I also did that for you, plus I removed your IDEA project files from the Git repository and streamlined/improved your .gitignore file. All these changes can be found and reviewed in my pull request.

Now the Maven build with mvn clean test as well as running the test from IntelliJ IDEA both work nicely.

Enjoy!

Question:

I have maven project that use aspectJ for auditing. I'm use Intellij idea. Here is my plugin config in pom file:

<plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>aspectj-maven-plugin</artifactId>
                <version>1.7</version>
                <configuration>
                    <showWeaveInfo>true</showWeaveInfo>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                    <Xlint>ignore</Xlint>
                    <complianceLevel>${java.version}</complianceLevel>
                    <encoding>UTF-8</encoding>
                    <verbose>true</verbose>
                </configuration>
                <executions>
                    <execution>
                        <!-- IMPORTANT -->
                        <phase>process-sources</phase>
                        <goals>
                            <goal>compile</goal>
                            <goal>test-compile</goal>
                        </goals>
                    </execution>
                </executions>
                <dependencies>
                    <dependency>
                        <groupId>org.aspectj</groupId>
                        <artifactId>aspectjtools</artifactId>
                        <version>1.8.10</version>
                    </dependency>
                </dependencies>
</plugin>

When I clean package the aspectJ plugin says:

Join point 'method-execution(java.util.List com.test.getHistories(java.lang.String, java.lang.String))' in Type 'com.test.HistoryService' (HistoryService.java:18) advised by around advice from 'com.test.aspects.AuditLoggerAspect' (AuditLoggerAspect.java:88)

Join point 'method-execution(java.lang.String com.test.getString(int, java.lang.Object))' in Type 'com.test' (AspectTest.java:14) advised by around advice from 'com.test.AuditLoggerAspect' (AuditLoggerAspect.class(from AuditLoggerAspect.java))

This app packaging is WAR and i want to deploy it on Weblogic. When I deploy it or run test the aspect not work. Why?

I test this aspect and maven plugin config in Java App and it's work good.


Answer:

When I clean and package the project, the maven-compiler-plugin recompiles the projects after aspectj-compiler-plugin compiled it. So the compiled aspects are removed.

I added the below config to maven-compiler-plugin to solve it:

<plugin>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.1</version>
    <configuration>
        <source>${java.version}</source>
        <target>${java.version}</target>
        <!-- IMPORTANT -->
        <useIncrementalCompilation>false</useIncrementalCompilation>
    </configuration>
</plugin>