I've gone through many Aspect related posts, but none of them seem to help me. I see a lot of the posts are really old, and all the example GitHub repositories only feature a single .jar when I'm working with multiple.
I know my common jar is being included properly because I can see other code clearly working. When I build the common jar then I see my aspect printed in the output logs.
mvn clean install
logs
-------------------------------------------------------
T E S T S
-------------------------------------------------------
[AppClassLoader@18b4aac2] info AspectJ Weaver Version 1.8.13 built on Wednesday Nov 15, 2017 at 19:26:44 GMT
[AppClassLoader@18b4aac2] info register classloader sun.misc.Launcher$AppClassLoader@18b4aac2
[AppClassLoader@18b4aac2] info using configuration /C:/Users/<username>/Documents/IntelliJ/Team-Common/team-common/target/classes/META-INF/aop.xml
[AppClassLoader@18b4aac2] info using configuration file:/C:/Users/<username>/.m2/repository/org/springframework/spring-aspects/4.3.13.RELEASE/spring-aspects-4.3.13.RELEASE.jar!/META-INF/aop.xml
[AppClassLoader@18b4aac2] info register aspect com.mycompany.myteam.common.aspect.MyAspect
[AppClassLoader@18b4aac2] info register aspect org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect
[AppClassLoader@18b4aac2] info register aspect org.springframework.scheduling.aspectj.AnnotationAsyncExecutionAspect
[AppClassLoader@18b4aac2] info register aspect org.springframework.transaction.aspectj.AnnotationTransactionAspect
[AppClassLoader@18b4aac2] info register aspect org.springframework.transaction.aspectj.JtaAnnotationTransactionAspect
[AppClassLoader@18b4aac2] info register aspect org.springframework.cache.aspectj.AnnotationCacheAspect
[AppClassLoader@18b4aac2] info register aspect org.springframework.cache.aspectj.JCacheCacheAspect
[AppClassLoader@18b4aac2] info deactivating aspect 'org.springframework.cache.aspectj.JCacheCacheAspect' as it requires type 'org.springframework.cache.jcache.interceptor.JCacheAspectSupport' which cannot be found on the classpath
[AppClassLoader@18b4aac2] info deactivating aspect 'org.springframework.cache.aspectj.JCacheCacheAspect' as it requires type 'javax.cache.annotation.CacheResult' which cannot be found on the classpath
[IsolatedClassLoader@48503868] info AspectJ Weaver Version 1.8.13 built on Wednesday Nov 15, 2017 at 19:26:44 GMT
[IsolatedClassLoader@48503868] info register classloader org.apache.maven.surefire.booter.IsolatedClassLoader@48503868
[IsolatedClassLoader@48503868] info using configuration /C:/Users/<username>/Documents/IntelliJ/Team-Common/team-common/target/classes/META-INF/aop.xml
[IsolatedClassLoader@48503868] info using configuration file:/C:/Users/<username>/.m2/repository/org/springframework/spring-aspects/4.3.13.RELEASE/spring-aspects-4.3.13.RELEASE.jar!/META-INF/aop.xml
[IsolatedClassLoader@48503868] info register aspect com.mycompany.myteam.common.aspect.MyAspect
[IsolatedClassLoader@48503868] info register aspect org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect
[IsolatedClassLoader@48503868] info register aspect org.springframework.scheduling.aspectj.AnnotationAsyncExecutionAspect
[IsolatedClassLoader@48503868] info register aspect org.springframework.transaction.aspectj.AnnotationTransactionAspect
[IsolatedClassLoader@48503868] info register aspect org.springframework.transaction.aspectj.JtaAnnotationTransactionAspect
[IsolatedClassLoader@48503868] info register aspect org.springframework.cache.aspectj.AnnotationCacheAspect
[IsolatedClassLoader@48503868] info register aspect org.springframework.cache.aspectj.JCacheCacheAspect
[IsolatedClassLoader@48503868] info deactivating aspect 'org.springframework.cache.aspectj.JCacheCacheAspect' as it requires type 'org.springframework.cache.jcache.interceptor.JCacheAspectSupport' which cannot be found on the classpath
[IsolatedClassLoader@48503868] info deactivating aspect 'org.springframework.cache.aspectj.JCacheCacheAspect' as it requires type 'javax.cache.annotation.CacheResult' which cannot be found on the classpath
Results :
Tests run: 0, Failures: 0, Errors: 0, Skipped: 0
When I invoke the API in the UserSearch.jar it returns data properly, but the Aspect is never fired even though the controller method matches the pointcut of my aspect inside the Common Jar.
Why isn't my Common Jar aspect intercepting the UserSeach application?
Here is my application structure.
Common Jar
package com.mycompany.myteam.common.aspect;
@Aspect
@Component
public class MyAspect {
private static final Logger LOGGER = LoggerFactory.getLogger(AuditAdvice.class);
@Around("execution(public * com.mycompany.myteam.*.*Controller.*(..)) "
+ "&& !execution(public * com.mycompany.myteam.*.AuditController.*(..))")
public Object aroundRestEndpoints(ProceedingJoinPoint pjp) throws Throwable {
System.err.println("\n\n---------------------------------INSIDE ASPECT---------------------------------\n\n");
return pjp.proceed();
}
}
package com.mycompany.myteam.common.config;
@Configuration
@EnableAspectJAutoProxy
public class CommonAppConfig {
// ... Unrelated
}
/src/main/resources/META-INF/aop.xml
<aspectj>
<aspects>
<aspect name="com.mycompany.myteam.common.aspect.MyAspect"/>
<weaver options="-verbose -showWeaveInfo">
<include within="com.mycompany.myteam.*"/>
</weaver>
</aspects>
</aspectj>
pom.xml
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.myteam.common</groupId>
<artifactId>team-common</artifactId>
<version>1.0.0</version>
<name>team-common</name>
<description>team-common</description>
<properties>
<java.version>1.8</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<packaging>jar</packaging>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- Dependency Versions -->
<aspectj.version>1.8.13</aspectj.version>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
</parent>
<dependencies>
<!-- AOP -->
<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>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Spring Boot -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</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-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<repositories>
<repository>
<id>central</id>
<name>libs-release</name>
<url>http://somerepo.com/artifacts/release</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>snapshots</id>
<name>libs-snapshot</name>
<url>http://somerepo.com/artifacts/snapshot</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>spring-milestones</id>
<name>spring-milestones</name>
<url>http://somerepo.com/artifacts/milestones</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.11</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>
<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>${aspectj.version}</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.9</version>
<configuration>
<argLine>-XX:-UseSplitVerifier</argLine>
<argLine>
-javaagent:"${settings.localRepository}"/org/aspectj/aspectjweaver/${aspectj.version}/aspectjweaver-${aspectj.version}.jar
</argLine>
</configuration>
</plugin>
</plugins>
</build>
</project>
UserSearch.jar
package com.mycompany.myteam.usersearch.controller;
@RestController
@RequestMapping("/usersearch")
public class UserSearchController {
@Autowired
private UserSearchService userSearchService;
@RequestMapping(value = "/{name}", method = RequestMethod.GET, produces = "application/json")
public List<UserDTO> search(@PathVariable("name") String name){
return userSearchService.search(name);
}
}
package com.mycompany.myteam.usersearch;
@SpringBootApplication
@ComponentScan("com.mycompany.myteam")
public class UserSearchApplication {
public static void main(String[] args) {
SpringApplication.run(UserSearchApplication.class, args);
}
}
pom.xml
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.myteam.usersearch</groupId>
<artifactId>user-search</artifactId>
<version>1.0.0</version>
<name>user-search</name>
<description>user-search</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
</parent>
<properties>
<java.version>1.8</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<packaging>jar</packaging>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<start-class>com.mycompany.myteam.usersearch.UserSearchApplication</start-class>
</properties>
<dependencies>
<!-- Commons -->
<dependency>
<groupId>com.mycompany.myteam.common</groupId>
<artifactId>team-common</artifactId>
<version>1.0.0</version>
</dependency>]
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Spring Boot -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</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-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
I copied your source and XML files into new Maven projects. What I wrote in my comments as an educated guess is actually true:
You do not need any AspectJ LTW or CTW, i.e. you can remove
Spring AOP works nicely with your multi-module setup.
@Around(
"execution(public * com.mycompany.myteam..*Controller.*(..)) && " +
"!execution(public * com.mycompany.myteam..AuditController.*(..))"
)
I had to fix some stuff in your classes (e.g. rename the aspect to match the logger name, add a dummy service and DTO with corresponding methods in order to make the code compile) and add H2 database driver to your user-search POM. Then everything worked nicely.