Hot questions for Using AspectJ in load time weaving

Top Java Programmings / AspectJ / load time weaving

Question:

Here is my sample non-working project.

It contains 2 modules:

  • aop-lib - Aspects used as lib. It contains the following classes
    1. Wrap.java - It's the annotation used to attach advice
    2. WrapDef.java - It is the definition of the above mentioned Wrap annotation.
  • aop-app - Uses the above aspect lib
    1. DynamicLoad.java - class to load javaagent dynamically
    2. Main.java - Main class which uses Wrap annotation.

Dir structure is as follows:

.
├── README.md
├── aop-app
│   ├── pom.xml
│   └── src
│       └── main
│           └── java
│               └── com
│                   └── aop
│                       └── app
│                           ├── DynamicLoad.java
│                           └── Main.java
└── aop-lib
    ├── pom.xml
    └── src
        └── main
            └── java
                └── com
                    └── aop
                        └── app
                            └── lib
                                ├── Wrap.java
                                └── WrapDef.java

I'm trying to use the aspect lib aop-lib (an AOP advice lib) inside aop-app through Load Time Weaving (LTW) by dynamically loading the javaagent as mentioned in the official docs. But it's not working.

Following are the contents of Wrap.java

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(value = RetentionPolicy.RUNTIME)
public @interface Wrap { }

Following are the contents of WrapDef.java

@Aspect
public class WrapDef {
    private static final Logger logger = LoggerFactory.getLogger(WrapDef.class);

    public static boolean loaded = false;

    @Around("@annotation( wrapAnnotation ) && execution(* *(..))")
    public Object processSystemRequest(final ProceedingJoinPoint pjp, Wrap wrapAnnotation)
            throws Throwable {
        logger.debug("before wrap");
        Object o = pjp.proceed();
        logger.debug("after wrap");
        return o;
    }

    static {
        System.out.println("Loading");
        WrapDef.loaded = true;
    }
    public static void reportLoaded() {
        System.out.println("loaded : " + loaded);
    }
}

Following are the contents of Main.java:

public class Main {

    private static final Logger logger = LoggerFactory.getLogger(Main.class);

    @Wrap
    public void myFunc(){
        logger.debug("inside myFunc");
    }

    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {

        boolean dynamicLoad = Boolean.getBoolean("dynamicLoad");
        if(dynamicLoad){
            Main.isAdviceClassLoaded();           //To see if WrapDef.java is loaded or not.
            if(!DynamicLoad.isAspectJAgentLoaded()) {
                logger.error("AspectJ Not Loaded. Existing.");
                System.exit(0);
            }
            Main.isAdviceClassLoaded();           //To see if WrapDef.java is loaded or not.
        }

        new Main().myFunc();
    }

    private static void isAdviceClassLoaded() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        java.lang.reflect.Method m = ClassLoader.class.getDeclaredMethod("findLoadedClass", String.class);
        m.setAccessible(true);
        ClassLoader cl = ClassLoader.getSystemClassLoader();
        Object test1 = m.invoke(cl, "com.aop.app.lib.WrapDef");
        boolean loaded = test1 != null;
        System.out.println("com.aop.app.lib.WrapDef Loaded : " + loaded);
    }

}

With javaagent as cmd line arg, it works perfectly fine:

