Running AspectJ causes NoSuchMethodError: Aspect.aspectOf

I run into the same problem but I used Maven instead of Gradle.

Before an aspect class can be applied to a target class it first needs to be 'weaved' into an aspect. A weaved aspect class will have two static methods added (aspectOf and hasAspect).

In my particular case I didn't weave my aspects.

It can be done by adding aspectj-maven-plugin to the build section.

<build>
<plugins>
  <plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>aspectj-maven-plugin</artifactId>
    <executions>
      <execution>
        <goals>
          <goal>compile</goal> 
        </goals>
      </execution>
    </executions>
  </plugin>
</plugins>

Hope it helps!


The message implies that the aspect file has not gone through the aspectj weaver. The weaver would be responsible for adding the aspectOf() method. Although your annotation style aspects will compile fine with javac, they must be 'finished off' by aspectj at some point to introduce the infrastructure methods that support weaving. If you were load-time weaving this is done as the aspects are loaded but if you are compile time or post-compile time weaving then you need to get them to ajc some other way. If you have a library built like this:

javac MyAspect.java
jar -cvMf code.jar MyAspect.class

then you'd need to get that jar woven to 'complete' the aspects:

ajc -inpath code.jar -outjar myfinishedcode.jar

Or you could just use ajc instead of javac for the initial step

ajc MyAspect.java

Or you could do it at the point the aspects are being applied to your other code:

ajc <myAppSourceFiles> -inpath myaspects.jar 

By including myaspects.jar on the inpath, any aspect classes in there will be 'finished off' as part of this compile step and the finished versions put alongside your compiled application source files. Note this is different to if you used the aspect path:

ajc <myAppSourceFiles> -aspectpath myaspects.jar

Here the aspects on the aspect path are applied to your code but they are only loaded from there, they are not finished off and so you wouldn't get the finished versions alongside your compiled application source files.


I played around with a Gradle AspectJ plugin and applied it to the annotation subproject like this:

buildscript {
    repositories {
        maven {
            url "https://maven.eveoh.nl/content/repositories/releases"
        }
    }

    dependencies {
        classpath "nl.eveoh:gradle-aspectj:1.4"
    }
}

project.ext {
    aspectjVersion = '1.8.4'
}

apply plugin: 'aspectj'

project.convention.plugins.java.sourceCompatibility = org.gradle.api.JavaVersion.VERSION_1_7
project.convention.plugins.java.targetCompatibility = org.gradle.api.JavaVersion.VERSION_1_7

Now the app works in the emulator and DDMS from the Android SDK shows that the advice output is on the console as expected. :-)

Debug Monitor console log

Please note that I have upgraded the project to AspectJ 1.8.4 and Java 7. I have also changed these settings:

Index: app/build.gradle
===================================================================
--- app/build.gradle    (revision 9d9c3ce4e0f903b5e7c650f231577c20585e6923)
+++ app/build.gradle    (revision )
@@ -2,8 +2,7 @@

 dependencies {
     // aspectJ compiler
-    compile 'org.aspectj:aspectjrt:1.8.1'
-
+    compile 'org.aspectj:aspectjrt:1.8.4'
     compile (project (':annotation'))
 }

@@ -50,13 +49,13 @@
     JavaCompile javaCompile = variant.javaCompile
     javaCompile.doLast {
         String[] args = ["-showWeaveInfo",
-                         "-1.5",
+                         "-1.7",
                          "-XnoInline",
                          "-inpath", javaCompile.destinationDir.toString(),
                          "-aspectpath", javaCompile.classpath.asPath,
                          "-d", javaCompile.destinationDir.toString(),
                          "-classpath", javaCompile.classpath.asPath,
-                         //"-log", "/home/flo/workspace/test-aspectj/weave.log",
+                         "-log", "weave.log",
                          "-bootclasspath", plugin.project.android.bootClasspath.join(File.pathSeparator)]

         MessageHandler handler = new MessageHandler(true);
Index: build.gradle
===================================================================
--- build.gradle    (revision 9d9c3ce4e0f903b5e7c650f231577c20585e6923)
+++ build.gradle    (revision )
@@ -5,7 +5,7 @@
     dependencies {
         classpath 'com.android.tools.build:gradle:0.12.+'
         // aspectj - http://fernandocejas.com/2014/08/03/aspect-oriented-programming-in-android/
-        classpath 'org.aspectj:aspectjtools:1.8.1'
+        classpath 'org.aspectj:aspectjtools:1.8.4'
     }
 }