我有一个非常简单的AspectJ方面(使用@AspectJ)刚刚打印出的日志信息。我的目标是劝告code在我的Android应用程序。现在这方面的工作完全正常,只要我有纵横类本身在我的应用程序源码 - code。 有一次,我将纵横成不同的模块(无论是爪哇 - >的.jar或Android LIB - > .aar)我得到以下运行时异常运行谏code在我的应用程序时:
I have a very simple AspectJ aspect (using @AspectJ) which just prints out a log message. My goal is to advice code in my android application. Now this aspects works perfectly fine as long as I have the aspect class itself in my applications source-code. Once I move the aspect into a different module (either java -> .jar or android lib -> .aar) I get the following runtime exception when running the adviced code in my application:
java.lang.NoSuchMethodError: com.xxx.xxx.TraceAspect.aspectOf
基本上我的结构是这样的:
Basically my structure is like this:
Root
+ app (com.android.application)
- MainActivity (with annotation to be adviced)
+ library (android-library)
- TraceAspect (aspect definition)
从AJC编译器,我可以看到,AJC编译拿起我的课,正确通知:他们,所以我真的不知道为什么它的工作原理,只要我有@AspectJ类在我的源$ C $ C ,但停止工作,一旦我将它移动到一个JAR档案。
From the ajc compiler, I can see that the ajc compiler picks up my classes and advices them correctly, so I really don't know why it works as long as I have the @AspectJ class in my sourcecode, but stops working once I move it to a jar archive.
我使用的摇篮。 Buildscript我的应用程序是非常简单的。我也跟着在http://fernandocejas.com/2014/08/03/aspect-oriented-programming-in-android/
I am using gradle. Buildscript for my app is super simple. I followed the instructions in http://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;
}
}
}
}
不知道是否很重要,但为了以防万一,我的方面,code:
Not sure if important, but just in case, the code of my aspect:
@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();
}
}
类路径
我还检查 javaCompile.classPath
,它正确地包含了库classes.jar
和我的 APP-classes.jar
。添加 -log文件
到 AJC
任务也表明,文件被正确地编织。
I also checked the javaCompile.classPath
and it correctly contains both the library-classes.jar
and my app-classes.jar
. Adding -log file
to the ajc
tasks also shows that files are correctly weaved.
任何想法?
小例子来重现此问题
https://github.com/fschoellhammer/test-aspectj
我有一个摇篮AspectJ的插件发挥各地并把它应用到的注释的子项目是这样的:
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
现在的应用作品,在仿真器和DDMS从Android SDK显示,建议输出在控制台上的预期。 : - )
Now the app works in the emulator and DDMS from the Android SDK shows that the advice output is on the console as expected. :-)
请注意,我这个项目升级到1.8.4的AspectJ和Java 7,我也改变了这些设置:
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'
}
}