$ java -javaagent:deploy/lib/aspectjweaver-1.9.1.jar -classpath aop-app-1.0.jar:deploy/lib/* com.aop.app.Main
14:02:45.384 [main] DEBUG com.aop.app.lib.WrapDef - before wrap
14:02:45.391 [main] DEBUG com.aop.app.Main - inside myFunc
14:02:45.391 [main] DEBUG com.aop.app.lib.WrapDef - after wrap

But, with Dynamic loading of javaagent, it gives the following output:

$ java -DdynamicLoad=true -DAGENT_PATH=deploy/lib/aspectjweaver-1.9.1.jar -classpath aop-app-1.0.jar:deploy/lib/* com.aop.app.Main
com.aop.app.lib.WrapDef Loaded : false                   //The WrapDef is NOT loaded before JAVAAGENT is Loaded - which is correct
java.lang.UnsupportedOperationException: AspectJ weaving agent was neither started via '-javaagent' (preMain) nor attached via 'VirtualMachine.loadAgent' (agentMain)
loading javaAgent deploy/lib/aspectjweaver-1.9.1.jar
loaded javaAgent deploy/lib/aspectjweaver-1.9.1.jar      //The JAVAAGENT is Dynamically Loaded - which is correct
com.aop.app.lib.WrapDef Loaded : false                   //The WrapDef is STILL NOT loaded even AFTER JAVAAGENT is Loaded - THIS IS THE ISSUE
15:53:08.543 [main] DEBUG com.aop.app.Main - inside myFunc

The official docs does say that any classes loaded before attachment will not be woven. But, on the contrary as you can see in the above output, the WrapDef class is not loaded at all.

Also, note that I'm using aspectj-maven-plugin in my aop-lib/pom.xml, with the following options:

<outxml>true</outxml>                           //creates META-INF/aop-ajc.xml
<showWeaveInfo>true</showWeaveInfo>             //supposed to create <weaver options="-showWeaveInfo"/> BUT DOES NOT WORK
<verbose>true</verbose>                         //supposed to create <weaver options="-verbose"/> BUT DOES NOT WORK

So, it creates META-INF/aop-ajc.xml inside aop-lib-1.0.jar with the following content:

<aspectj>
<aspects>
<aspect name="com.aop.app.lib.WrapDef"/>
</aspects>
</aspectj>

but the other tags corresponding to showWeaveInfo & verbose are not created in META-INF/aop-ajc.xml. This is another thing that is not working here.

If you require any other info - I shall provide it.

Any help is appreciated.


Answer:

The explanation is quite simple: You are testing the weaving agent directly in class Main which is already loaded before you attach that very agent from that class. So you have to avoid classes which you like to be woven to be loaded too early. I suggest you put method myFunc() (horrible name, by the way) into another class. How about that?

package com.aop.app;

import com.aop.app.lib.Wrap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Application {
  private static final Logger logger = LoggerFactory.getLogger(Application.class);

  @Wrap
  public void myFunc(){
    logger.debug("inside myFunc");
  }

  public static void main(String[] args) {
    new Application().myFunc();
  }
}

Then in the last line of Main.main(..) you start the actual application you want woven:

Application.main(null);

This will yield the following output:

com.aop.app.lib.WrapDef Loaded : false
java.lang.UnsupportedOperationException: AspectJ weaving agent was neither started via '-javaagent' (preMain) nor attached via 'VirtualMachine.loadAgent' (agentMain)
loading javaAgent aop-app/target/deploy/lib/aspectjweaver-1.9.1.jar
loaded javaAgent aop-app/target/deploy/lib/aspectjweaver-1.9.1.jar
com.aop.app.lib.WrapDef Loaded : false
Loading
07:56:21.703 [main] DEBUG com.aop.app.lib.WrapDef - before wrap
07:56:21.716 [main] DEBUG com.aop.app.Application - inside myFunc
07:56:21.716 [main] DEBUG com.aop.app.lib.WrapDef - after wrap

P.S.: Do you really think it is easier for users of your aspect library to specify two properties on the JVM command line instead of just using -javaagent:/path/to/aspectweaver.jar? Anyway, you probably have your reasons to use dynamic weaver attachment. In a way I am kind of happy that someone uses the functionality I added to AspectJ myself a while ago. ;-)

Question:

I updated my Eclipse target definition from Mars to Neon: http://download.eclipse.org/releases/mars http://download.eclipse.org/releases/neon

Now my launch is missing the org.eclipse.equinox.weaving.aspectj bundle. In Mars Equinox Target Components provided the bundle, but Neon does not. What feature do I have to choose to get it back? Maybe even another update site?

EDIT: Also the Mars Equinox Weaving SDK feature contained the bundle, but this feature is not available in the Neon update site.


Answer:

Eclipse bug 470000 seems to be the discussion of this. It seems like the AspectJ parts of the code have been moved to the Eclipse AJDT project and are no longer included in the Neon version of the Eclipse Weaving SDK.

The bug mentions some AJDT update sites.

Question:

I'm adding Spring Cache on an existing spring project using annotations. I'm using Couchbase as cache provider. I want to use load time weaving using AspectJ to allow private method calls and case class method calls to be cached as well.

It's been three days I'm stuck over this problem and I've read dozens of articles, documentations and examples but this thing just doesn't work.

This is what I've done -

@Configuration
@EnableSpringConfigured
@EnableAspectJAutoProxy
@EnableLoadTimeWeaving(aspectjWeaving = EnableLoadTimeWeaving.AspectJWeaving.ENABLED)
@EnableTransactionManagement
@EnableRetry
@PropertySource(
        value = {"classpath:application.properties", "classpath:${spring.profiles.active}.properties"},
        ignoreResourceNotFound = true)
public class BeanConfig implements LoadTimeWeavingConfigurer {

    ... various beans here ...

    @Override
    public LoadTimeWeaver getLoadTimeWeaver() {
        return new TomcatLoadTimeWeaver();// because I'm using Tomcat 7
    }

    @Bean
    public InstrumentationLoadTimeWeaver loadTimeWeaver()  throws Throwable {
        return new InstrumentationLoadTimeWeaver();
    }
}

@Configuration
@EnableSpringConfigured
@EnableCaching(mode = AdviceMode.ASPECTJ)
@ComponentScan(basePackages = "com.foo.bar.dao.cache.couchbase")
public class CacheConfigurer extends CachingConfigurerSupport {
    @Bean
    @Override
    public CacheManager cacheManager() {
        ... cachemanager configuration here ...
    }
}

Then I have @Chacheable on a DAO method on class, not on interface.

Finally, in my Tomcat 7's $CATALINA_HOME/conf/context.xml I have -

<Context>
    <Loader loaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader"/>    
</Context>

I have added following dependencies in pom.xml (its a maven project) -

  • couchbase-spring-cache
  • spring-aspects
  • aspectjweaver
  • aspectjrt
  • spring-instrument
  • spring-instrument-tomcat

If I do not use LTW caching works fine for methods calls arriving through interfaces (as it should). But after I enable LTW caching doesn't works at all - no caching for any method call, no errors either.

Has anyone tried using LTW for Spring cache with couchbase? What am I missing or doing wrong here?

I'm on Spring 4.3.5.Release.

Update -

Here is my bare-minimal code replicating the situation - https://github.com/harshilsharma63/spring-boilerplate-with-cache


Answer:

Forget classloader based load-time weaving, especially with Tomcat < 8.0. You'll have a lot of problems related to classloading order, with some classes being loaded before spring would install his weaving classloader, and you're gonna end-up with hard-to debug problems some of your classes not being weaved, etc. Instead, use a java agent.

Here's how to fix your config with Tomcat 7 by switching to java agent based weaving:

  1. Remove @EnableLoadTimeWeaving annotations.
  2. Remove <Loader loaderClass... from context.xml.
  3. Add -javaagent:/path/to/aspectjweaver.jar to your JVM startup arguments.

If you're willing to move to Tomcat 8, here are the steps needed:

  1. Move @EnableLoadTimeWeaving(aspectjWeaving=ENABLED) to a separate configuration class, let's name it WeavingConfig.
  2. Change your WebInitializer class so that for the getRootConfigClasses() you return only WeavingConfig.class.
  3. Move other required config classes to getServletConfigClasses().
  4. Remove unneded configurations like <Loader loaderClass... from context.xml, @EnableAspectJAutoProxy.
  5. Profit.

Of course, the best would still be to just use compile time weaving.

Question:

I want to use AspectJ Load-Time Weaving to be able to intercept static methods. I followed this example. When I execute the following test, the static method is well intercepted. However when I run directly the main class it is not intercepted.

According to this answer, I tested if the required agents are well loaded through isAspectJAgentLoaded(). Result: it's well loaded in both cases.

The configuration:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context
                           http://www.springframework.org/schema/context/spring-context.xsd">

    <context:load-time-weaver />

</beans>

The Aspect class:

@Aspect
public class PerformanceAdvice {

    @Before("execution(* org.springbyexample.aspectjLoadTimeWeaving.MyStaticClass.myStaticClass(..))")
    public void logBefore(JoinPoint joinPoint) {
        System.out.println("*** hijacked : " + joinPoint.getSignature().getName());
    }

}

The META-INF/aop.xml file:

<!DOCTYPE aspectj PUBLIC "-//AspectJ//DTD//EN" "http://www.eclipse.org/aspectj/dtd/aspectj.dtd">
<aspectj>
    <weaver>
        <include within="org.springbyexample.aspectjLoadTimeWeaving.*" />
    </weaver>
    <aspects>
        <aspect name="org.springbyexample.aspectjLoadTimeWeaving.PerformanceAdvice" />
    </aspects>
</aspectj>

The main class:

public class ProcessorRunner { 

    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("/application-context.xml", ProcessorRunner.class);
        if (isAspectJAgentLoaded()) System.out.println("*** AspectJ Agent Loaded ***");
        MyStaticClass.myStaticClass();
    }
    public static boolean isAspectJAgentLoaded() {
        try {
            org.aspectj.weaver.loadtime.Agent.getInstrumentation();
        } catch (NoClassDefFoundError | UnsupportedOperationException e) {
            return false;
        }
        return true;
    }
}

The test class:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"/application-context.xml"})
public class ProcessorTest { 

    @Test
    public void testProcessorFromContext() {
        if (isAspectJAgentLoaded()) {
            System.out.println("*** AspectJ required agents loaded ***");
        }
        ProcessorRunner.main(new String[]{"myArg"});
    }

    public static boolean isAspectJAgentLoaded() {
        try {
            org.aspectj.weaver.loadtime.Agent.getInstrumentation();
        } catch (NoClassDefFoundError | UnsupportedOperationException e) {
            System.out.println(e);
            return false;
        }
        return true;
    }
}

How come the wished method is well intercepted with the test class while it is not with the main class?


EDIT: I add the stack traces if it can help.

1) When it is ok by executing the test:

objc[73666]: Class JavaLaunchHelper is implemented in both /Library/Java/JavaVirtualMachines/jdk1.8.0_72.jdk/Contents/Home/bin/java and /Library/Java/JavaVirtualMachines/jdk1.8.0_72.jdk/Contents/Home/jre/lib/libinstrument.dylib. One of the two will be used. Which one is undefined.
00:06:25,484 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.groovy]
00:06:25,484 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Found resource [logback-test.xml] at [file:/Users/richard/dev/spring-by-example/core/aspectj-load-time-weaving/target/test-classes/logback-test.xml]
00:06:25,654 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - debug attribute not set
00:06:25,935 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.ConsoleAppender]
00:06:25,958 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [CONSOLE]
00:06:26,098 |-WARN in ch.qos.logback.core.ConsoleAppender[CONSOLE] - This appender no longer admits a layout as a sub-component, set an encoder instead.
00:06:26,098 |-WARN in ch.qos.logback.core.ConsoleAppender[CONSOLE] - To ensure compatibility, wrapping your layout in LayoutWrappingEncoder.
00:06:26,098 |-WARN in ch.qos.logback.core.ConsoleAppender[CONSOLE] - See also http://logback.qos.ch/codes.html#layoutInsteadOfEncoder for details
00:06:26,099 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting additivity of logger [org.springbyexample] to false
00:06:26,099 |-INFO in ch.qos.logback.classic.joran.action.LevelAction - org.springbyexample level set to DEBUG
00:06:26,100 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [CONSOLE] to Logger[org.springbyexample]
00:06:26,100 |-INFO in ch.qos.logback.classic.joran.action.LevelAction - ROOT level set to INFO
00:06:26,100 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [CONSOLE] to Logger[ROOT]
00:06:26,100 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - End of configuration.
00:06:26,102 |-INFO in ch.qos.logback.classic.joran.JoranConfigurator@1324409e - Registering current configuration as safe fallback point

avr. 24 2017 22:06:26 INFO  org.springframework.test.context.support.DefaultTestContextBootstrapper - Loaded default TestExecutionListener class names from location [META-INF/spring.factories]: [org.springframework.test.context.web.ServletTestExecutionListener, org.springframework.test.context.support.DependencyInjectionTestExecutionListener, org.springframework.test.context.support.DirtiesContextTestExecutionListener, org.springframework.test.context.transaction.TransactionalTestExecutionListener, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener]
avr. 24 2017 22:06:26 INFO  org.springframework.test.context.support.DefaultTestContextBootstrapper - Could not instantiate TestExecutionListener [org.springframework.test.context.web.ServletTestExecutionListener]. Specify custom listener classes or make the default listener classes (and their required dependencies) available. Offending class: [javax/servlet/ServletContext]
avr. 24 2017 22:06:26 INFO  org.springframework.test.context.support.DefaultTestContextBootstrapper - Could not instantiate TestExecutionListener [org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener]. Specify custom listener classes or make the default listener classes (and their required dependencies) available. Offending class: [org/springframework/transaction/interceptor/TransactionAttribute]
avr. 24 2017 22:06:26 INFO  org.springframework.test.context.support.DefaultTestContextBootstrapper - Could not instantiate TestExecutionListener [org.springframework.test.context.transaction.TransactionalTestExecutionListener]. Specify custom listener classes or make the default listener classes (and their required dependencies) available. Offending class: [org/springframework/transaction/interceptor/TransactionAttributeSource]
avr. 24 2017 22:06:26 INFO  org.springframework.test.context.support.DefaultTestContextBootstrapper - Using TestExecutionListeners: [org.springframework.test.context.support.DependencyInjectionTestExecutionListener@7d0587f1, org.springframework.test.context.support.DirtiesContextTestExecutionListener@5d76b067]avr. 24 2017 22:06:26 INFO  org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from class path resource [application-context.xml]
avr. 24 2017 22:06:27 INFO  org.springframework.context.support.GenericApplicationContext - Refreshing org.springframework.context.support.GenericApplicationContext@27808f31: startup date [Tue Apr 25 00:06:27 CEST 2017]; root of context hierarchy
avr. 24 2017 22:06:27 INFO  org.springframework.context.weaving.DefaultContextLoadTimeWeaver - Found Spring's JVM agent for instrumentation
java.lang.UnsupportedOperationException: Java 5 was not started with preMain -javaagent for AspectJ
avr. 24 2017 22:06:28 INFO  org.springframework.context.support.ClassPathXmlApplicationContext - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@59505b48: startup date [Tue Apr 25 00:06:28 CEST 2017]; root of context hierarchy
avr. 24 2017 22:06:28 INFO  org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from class path resource [application-context.xml]
avr. 24 2017 22:06:28 INFO  org.springframework.context.weaving.DefaultContextLoadTimeWeaver - Found Spring's JVM agent for instrumentation
[AppClassLoader@18b4aac2] error at org/springbyexample/aspectjLoadTimeWeaving/MyStaticClass.java::0 class {0} is already woven and has not been built in reweavable mode [Xlint:nonReweavableTypeEncountered]
[AppClassLoader@18b4aac2] error at org/springbyexample/aspectjLoadTimeWeaving/PerformanceAdvice.java::0 class {0} is already woven and has not been built in reweavable mode [Xlint:nonReweavableTypeEncountered]
*** hijacked : myStaticClass
ECHO myStaticClass()
avr. 24 2017 22:06:28 INFO  org.springframework.context.support.GenericApplicationContext - Closing org.springframework.context.support.GenericApplicationContext@27808f31: startup date [Tue Apr 25 00:06:27 CEST 2017]; root of context hierarchy
avr. 24 2017 22:06:28 INFO  org.springframework.context.weaving.DefaultContextLoadTimeWeaver - Removing all registered transformers for class loader: sun.misc.Launcher$AppClassLoader

Process finished with exit code 0

2) When I execute the main class:

objc[73710]: Class JavaLaunchHelper is implemented in both /Library/Java/JavaVirtualMachines/jdk1.8.0_72.jdk/Contents/Home/bin/java and /Library/Java/JavaVirtualMachines/jdk1.8.0_72.jdk/Contents/Home/jre/lib/libinstrument.dylib. One of the two will be used. Which one is undefined.
00:17:44.565 [main] INFO  o.s.c.s.ClassPathXmlApplicationContext - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@4563e9ab: startup date [Tue Apr 25 00:17:44 CEST 2017]; root of context hierarchy
00:17:44.656 [main] DEBUG o.s.core.env.StandardEnvironment - Adding [systemProperties] PropertySource with lowest search precedence
00:17:44.672 [main] DEBUG o.s.core.env.StandardEnvironment - Adding [systemEnvironment] PropertySource with lowest search precedence
00:17:44.672 [main] DEBUG o.s.core.env.StandardEnvironment - Initialized StandardEnvironment with PropertySources [systemProperties,systemEnvironment]
00:17:44.724 [main] DEBUG o.s.core.env.StandardEnvironment - Adding [systemProperties] PropertySource with lowest search precedence
00:17:44.724 [main] DEBUG o.s.core.env.StandardEnvironment - Adding [systemEnvironment] PropertySource with lowest search precedence
00:17:44.727 [main] DEBUG o.s.core.env.StandardEnvironment - Initialized StandardEnvironment with PropertySources [systemProperties,systemEnvironment]
00:17:44.735 [main] INFO  o.s.b.f.xml.XmlBeanDefinitionReader - Loading XML bean definitions from class path resource [application-context.xml]
00:17:44.763 [main] DEBUG o.s.b.f.xml.DefaultDocumentLoader - Using JAXP provider [com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl]
00:17:44.824 [main] DEBUG o.s.b.f.xml.PluggableSchemaResolver - Loading schema mappings from [META-INF/spring.schemas]
00:17:44.827 [main] DEBUG o.s.b.f.xml.PluggableSchemaResolver - Loaded schema mappings: {http://www.springframework.org/schema/jee/spring-jee-3.2.xsd=org/springframework/ejb/config/spring-jee-3.2.xsd, http://www.springframework.org/schema/util/spring-util.xsd=org/springframework/beans/factory/xml/spring-util-4.1.xsd, http://www.springframework.org/schema/beans/spring-beans-4.1.xsd=org/springframework/beans/factory/xml/spring-beans-4.1.xsd, http://www.springframework.org/schema/task/spring-task.xsd=org/springframework/scheduling/config/spring-task-4.1.xsd, http://www.springframework.org/schema/beans/spring-beans-3.1.xsd=org/springframework/beans/factory/xml/spring-beans-3.1.xsd, http://www.springframework.org/schema/cache/spring-cache.xsd=org/springframework/cache/config/spring-cache-4.1.xsd, http://www.springframework.org/schema/aop/spring-aop-3.0.xsd=org/springframework/aop/config/spring-aop-3.0.xsd, http://www.springframework.org/schema/task/spring-task-3.1.xsd=org/springframework/scheduling/config/spring-task-3.1.xsd, http://www.springframework.org/schema/aop/spring-aop-2.0.xsd=org/springframework/aop/config/spring-aop-2.0.xsd, http://www.springframework.org/schema/aop/spring-aop-4.0.xsd=org/springframework/aop/config/spring-aop-4.0.xsd, http://www.springframework.org/schema/task/spring-task-4.1.xsd=org/springframework/scheduling/config/spring-task-4.1.xsd, http://www.springframework.org/schema/tool/spring-tool-2.5.xsd=org/springframework/beans/factory/xml/spring-tool-2.5.xsd, http://www.springframework.org/schema/beans/spring-beans.xsd=org/springframework/beans/factory/xml/spring-beans-4.1.xsd, http://www.springframework.org/schema/jee/spring-jee-2.5.xsd=org/springframework/ejb/config/spring-jee-2.5.xsd, http://www.springframework.org/schema/tool/spring-tool-3.1.xsd=org/springframework/beans/factory/xml/spring-tool-3.1.xsd, http://www.springframework.org/schema/tool/spring-tool-4.1.xsd=org/springframework/beans/factory/xml/spring-tool-4.1.xsd, http://www.springframework.org/schema/jee/spring-jee-3.1.xsd=org/springframework/ejb/config/spring-jee-3.1.xsd, http://www.springframework.org/schema/aop/spring-aop.xsd=org/springframework/aop/config/spring-aop-4.1.xsd, http://www.springframework.org/schema/context/spring-context-3.2.xsd=org/springframework/context/config/spring-context-3.2.xsd, http://www.springframework.org/schema/jee/spring-jee-4.1.xsd=org/springframework/ejb/config/spring-jee-4.1.xsd, http://www.springframework.org/schema/beans/spring-beans-2.0.xsd=org/springframework/beans/factory/xml/spring-beans-2.0.xsd, http://www.springframework.org/schema/util/spring-util-3.2.xsd=org/springframework/beans/factory/xml/spring-util-3.2.xsd, http://www.springframework.org/schema/lang/spring-lang-3.2.xsd=org/springframework/scripting/config/spring-lang-3.2.xsd, http://www.springframework.org/schema/beans/spring-beans-4.0.xsd=org/springframework/beans/factory/xml/spring-beans-4.0.xsd, http://www.springframework.org/schema/beans/spring-beans-3.0.xsd=org/springframework/beans/factory/xml/spring-beans-3.0.xsd, http://www.springframework.org/schema/cache/spring-cache-3.2.xsd=org/springframework/cache/config/spring-cache-3.2.xsd, http://www.springframework.org/schema/task/spring-task-3.0.xsd=org/springframework/scheduling/config/spring-task-3.0.xsd, http://www.springframework.org/schema/task/spring-task-4.0.xsd=org/springframework/scheduling/config/spring-task-4.0.xsd, http://www.springframework.org/schema/context/spring-context-2.5.xsd=org/springframework/context/config/spring-context-2.5.xsd, http://www.springframework.org/schema/tool/spring-tool-3.0.xsd=org/springframework/beans/factory/xml/spring-tool-3.0.xsd, http://www.springframework.org/schema/lang/spring-lang.xsd=org/springframework/scripting/config/spring-lang-4.1.xsd, http://www.springframework.org/schema/tool/spring-tool-2.0.xsd=org/springframework/beans/factory/xml/spring-tool-2.0.xsd, http://www.springframework.org/schema/util/spring-util-2.5.xsd=org/springframework/beans/factory/xml/spring-util-2.5.xsd, http://www.springframework.org/schema/lang/spring-lang-2.5.xsd=org/springframework/scripting/config/spring-lang-2.5.xsd, http://www.springframework.org/schema/tool/spring-tool-4.0.xsd=org/springframework/beans/factory/xml/spring-tool-4.0.xsd, http://www.springframework.org/schema/aop/spring-aop-3.2.xsd=org/springframework/aop/config/spring-aop-3.2.xsd, http://www.springframework.org/schema/jee/spring-jee-3.0.xsd=org/springframework/ejb/config/spring-jee-3.0.xsd, http://www.springframework.org/schema/context/spring-context-4.1.xsd=org/springframework/context/config/spring-context-4.1.xsd, http://www.springframework.org/schema/jee/spring-jee-2.0.xsd=org/springframework/ejb/config/spring-jee-2.0.xsd, http://www.springframework.org/schema/context/spring-context-3.1.xsd=org/springframework/context/config/spring-context-3.1.xsd, http://www.springframework.org/schema/jee/spring-jee-4.0.xsd=org/springframework/ejb/config/spring-jee-4.0.xsd, http://www.springframework.org/schema/util/spring-util-3.1.xsd=org/springframework/beans/factory/xml/spring-util-3.1.xsd, http://www.springframework.org/schema/lang/spring-lang-3.1.xsd=org/springframework/scripting/config/spring-lang-3.1.xsd, http://www.springframework.org/schema/cache/spring-cache-4.1.xsd=org/springframework/cache/config/spring-cache-4.1.xsd, http://www.springframework.org/schema/util/spring-util-4.1.xsd=org/springframework/beans/factory/xml/spring-util-4.1.xsd, http://www.springframework.org/schema/cache/spring-cache-3.1.xsd=org/springframework/cache/config/spring-cache-3.1.xsd, http://www.springframework.org/schema/lang/spring-lang-4.1.xsd=org/springframework/scripting/config/spring-lang-4.1.xsd, http://www.springframework.org/schema/context/spring-context.xsd=org/springframework/context/config/spring-context-4.1.xsd, http://www.springframework.org/schema/jee/spring-jee.xsd=org/springframework/ejb/config/spring-jee-4.1.xsd, http://www.springframework.org/schema/aop/spring-aop-2.5.xsd=org/springframework/aop/config/spring-aop-2.5.xsd, http://www.springframework.org/schema/beans/spring-beans-3.2.xsd=org/springframework/beans/factory/xml/spring-beans-3.2.xsd, http://www.springframework.org/schema/aop/spring-aop-3.1.xsd=org/springframework/aop/config/spring-aop-3.1.xsd, http://www.springframework.org/schema/task/spring-task-3.2.xsd=org/springframework/scheduling/config/spring-task-3.2.xsd, http://www.springframework.org/schema/context/spring-context-4.0.xsd=org/springframework/context/config/spring-context-4.0.xsd, http://www.springframework.org/schema/aop/spring-aop-4.1.xsd=org/springframework/aop/config/spring-aop-4.1.xsd, http://www.springframework.org/schema/context/spring-context-3.0.xsd=org/springframework/context/config/spring-context-3.0.xsd, http://www.springframework.org/schema/tool/spring-tool.xsd=org/springframework/beans/factory/xml/spring-tool-4.1.xsd, http://www.springframework.org/schema/util/spring-util-3.0.xsd=org/springframework/beans/factory/xml/spring-util-3.0.xsd, http://www.springframework.org/schema/lang/spring-lang-3.0.xsd=org/springframework/scripting/config/spring-lang-3.0.xsd, http://www.springframework.org/schema/util/spring-util-2.0.xsd=org/springframework/beans/factory/xml/spring-util-2.0.xsd, http://www.springframework.org/schema/cache/spring-cache-4.0.xsd=org/springframework/cache/config/spring-cache-4.0.xsd, http://www.springframework.org/schema/lang/spring-lang-2.0.xsd=org/springframework/scripting/config/spring-lang-2.0.xsd, http://www.springframework.org/schema/util/spring-util-4.0.xsd=org/springframework/beans/factory/xml/spring-util-4.0.xsd, http://www.springframework.org/schema/lang/spring-lang-4.0.xsd=org/springframework/scripting/config/spring-lang-4.0.xsd, http://www.springframework.org/schema/tool/spring-tool-3.2.xsd=org/springframework/beans/factory/xml/spring-tool-3.2.xsd, http://www.springframework.org/schema/beans/spring-beans-2.5.xsd=org/springframework/beans/factory/xml/spring-beans-2.5.xsd}
00:17:44.828 [main] DEBUG o.s.b.f.xml.PluggableSchemaResolver - Found XML schema [http://www.springframework.org/schema/beans/spring-beans.xsd] in classpath: org/springframework/beans/factory/xml/spring-beans-4.1.xsd
00:17:44.882 [main] DEBUG o.s.b.f.xml.PluggableSchemaResolver - Found XML schema [http://www.springframework.org/schema/context/spring-context.xsd] in classpath: org/springframework/context/config/spring-context-4.1.xsd
00:17:44.910 [main] DEBUG o.s.b.f.xml.PluggableSchemaResolver - Found XML schema [http://www.springframework.org/schema/tool/spring-tool-4.1.xsd] in classpath: org/springframework/beans/factory/xml/spring-tool-4.1.xsd
00:17:44.925 [main] DEBUG o.s.b.f.x.DefaultBeanDefinitionDocumentReader - Loading bean definitions
00:17:44.936 [main] DEBUG o.s.b.f.x.DefaultNamespaceHandlerResolver - Loaded NamespaceHandler mappings: {http://www.springframework.org/schema/p=org.springframework.beans.factory.xml.SimplePropertyNamespaceHandler, http://www.springframework.org/schema/util=org.springframework.beans.factory.xml.UtilNamespaceHandler, http://www.springframework.org/schema/jee=org.springframework.ejb.config.JeeNamespaceHandler, http://www.springframework.org/schema/aop=org.springframework.aop.config.AopNamespaceHandler, http://www.springframework.org/schema/cache=org.springframework.cache.config.CacheNamespaceHandler, http://www.springframework.org/schema/c=org.springframework.beans.factory.xml.SimpleConstructorNamespaceHandler, http://www.springframework.org/schema/task=org.springframework.scheduling.config.TaskNamespaceHandler, http://www.springframework.org/schema/lang=org.springframework.scripting.config.LangNamespaceHandler, http://www.springframework.org/schema/context=org.springframework.context.config.ContextNamespaceHandler}
00:17:44.954 [main] DEBUG o.s.c.s.ClassPathXmlApplicationContext - Bean factory for org.springframework.context.support.ClassPathXmlApplicationContext@4563e9ab: org.springframework.beans.factory.support.DefaultListableBeanFactory@34cd072c: defining beans [loadTimeWeaver]; root of factory hierarchy
00:17:44.976 [main] DEBUG o.s.c.s.ClassPathXmlApplicationContext - Unable to locate MessageSource with name 'messageSource': using default [org.springframework.context.support.DelegatingMessageSource@8e24743]
00:17:44.978 [main] DEBUG o.s.c.s.ClassPathXmlApplicationContext - Unable to locate ApplicationEventMulticaster with name 'applicationEventMulticaster': using default [org.springframework.context.event.SimpleApplicationEventMulticaster@1fc2b765]
00:17:44.981 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@34cd072c: defining beans [loadTimeWeaver]; root of factory hierarchy
00:17:44.982 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Creating shared instance of singleton bean 'loadTimeWeaver'
00:17:44.982 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Creating instance of bean 'loadTimeWeaver'
00:17:44.995 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Eagerly caching bean 'loadTimeWeaver' to allow for resolving potential circular references
00:17:44.996 [main] INFO  o.s.c.w.DefaultContextLoadTimeWeaver - Found Spring's JVM agent for instrumentation
00:17:44.997 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Finished creating instance of bean 'loadTimeWeaver'
00:17:44.998 [main] DEBUG o.s.c.s.ClassPathXmlApplicationContext - Unable to locate LifecycleProcessor with name 'lifecycleProcessor': using default [org.springframework.context.support.DefaultLifecycleProcessor@587c290d]
00:17:44.999 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'lifecycleProcessor'
00:17:45.000 [main] DEBUG o.s.c.e.PropertySourcesPropertyResolver - Searching for key 'spring.liveBeansView.mbeanDomain' in [systemProperties]
00:17:45.000 [main] DEBUG o.s.c.e.PropertySourcesPropertyResolver - Searching for key 'spring.liveBeansView.mbeanDomain' in [systemEnvironment]
00:17:45.001 [main] DEBUG o.s.c.e.PropertySourcesPropertyResolver - Could not find key 'spring.liveBeansView.mbeanDomain' in any property source. Returning [null]
*** AspectJ Agent Loaded ***
ECHO myStaticClass()

Process finished with exit code 0

Answer:

In the aspectj-load-time-weaving example, the META-INF/aop.xml file is only present in the src/tests/resources folder. That's why the weaving works only when we execute the test.

To make it work also when we run directly the main method, we need to add META-INF/aop.xml in the src/java/resources folder.

Question:

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>

Answer:

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

    • aop.xml (and the META-INF folder),
    • AspectJ Maven plugin,
    • dependencies on AspectJ runtime and weaver,
    • Maven Surefire LTW configuration (remove the whole plugin).
  • Spring AOP works nicely with your multi-module setup.

  • As I said, please just fix your pointcut to match sub-packages:
@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.

Question:

Is it possible to configure AspectJ LTW solely in Java? I don't want to deal with XML, and I was wondering if I can do without it. I searched through AspectJ website, and I found only the XML way.

I am planning to use it with Spring, hopefully without any strange consequences(had enough problems already:)).

Thanks!


Answer:

You can set up Spring to use AspectJ via LTW mostly using Spring annotations. But you do need META-INF/aop.xml because this is an AspectJ LTW requirement, it does not come from Spring. AspectJ is an independent technology which does not need Spring, Spring only supports it being used in its own context.

If you don't like XML for whatever reason - done right there is no problem and you only need to touch the file once - use CTW (compile-time weaving), e.g. via AspectJ Maven Plugin.

Question:

@Configurable(preConstruction = false)
public class Mock implements IMock
{

    @Autowired
    private Foo foo;


    public Mock()
    {
        System.out.println("i need foo in the constructor but it is not autowired at this point " + foo);
    }

    @PostConstruct
    public void start()
    {
        System.out.println("starting");
    }
}

When I set up Spring Aspectj load time weaving and created a instance through new keyword like this(below). It turns out that I have no access to the dependencies in the constructor. That's all fine as expected. The execution order was constructor->autowire->postconstruct .

public class Main
{

    public static void main(String[] args)
    {
        URL url = Main.class.getResource("applicationContext.xml");
        FileSystemXmlApplicationContext ctx = new FileSystemXmlApplicationContext(url.getPath());

        Mock mock = new Mock();
    }
}

So I set @Configurable(preConstruction = true). Now I can access the dependencies in the constructor. But the problem is the execution order: autowire->postconstruct->construct . Why postconstruct comes before construct? That's not what I expected.

Did I misunderstand something? What is the semantics of @PostConstruct? Is it "post constructor" or "post dependency injection"? I checked out the javadoc of @PostConstruct. It says nothing about constructor.

EDIT: btw, here are the libraries versions I use:

spring-aspects 4.1.6.RELEASE

spring-instrument 4.1.6.RELEASE


Answer:

@PostConstruct is handled in Spring by the CommonAnnotationBeanPostProcessor and is run together with all bean configuration post-processors that are configured for the given bean factory and applicable to the bean in question (in the order they are configured to run). The @Configurable annotation just marks otherwise not Spring managed beans to be eligible for autowiring and bean post-processing by Spring, and it's done through AnnotationBeanConfigurerAspect. preConstruction=true will signal that this configuration should happen before the constructor of the object in question is run. That means that if preConstruction=true, by the time the constructor of the object in question is being run, Spring will have finished its configuration of the object.

TL;DR - yes, this is the intended order things should happen in your case.

Question:

I am using AspectJ for logging when tests execution only, so I use load time weaving. I pack Interceptor to a jar file to use with another Maven project. But with below config, aspectjweaver will weave methods of external libraries. I want it only weave my source code (include test) without specific config like <include within="hello.*"/>, for generic using like dependency.

Sorry, my English is quite bad. Thanks so much !!!

In aop.xml of this jar file, it likes

<aspectj>
<aspects>
    <aspect name="log.Interceptor"/>
    <weaver options="-verbose -showWeaveInfo">
        <include within="*"/>
    </weaver>
</aspects>
</aspectj>

// Interceptor

pointcut traceMethods() : (execution(* *(..)) && !cflow(within(Interceptor)) && !within(*Test) && !within(Test*) && !within(*Tests) && !within(*TestCase));
before(): traceMethods(){
    Method method = ((MethodSignature) thisJoinPointStaticPart.getSignature()).getMethod();
    logDebug(method, LogPattern.METHOD_START);
}
after(): traceMethods(){
    Method method = ((MethodSignature) thisJoinPointStaticPart.getSignature()).getMethod();
    logDebug(method, LogPattern.METHOD_FINISH);
}` 

Answer:

Well, you cannot eat the cake and keep it at the same time. So either your solution is generic with pointcuts targeting the whole world or it is specific via includes and/or excludes.

  • What you could try is to use an additional META-INF/aop.xml locally when building or deploying projects using you generic library and specify in-/excludes there. As far as I remember AspectJ will find all those files on the classpath and merge the settings found there.

  • Alternatively, you can define an abstract pointcut and tell your users to make it concrete in an aop.xml file in their project.

Both suggested solutions should work, but they require your library's users to have a basic understanding of AspectJ or at least pointcut syntax. Either you do that and document your library accordingly with sample pointcuts or whole sample AOP config files or you have to be more specific in your own pointcuts and/or in-/excludes. There is no magic solution, the AspectJ weaver cannot guess what you want to weave and what not.

Question:

Currently I am using AspectJ Load Time Weaving to intercept the constructor of a base entity for auditing purposes. However when running the application I am getting incredibly inconsistent results revolving around the aspectOf() method that aspectJ weaves into LTW classes.

In some cases the application runs, the weaving is done correctly, and the code is functioning as expected. Other times I am met with:

java.lang.NoSuchMethodException: ca.gc.cfp.core.cfpws.repository.aspect.BaseEntityAspect.aspectOf() 

Currently I am using https://github.com/subes/invesdwin-instrument to dynamically attach the instrumentation agent into the JVM so our deployment guys don't need to do any extra configuration.

My Spring application main:

@SpringBootApplication
@EntityScan(basePackages = {"ca.gc.cfp.model"})
public class CfpWsApplication {

  public static void main(final String[] args) {

    DynamicInstrumentationLoader.waitForInitialized();
    DynamicInstrumentationLoader.initLoadTimeWeavingContext();

    if (!InstrumentationLoadTimeWeaver.isInstrumentationAvailable()) {
      throw new IllegalStateException(
          "Instrumentation is not available AspectJ weaver will not function.");
    }

    SpringApplication.run(CfpWsApplication.class, args);
  }

The LTW Aspect:

@Aspect
public class BaseEntityAspect {
  Logger logger = LoggerFactory.getLogger(BaseEntityAspect.class);

  /** Application context property needed to fetch the AuditDate bean */
  @Autowired private ApplicationContext context;

  @AfterReturning(
      "onBaseEntityCreated() && !within(ca.gc.cfp.core.cfpws.repository.aspect.BaseEntityAspect)")
  public void injectAuditTimeStamp(JoinPoint joinPoint) {
    try {
      AuditDate auditDate = context.getBean(AuditDate.class);
      Object entityTarget = joinPoint.getTarget();

      // Inject the auditing date for this Entity instance
      if (entityTarget instanceof BaseEntity) {
        BaseEntity baseEnt = (BaseEntity) entityTarget;
        baseEnt.setAuditDate(auditDate.getAuditingTimeStamp());
      }
    } catch (NullPointerException e) {
      logger.error(
          e.getMessage()
              + " Not yet in the conext of an httpRequest, the AuditDate bean has not yet been instantiated.");
    }
  }

  @Pointcut(
      "execution(ca.gc.cfp.model.entity.BaseEntity.new(..)) && !within(ca.gc.cfp.core.cfpws.repository.aspect.BaseEntityAspect)")
  public void onBaseEntityCreated() {}
}

