Running AspectJ verursacht NoSuchMethodError: Aspect.aspectOf
Ich habe einen sehr einfachen Aspekt von AspectJ (mit @AspectJ), der nur eine Protokollmeldung ausgibt. Mein Ziel ist es, Code in meiner Android-Anwendung zu beraten. Jetzt funktioniert dieser Aspekt einwandfrei, solange ich die Aspektklasse selbst in meinem Anwendungs-Quellcode habe.Einmal, wenn ich den Aspekt in ein anderes Modul verschiebe (entweder Java -> .jar oder Android Lib -> .aar), erhalte ich die folgende Laufzeitausnahme beim Ausführen des empfohlenen Codes in meiner Anwendung:
java.lang.NoSuchMethodError: com.xxx.xxx.TraceAspect.aspectOf
rundsätzlich ist meine Struktur wie folgt:
Root
+ app (com.android.application)
- MainActivity (with annotation to be adviced)
+ library (android-library)
- TraceAspect (aspect definition)
Aus dem ajc-Compiler kann ich ersehen, dass der ajc-Compiler meine Klassen aufnimmt und sie korrekt empfiehlt. Daher weiß ich nicht, warum das so lange funktioniert, wie ich die Klasse @AspectJ in meinem Quellcode habe, aber nicht mehr funktioniert, sobald ich es getan habe verschiebe es in ein jar Archiv.
Ich benutze gradle. Buildscript für meine App ist super einfach. Ich habe die Anweisungen in @ befolhttp: //fernandocejas.com/2014/08/03/aspect-oriented-programming-in-android
import com.android.build.gradle.LibraryPlugin
import org.aspectj.bridge.IMessage
import org.aspectj.bridge.MessageHandler
import org.aspectj.tools.ajc.Main
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.12.+'
classpath 'org.aspectj:aspectjtools:1.8.1'
}
}
apply plugin: 'com.android.application'
repositories {
mavenCentral()
}
dependencies {
compile 'org.aspectj:aspectjrt:1.8.1'
compile project (':library')
}
android.applicationVariants.all { variant ->
AppPlugin plugin = project.plugins.getPlugin(AppPlugin)
JavaCompile javaCompile = variant.javaCompile
javaCompile.doLast {
String[] args = ["-showWeaveInfo",
"-1.5",
"-XnoInline",
"-inpath", javaCompile.destinationDir.toString(),
"-aspectpath", javaCompile.classpath.asPath,
"-d", javaCompile.destinationDir.toString(),
"-classpath", javaCompile.classpath.asPath,
"-bootclasspath", plugin.project.android.bootClasspath.join(File.pathSeparator)]
MessageHandler handler = new MessageHandler(true);
new Main().run(args, handler)
def log = project.logger
for (IMessage message : handler.getMessages(null, true)) {
switch (message.getKind()) {
case IMessage.ABORT:
case IMessage.ERROR:
case IMessage.FAIL:
log.error message.message, message.thrown
break;
case IMessage.WARNING:
log.warn message.message, message.thrown
break;
case IMessage.INFO:
log.info message.message, message.thrown
break;
case IMessage.DEBUG:
log.debug message.message, message.thrown
break;
}
}
}
}
Nicht sicher, ob es wichtig ist, aber nur für den Fall, den Code meines Aspekts:
@Aspect
public class TraceAspect {
private static final String POINTCUT_METHOD = "execution(@com.xxx.TraceAspect * *(..))";
@Pointcut(POINTCUT_METHOD)
public void annotatedMethod() {}
@Around("annotatedMethod()")
public Object weaveJoinPoint(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("Aspect works...");
return joinPoint.proceed();
}
}
Klassenpfad
Ich habe auch das @ überprüjavaCompile.classPath
und es enthält korrekterweise sowohl daslibrary-classes.jar
und meinapp-classes.jar
. @ Hinzufüg-log file
zumajc
tasks zeigt auch an, dass die Dateien korrekt gewebt sind.
Irgendwelche Ideen
Minimales Beispiel, um dieses Problem zu reproduzieren