0

I have a bunch of methods that are marked with @Transactional annotation and then they do self-invocation and some of the methods are private, so I want to use AspectJ flavour of transaction management with Spring.

I am compiling my code with aspectj-maven-plugin version 1.11:

            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>aspectj-maven-plugin</artifactId>
                <version>1.11</version>
                <configuration>
                    <proc>none</proc>
                    <forceAjcCompile>true</forceAjcCompile>
                    <complianceLevel>${java.version}</complianceLevel>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                    <showWeaveInfo>true</showWeaveInfo>


                    <aspectLibraries>
                        <aspectLibrary>
                            <groupId>org.springframework</groupId>
                            <artifactId>spring-aspects</artifactId>
                        </aspectLibrary>
                    </aspectLibraries>


                    <sources>
                        <source>
                            <basedir>${project.build.directory}/generated-sources/annotations</basedir>
                        </source>
                        <source>
                            <basedir>${project.build.directory}/generated-sources/delombok</basedir>
                        </source>
                    </sources>
                    <testSources>
                        <source>
                            <basedir>
                                ${project.build.directory}/generated-test-sources/delombok
                            </basedir>
                        </source>
                    </testSources>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>test-compile</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

The compile part works fine and I see my classes being woven in the logs and I can also see that in the class files: a bunch of ...$AjcClosure... classes.

But then, my maven script is executing integration tests (which are spring boot tests) using maven surefire plugin and the tests that are meant to verify if the transaction is being rollbacked in case an exception is being thrown, are failing.

Here is my @Configuration file:

@Configuration
@EnableTransactionManagement(mode = AdviceMode.ASPECTJ)
public class MyAppConfig {

// some beans not related to persistence

}

What am I missing here?

Ihor M.
  • 2,728
  • 3
  • 44
  • 70

2 Answers2

1

In order to configure CTW I had to configure following bean in my config:

    @Bean
    public PlatformTransactionManager txManager(DataSource dataSource) {
        DataSourceTransactionManager txManager = new DataSourceTransactionManager(dataSource);
        AnnotationTransactionAspect.aspectOf().setTransactionManager(txManager);
        return txManager;
    }

Also, my maven file evolved into:

           <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>aspectj-maven-plugin</artifactId>
                <version>1.11</version>
                <configuration>
                    <proc>none</proc>
                    <Xlint>ignore</Xlint>
                    <forceAjcCompile>true</forceAjcCompile>
                    <complianceLevel>${java.version}</complianceLevel>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                    <showWeaveInfo>true</showWeaveInfo>
                    <sources/>
                    <testSources/>
                    <aspectLibraries>
                        <aspectLibrary>
                            <groupId>org.springframework</groupId>
                            <artifactId>spring-aspects</artifactId>
                        </aspectLibrary>
                    </aspectLibraries>
                </configuration>
                <executions>
                    <execution>
                        <id>compile-sources</id>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                        <configuration>
                            <weaveDirectories>
                                <weaveDirectory>${project.build.outputDirectory}</weaveDirectory>
                            </weaveDirectories>
                        </configuration>
                    </execution>
                    <execution>
                        <id>compile-test-sources</id>
                        <goals>
                            <goal>test-compile</goal>
                        </goals>
                        <configuration>
                            <weaveDirectories>
                                <weaveDirectory>${project.build.testOutputDirectory}</weaveDirectory>
                            </weaveDirectories>
                        </configuration>
                    </execution>
                </executions>
                <dependencies>
                    <dependency>
                        <groupId>org.aspectj</groupId>
                        <artifactId>aspectjtools</artifactId>
                        <version>${aspectj.version}</version>
                    </dependency>
                    <dependency>
                        <groupId>org.aspectj</groupId>
                        <artifactId>aspectjrt</artifactId>
                        <version>${aspectj.version}</version>
                    </dependency>
                </dependencies>
            </plugin>
Ihor M.
  • 2,728
  • 3
  • 44
  • 70
0

You do not need AspectJ Maven or any other type of compile-time weaving tool in order for this to work in Spring. Just use AspectJ via LTW (load-time weaving) instead.

kriegaex
  • 63,017
  • 15
  • 111
  • 202
  • I tried to configure LTW and it never worked for me. On top of that CTW should have better performance. – Ihor M. Oct 18 '19 at 12:33
  • The performance of LTW vs CTW is identical except for the longer class-loading time with LTW. I suggest you get LTW working and concentrate on finding out what is wrong there. But I can also help you with CTW, if (and only if) you provide an [MCVE](https://stackoverflow.com/help/mcve) on GitHub for me to reproduce and analyse your problem. Thank you. – kriegaex Oct 19 '19 at 12:44
  • The reason I didn't want to use LTW b/c I have a datadog agent instrumenting my jar already. If I have several jars instrumenting my app jar there might be unexpected behavior caused by the class loading. – Ihor M. Nov 15 '19 at 02:45