The Aspect config class with a temporary factory method using the Aspects utils to let spring know it should ask aspectJ for the woven Aspect:

@Configuration
@EnableAspectJAutoProxy
public class AspectConfig {

  /**
   * Static factory for access to the load time woven aspect. This allows the aspect to be injected
   * with the application context and beans from the spring IoC
   */
  @Bean
  public BaseEntityAspect getBaseEntityAspect() {
    return Aspects.aspectOf(BaseEntityAspect.class);
  }
}

aop.xml:

<aspectj>
    <weaver options="-verbose -showWeaveInfo -Xreweavable -debug">
        <include within="ca.gc.cfp.model" />
        <include within="ca.gc.cfp.model..*" /> 
        <include within="ca.gc.cfp.core.cfpws.repository.aspect..*"/>
    </weaver>
    <aspects>
        <aspect name="ca.gc.cfp.core.cfpws.repository.aspect.BaseEntityAspect" />
    </aspects>
</aspectj>

In a lot of cases when I run with this configuration I get the following:

Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [ca.gc.cfp.core.cfpws.repository.aspect.BaseEntityAspect]: Factory method 'getBaseEntityAspect' threw exception; nested exception is org.aspectj.lang.NoAspectBoundException: Exception while initializing ca.gc.cfp.core.cfpws.repository.aspect.BaseEntityAspect: java.lang.NoSuchMethodException: ca.gc.cfp.core.cfpws.repository.aspect.BaseEntityAspect.aspectOf()
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185) ~[spring-beans-5.1.4.RELEASE.jar:5.1.4.RELEASE]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:622) ~[spring-beans-5.1.4.RELEASE.jar:5.1.4.RELEASE]
    ... 19 common frames omitted
