Home > front end >  Spring aspects woven by AspectJ compiler working in Maven, but not in IntelliJ IDEA
Spring aspects woven by AspectJ compiler working in Maven, but not in IntelliJ IDEA

Time:12-27

I'm using Spring boot 2.5.5 with AspectJ 1.9.7 (CTW). I've spotted that sometimes transactions don't roll back and to fix that I need only recompile code and run it again. For example:

I have method addB() persisting entity B, method addC() throwing exception and method A() combining them. When I call A(), exception is thrown, but entity B stays in database (as expected). When I annotate method A() with @Transactional result is the same. But if I build everything again (without any changes) then transaction is being rollbacked and there is no new record in database.

Here is my full POM:

<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.5</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.abcc</groupId>
    <artifactId>abcc</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>abcc</name>
    <description>abcc</description>
    <properties>
        <java.version>11</java.version>
        <log4j2.version>2.15.0</log4j2.version>
        <aspectj.version>1.9.7</aspectj.version>
        <aspectj-maven-plugin.version>1.14.0</aspectj-maven-plugin.version>
    </properties>
    <dependencies>
        <!--SPRING-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-rest</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>
        <!--CACHE-->
        <dependency>
            <groupId>javax.cache</groupId>
            <artifactId>cache-api</artifactId>
            <version>1.1.1</version>
        </dependency>
        <dependency>
            <groupId>org.ehcache</groupId>
            <artifactId>ehcache</artifactId>
            <version>3.8.1</version>
        </dependency>
        <!--DATABASE-->
        <dependency>
            <groupId>org.flywaydb</groupId>
            <artifactId>flyway-core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-boot-starter</artifactId>
            <version>3.0.0</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>3.0.0</version>
        </dependency>
        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>3.18.1</version>
        </dependency>
        <dependency>
            <groupId>org.assertj</groupId>
            <artifactId>assertj-core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.hibernate.validator</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>6.0.19.Final</version>
        </dependency>
        <dependency>
            <groupId>org.passay</groupId>
            <artifactId>passay</artifactId>
            <version>1.6.1</version>
        </dependency>
        <dependency>
            <groupId>org.modelmapper</groupId>
            <artifactId>modelmapper</artifactId>
            <version>2.4.2</version>
        </dependency>
        <dependency>
            <groupId>com.sanctionco.jmail</groupId>
            <artifactId>jmail</artifactId>
            <version>1.3.2</version>
        </dependency>
        <dependency>
            <groupId>joda-time</groupId>
            <artifactId>joda-time</artifactId>
            <version>2.10.13</version>
        </dependency>
        <!--AOP-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>${aspectj.version}</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>${aspectj.version}</version>
        </dependency>
    </dependencies>

    <profiles>
        <profile>
            <id>dev</id>
            <properties>
                <activatedProperties>dev</activatedProperties>
            </properties>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
        </profile>
        <profile>
            <id>test</id>
            <properties>
                <activatedProperties>test</activatedProperties>
            </properties>
            <dependencies>
                <dependency>
                    <groupId>com.h2database</groupId>
                    <artifactId>h2</artifactId>
                    <version>1.4.191</version>
                </dependency>
            </dependencies>
        </profile>
    </profiles>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                    <excludeDevtools>false</excludeDevtools>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <configuration>
                    <trimStackTrace>false</trimStackTrace>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>aspectj-maven-plugin</artifactId>
                <version>${aspectj-maven-plugin.version}</version>
                <dependencies>
                    <dependency>
                        <groupId>org.aspectj</groupId>
                        <artifactId>aspectjrt</artifactId>
                        <version>${aspectj.version}</version>
                    </dependency>
                    <dependency>
                        <groupId>org.aspectj</groupId>
                        <artifactId>aspectjtools</artifactId>
                        <version>${aspectj.version}</version>
                    </dependency>
                </dependencies>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>test-compile</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <showWeaveInfo>true</showWeaveInfo>
                    <Xlint>ignore</Xlint>
                    <verbose>true</verbose>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                    <complianceLevel>${java.version}</complianceLevel>
                    <encoding>utf-8</encoding>
                    <outxml>true</outxml>
                    <aspectLibraries>
                        <aspectLibrary>
                            <groupId>org.springframework</groupId>
                            <artifactId>spring-aspects</artifactId>
                        </aspectLibrary>
                    </aspectLibraries>
                    <excludes>
                        <exclude>**/*.java</exclude>
                    </excludes>
                    <forceAjcCompile>true</forceAjcCompile>
                    <sources/>
                    <weaveDirectories>
                        <weaveDirectory>${project.build.outputDirectory}</weaveDirectory>
                    </weaveDirectories>
                </configuration>
            </plugin>
        </plugins>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
            </resource>
        </resources>
    </build>
</project>

It's very strange situation, which I can't find information on. Could you help with finding reason to it?

CodePudding user response:

I cannot reproduce the problem because IDEA does not find the Lombok setters. Even when delegating build actions before run to Maven, I get NoSuchMethodError: '...TestEntity.setCode(java.lang.String)'. Next, I am going to try without Lombok. Please note that Lombok and AspectJ do not play nice with each other, see IntelliJ IDEA run configuration


Update: As we found out in the comment section of the other answer, in addition to the problematic Lombok vs. AspectJ compiler configuration, the OP also simply had a problem with his IDE: Using IntelliJ IDEA Community Edition, he was first unaware of, then unable to install the AspectJ plugin, which means that IDEA does not know antyhing about the AspectJ compiler and simply overwrites anything which might have been compiled by AspectJ Maven before with plain Java classes. Therefore, transactional aspects do not work either, unless

  • either pre-run compilation is disabled and mvn compile started as an additional pre-build step for the corresponding run configuration,
  • or all build actions for the project are being delegated to Maven via configuration,
  • the OP buys a licence of IDEA Ultimate and installs the AspectJ plugin.

CodePudding user response:

First of all: your multi-module approach works perfectly in my environment. But then I checked initial MCVE and when I completely removed Lombok, strange behaviour did not disappear. When reading your answers (this one) I have checked "Delegate IDE build/run actions to maven" in IntelliJ settings (Build Tools -> Maven -> Runner) and it started working as it should. In next step I switched this option off and checked "Do not build before run" in run configuration. I do not understand it completely (especially why did it work in old way after second try), but your comment helped me to reach that.

I will research IntelliJ behaviour (in two scenarios console output is almost identical), but if you have idea why does it work like that I would be glad to hear it. You helped me a lot, thank you!

Summary solution: I have enabled "Do not build before run" in IntelliJ run configuration for my application. Now changes works after first build.

  • Related