Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


Ejecutar AspectJ causa NoSuchMethodError: Aspect.aspectOf

Tengo un aspecto muy simple de AspectJ (usando @AspectJ) que apenas imprime hacia fuera un mensaje del registro. Mi objetivo es el código de consejos en mi aplicación Android. Ahora, este aspecto funciona perfectamente, siempre y cuando tenga la clase de aspecto en mis aplicaciones código fuente. Una vez que muevo el aspecto en un módulo diferente (ya sea java -> .jar o android lib -> .aar) Tengo la siguiente excepción de tiempo de ejecución al ejecutar el código adviced en mi aplicación:

java.lang.NoSuchMethodError: com.xxx.xxx.TraceAspect.aspectOf 

Básicamente mi estructura es así:

  • ¿Cómo puedo verificar que la imagen URI es válida en Android?
  • ¿Por qué los nombres de las variables a menudo comienzan con la letra "m"?
  • Utilizar FragmentStatePagerAdapter sin biblioteca de soporte
  • Mostrar el teclado virtual cuando se inicia la actividad
  • Android View PerformClick () y callOnClick () diferencia
  • NotificationCompat.setStyle () no puede obtener Notification.MediaStyle
  •  Root + app (com.android.application) - MainActivity (with annotation to be adviced) + library (android-library) - TraceAspect (aspect definition) 

    Desde el compilador ajc, puedo ver que el compilador ajc recoge mis clases y los advierte correctamente, así que realmente no sé por qué funciona, siempre y cuando tenga la clase @AspectJ en mi código fuente, pero deja de funcionar una vez que me muevo A un archivo jar.

    Estoy usando gradle. Buildscript para mi aplicación es muy simple. Seguí las instrucciones en 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; } } } } 

    No estoy seguro si es importante, pero por si acaso, el código de mi aspecto:

     @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(); } } 

    Camino de clase

    También he comprobado javaCompile.classPath y contiene correctamente tanto la library-classes.jar como mi app-classes.jar . La adición de -log file a las tareas de ajc también muestra que los archivos se tejen correctamente.

    ¿Algunas ideas?

    Ejemplo mínimo para reproducir este problema

    Https://github.com/fschoellhammer/test-aspectj

  • Cómo crear diseño con 6 botones como ventanas de azulejos
  • Android: anima el topMargin / bottomMargin / etc de una vista en LinearLayout o RelativeLayout
  • Android: Deshabilitar el teclado virtual en todos los EditTexts
  • No se puede generar clave en el almacén de claves de Android
  • No se puede emitir a una clase extendida en Java
  • Android: Centrar una imagen
  • 3 Solutions collect form web for “Ejecutar AspectJ causa NoSuchMethodError: Aspect.aspectOf”

    Jugué con un plugin Gradle AspectJ y lo apliqué al subproyecto de anotación como este:

     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 

    Ahora la aplicación funciona en el emulador y DDMS del SDK de Android muestra que la salida de asesoramiento está en la consola como se esperaba. :-)

    Debug Monitor consola de registro

    Tenga en cuenta que he actualizado el proyecto a AspectJ 1.8.4 y Java 7. También he cambiado esta configuración:

     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' } } 

    El mensaje implica que el archivo de aspecto no ha pasado por el aspectj tejedor. El tejedor sería responsable de agregar el método aspectOf() . Aunque sus aspectos de estilo de anotación se compilarán bien con javac , deben ser "terminados" por aspectj en algún momento para introducir los métodos de infraestructura que soportan el tejido. Si usted fue el tiempo de carga de tejer esto se hace como los aspectos se cargan, pero si se compila tiempo o post-compilar el tiempo de tejer, entonces usted necesita para obtener a ajc alguna otra manera. Si tiene una biblioteca construida de esta manera:

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

    Entonces usted necesitaría conseguir ese frasco tejido para "completar" los aspectos:

     ajc -inpath code.jar -outjar myfinishedcode.jar 

    O simplemente puede usar ajc lugar de javac para el paso inicial

     ajc MyAspect.java 

    O usted podría hacerlo en el punto que los aspectos se están aplicando a su otro código:

     ajc <myAppSourceFiles> -inpath myaspects.jar 

    Al incluir myaspects.jar en la vía de inpath , cualquier clase de aspecto en la que se habrá "terminado" como parte de este paso de compilación y las versiones terminadas puestas junto a los archivos de origen de la aplicación compilada. Tenga en cuenta que esto es diferente si usó la ruta de aspecto:

     ajc <myAppSourceFiles> -aspectpath myaspects.jar 

    Aquí los aspectos de la ruta de aspecto se aplican a su código, pero sólo se cargan desde allí, no se terminan y por lo que no obtendrá las versiones terminadas junto con los archivos de origen de la aplicación compilada.

    Me encuentro con el mismo problema, pero he utilizado Maven en lugar de Gradle.

    Antes de que se pueda aplicar una clase de aspecto a una clase de destino, primero hay que "tejerla" en un aspecto. Una clase de aspecto tejida tendrá dos métodos estáticos agregados (aspectOf y hasAspect).

    En mi caso particular no tejí mis aspectos.

    Se puede hacer agregando el aspectoj-maven-plugin a la sección de compilación.

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

    ¡Espero eso ayude!

    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.