Caused by: org.aspectj.lang.NoAspectBoundException: Exception while initializing ca.gc.cfp.core.cfpws.repository.aspect.BaseEntityAspect: java.lang.NoSuchMethodException: ca.gc.cfp.core.cfpws.repository.aspect.BaseEntityAspect.aspectOf()
    at org.aspectj.lang.Aspects.aspectOf(Aspects.java:50) ~[aspectjrt-1.9.4.jar:1.9.4]
    at ca.gc.cfp.core.cfpws.configuration.AspectConfig.getBaseEntityAspect(AspectConfig.java:22) ~[classes/:na]
    at ca.gc.cfp.core.cfpws.configuration.AspectConfig$$EnhancerBySpringCGLIB$$1cae4c58.CGLIB$getBaseEntityAspect$0(<generated>) ~[classes/:na]
    at ca.gc.cfp.core.cfpws.configuration.AspectConfig$$EnhancerBySpringCGLIB$$1cae4c58$$FastClassBySpringCGLIB$$84edb9e.invoke(<generated>) ~[classes/:na]
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244) ~[spring-core-5.1.4.RELEASE.jar:5.1.4.RELEASE]
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:363) ~[spring-context-5.1.4.RELEASE.jar:5.1.4.RELEASE]
    at ca.gc.cfp.core.cfpws.configuration.AspectConfig$$EnhancerBySpringCGLIB$$1cae4c58.getBaseEntityAspect(<generated>) ~[classes/:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_211]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_211]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_211]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_211]
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154) ~[spring-beans-5.1.4.RELEASE.jar:5.1.4.RELEASE]
    ... 20 common frames omitted
Caused by: java.lang.NoSuchMethodException: ca.gc.cfp.core.cfpws.repository.aspect.BaseEntityAspect.aspectOf()
    at java.lang.Class.getDeclaredMethod(Class.java:2130) ~[na:1.8.0_211]
    at org.aspectj.lang.Aspects.getSingletonOrThreadAspectOf(Aspects.java:134) ~[aspectjrt-1.9.4.jar:1.9.4]
    at org.aspectj.lang.Aspects.aspectOf(Aspects.java:45) ~[aspectjrt-1.9.4.jar:1.9.4]
    ... 31 common frames omitted

However this is not always the case, occasionally the application runs just fine, the code executes as expected and there are no issues. This has been eluding me for a couple weeks now and I cannot seem to figure out what could be causing this code to occasionally work and occasionally not work. Could it be that CGLIB proxies are hiding the aspectOf() method from the compiler??

EDIT / UPDATE: I was able to remove the use of the above third party dependency for dynamically loading the java agent into the Spring application context. I instead used javaagent arguments and it is working fine from within my IDE. However building and running via Maven in a terminal is still causing issues. I've specified the javaagent argument via the Environment variable : MAVEN_OPTS. After doing so maven seems to be picking it up but my class still isn't being woven.


Answer:

With regard to your own answer: The AspectJ Maven plugin helps you with compile-time weaving (CTW), not load-time weaving (LTW). For LTW you need to make sure that the weaving agent is active before any of the target classes have been loaded because LTW works at class-loader level. AspectJ Maven is only necessary if either you use aspects in native syntax (not annotation-based) or you want to use CTW.

I don't know about this invesdwin-instrument tool, but the AspectJ weaver offers its own capability to attach it during runtime. A third-party tool should not be necessary. Anyway, I do recommend to modify the Java command line in order to ensure the weaving agent is in place before anything else is loaded in your container. Your deployment guys ought to help you make sure that the -javaagent:... parameter is there. It is their job! To work around that in order to make life easier for them but the behaviour of your application potentially unpredictable is not going to improve its stability.

Question:

I have trying to test load time weaving in simple hello world normal Servlet based example in wildfly8.2

I have below Aspect code

package com.test.aspects;

import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

import com.test.helloworld.HelloService;

@Aspect
public abstract class FieldAspect {

    @Pointcut
    public abstract void getField();

    @Pointcut
    public abstract void setField();

    @Around("getField()")
    public HelloService getFieldValue() {
        System.out.println("In FieldAspect.getFieldValue() - Applying around advice - getting the value (Andy) for field annotated variable");
        return new HelloService();
    }

    @Around("setField()")
    public void setFieldValue() {
        System.out
                .println("In FieldAspect.setFieldValue() - Applying around advice - throw RuntimeException if field annotated variable is set");
        throw new RuntimeException();
    }
}

The below run time field annotation

package com.test.aspects;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Field {

}

Test Servlet:

package com.test.helloworld;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.test.aspects.Field;

@SuppressWarnings("serial")
@WebServlet("/HelloWorld")
public class HelloWorldServlet extends HttpServlet {

    static String PAGE_HEADER = "<html><head><title>helloworld</title></head><body>";

    static String PAGE_FOOTER = "</body></html>";

   @Field
   public  HelloService helloService;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html");
        PrintWriter writer = resp.getWriter();
        writer.println(PAGE_HEADER);
        writer.println("<h1>" + helloService.createHelloMessage("World") + "</h1>");
        writer.println(PAGE_FOOTER);
        writer.close();
    }

}

Service class:

package com.test.helloworld;

public class HelloService {

    String createHelloMessage(String name) {
        return "Hello " + name + "!";
    }

}

Aop.xml under web-inf:

<?xml version="1.0" encoding="UTF-8"?>
<aspectj>
    <aspects>

        <!-- Field annotation example -->
        <concrete-aspect name="com.test.aspects.MyFieldAspect"
            extends="com.test.aspects.FieldAspect">
            <pointcut name="getField" expression="get(@com.test.aspects.Field * *)" />
            <pointcut name="setField" expression="set(@com.test.aspects.Field * *)" />
        </concrete-aspect>


    </aspects>

    <weaver options="-verbose -showWeaveInfo" />
</aspectj>

And the POM.xml:

<?xml version="1.0"?>
<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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.wildfly.quickstarts</groupId>
    <artifactId>wildfly-helloworld</artifactId>
    <version>8.0.0-SNAPSHOT</version>
    <packaging>war</packaging>
    <name>WildFly : Helloworld</name>
    <description>WildFly : Helloworld</description>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>


        <version.wildfly.maven.plugin>1.0.2.Final</version.wildfly.maven.plugin>

        <version.jboss.spec.javaee.7.0>1.0.0.Final</version.jboss.spec.javaee.7.0>


        <!-- other plugin versions -->
        <version.compiler.plugin>3.1</version.compiler.plugin>
        <version.war.plugin>2.1.1</version.war.plugin>

        <!-- maven-compiler-plugin -->
        <maven.compiler.target>1.7</maven.compiler.target>
        <maven.compiler.source>1.7</maven.compiler.source>
    </properties>

    <dependencyManagement>
        <dependencies>
            <!-- Define the version of JBoss' Java EE 7 APIs we want to use -->
            <!-- JBoss distributes a complete set of Java EE 7 APIs including
                a Bill of Materials (BOM). A BOM specifies the versions of a "stack" (or
                a collection) of artifacts. We use this here so that we always get the correct
                versions of artifacts. Here we use the jboss-javaee-7.0 stack (you can
                read this as the JBoss stack of the Java EE 7 APIs). You can actually
                use this stack with any version of WildFly that implements Java EE 7, not
                just WildFly 8! -->
            <dependency>
                <groupId>org.jboss.spec</groupId>
                <artifactId>jboss-javaee-7.0</artifactId>
                <version>1.0.2</version>
                <type>pom</type>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.8.2</version>
        </dependency>

        <!-- Import the CDI API, we use provided scope as the API is included in JBoss WildFly -->
        <dependency>
            <groupId>javax.enterprise</groupId>
            <artifactId>cdi-api</artifactId>
            <version>1.2</version>            
        </dependency>

        <!-- Import the Common Annotations API (JSR-250), we use provided scope 
            as the API is included in JBoss WildFly -->
        <dependency>
            <groupId>org.jboss.spec.javax.annotation</groupId>
            <artifactId>jboss-annotations-api_1.2_spec</artifactId>
            <version>1.0.0.Final</version>
        </dependency>

        <!-- Import the Servlet API, we use provided scope as the API is included in JBoss WildFly -->
        <dependency>
            <groupId>org.jboss.spec.javax.servlet</groupId>
            <artifactId>jboss-servlet-api_3.1_spec</artifactId>
            <version>1.0.0.Final</version>
        </dependency>

    </dependencies>

    <build>
        <!-- Set the name of the war, used as the context root when the app 
            is deployed -->
        <finalName>wildfly-helloworld</finalName>
        <pluginManagement>
            <plugins>
                <!--This plugin's configuration is used to store Eclipse m2e settings 
                    only. It has no influence on the Maven build itself. -->
                <plugin>
                    <groupId>org.eclipse.m2e</groupId>
                    <artifactId>lifecycle-mapping</artifactId>
                    <version>1.0.0</version>
                    <configuration>
                        <lifecycleMappingMetadata>
                            <pluginExecutions>
                                <pluginExecution>
                                    <pluginExecutionFilter>
                                        <groupId>
                                            org.apache.maven.plugins
                                        </groupId>
                                        <artifactId>
                                            maven-compiler-plugin
                                        </artifactId>
                                        <versionRange>
                                            [2.5.1,)
                                        </versionRange>
                                        <goals>
                                            <goal>compile</goal>
                                        </goals>
                                    </pluginExecutionFilter>
                                    <action>
                                        <ignore></ignore>
                                    </action>
                                </pluginExecution>
                                <pluginExecution>
                                    <pluginExecutionFilter>
                                        <groupId>
                                            org.codehaus.mojo
                                        </groupId>
                                        <artifactId>
                                            aspectj-maven-plugin
                                        </artifactId>
                                        <versionRange>
                                            [1.7,)
                                        </versionRange>
                                        <goals>
                                            <goal>compile</goal>
                                            <goal>test-compile</goal>
                                        </goals>
                                    </pluginExecutionFilter>
                                    <action>
                                        <ignore></ignore>
                                    </action>
                                </pluginExecution>
                            </pluginExecutions>
                        </lifecycleMappingMetadata>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>

        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>aspectj-maven-plugin</artifactId>
                <configuration>
                    <complianceLevel>1.6</complianceLevel>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.6</version>
                <configuration>
                    <!-- Java EE 7 doesn't require web.xml, Maven needs to catch up! -->
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>
            <!-- WildFly plugin to deploy war -->
            <plugin>
                <groupId>org.wildfly.plugins</groupId>
                <artifactId>wildfly-maven-plugin</artifactId>
                <version>1.0.2.Final</version>
                <configuration>
                    <version>1.0.2.Final</version>
                    <jvmArgs>${the-whole-jvm-args}</jvmArgs>
                </configuration>
            </plugin>
            <!-- Compiler plugin enforces Java 1.6 compatibility and activates 
                annotation processors -->
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

Used below link to configure the Load time weaving: http://wiki.eclipse.org/LTWJboss7

So after above if I start wildfly, it shows below error stack trace.

[AppClassLoader@1912a56] info AspectJ Weaver Version 1.8.5 built on Thursday Jan 29, 2015 at 01:03:58 GMT
[AppClassLoader@1912a56] info register classloader sun.misc.Launcher$AppClassLoader@1912a56
[AppClassLoader@1912a56] info using configuration file:/helloworld/target/wildfly-helloworld.war!/WEB-INF/aop.xml
[AppClassLoader@1912a56] info define aspect com.test.aspects.MyFieldAspect
[AppClassLoader@1912a56] error Cannot find parent aspect for: <concrete-aspect name='com.test.aspects.MyFieldAspect' extends='com.test.aspects.FieldAspect' perclause='null'/> in aop.xml
[AppClassLoader@1912a56] error Concrete-aspect 'com.test.aspects.MyFieldAspect' could not be registered
[AppClassLoader@1912a56] warning failure(s) registering aspects. Disabling weaver for class loader sun.misc.Launcher$AppClassLoader@1912a56

I am confused here what has been done wrong. Can someone help me to run my test program. I am learning AspectJ and LTW with wildfly and new to this all. Thanks,


Answer:

classpath was wrong. Place the aspectjWeaver jar in WEB-INF/lib folder. Also package aop module as create Aspects inside war module , create aspects in different module and package in jar.