Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] I can not get the correct line number

The reason this occurs is because after() returning advice is implemented by forwarding all ‘return’ byte codes through to the end of a method where some generated code is created to call the advice, then the actual return occurs:

         0: getstatic     #24                 // Field instance:LSample;
         3: ifnull        14
         6: getstatic     #24                 // Field instance:LSample;
         9: dup
        10: astore_0
        11: goto          29 // would have been an ARETURN if no after returning advice
        14: new           #1                  // class Sample
        17: dup
        18: invokespecial #26                 // Method "<init>":()V
        21: putstatic     #24                 // Field instance:LSample;
        24: getstatic     #24                 // Field instance:LSample;
        27: dup
        28: astore_0
        29: dup
        30: astore_1
        31: invokestatic  #35                 // Method X.aspectOf:()LX;
        34: aload_1
        35: invokevirtual #39                 // Method X.ajc$afterReturning$X$1$8f645123:(Ljava/lang/Object;)V
        38: aload_0
        39: areturn

Here you can see at 11, there is a goto 29 which goes to the ‘advice invocation logic’ where without the aspect it would have been an areturn (see instruction 9 here - same code with no aspects):

         0: getstatic     #24                 // Field instance:LSample;
         3: ifnull        10
         6: getstatic     #24                 // Field instance:LSample;
         9: areturn // Here is the areturn that gets rewritten to GOTO when advice applies.
        10: new           #1                  // class Sample
        13: dup
        14: invokespecial #26                 // Method "<init>":()V
        17: putstatic     #24                 // Field instance:LSample;
        20: getstatic     #24                 // Field instance:LSample;
        23: areturn

Because the advice is inserted at the end of the method you end up getting the line number of the last return, and can never get the others.

Could after advice be implemented differently? Yes, it could be inlined/duplicated at each return location. That would give you what you want at the cost of increased byte code size - there isn’t currently an option to switch to that weaving behavior I’m afraid.


cheers,
Andy


> On Jun 6, 2018, at 8:25 AM, Hirokawa Yuya <yu_ya45@xxxxxxxxxxx> wrote:
> 
> Hello
> 
> I am using @ AnfterReturning annotation.
> We create a function to keep line numbers as logs.
> 
> When there are multiple returns in the method,
> The line number always points to the last return.
> Is it impossible to get a line number other than the last return?
> 
> environment:
> org.aspectj:aspectjrt:1.9.1
> Android Studio 3.1.2
> Build #AI-173.4720617, built on April 14, 2018
> JRE: 1.8.0_152-release-1024-b02 amd64
> JVM: OpenJDK 64-Bit Server VM by JetBrains s.r.o
> Windows 10 10.0
> 
> app/gradle
> import org.aspectj.bridge.IMessage
> import org.aspectj.bridge.MessageHandler
> import org.aspectj.tools.ajc.Main
> 
> buildscript {
>    repositories {
>        jcenter()
>        mavenCentral()
>    }
> 
>    dependencies {
>        classpath 'org.aspectj:aspectjtools:1.9.1'
>    }
> }
> apply plugin: 'com.android.application'
> 
> android {
>    compileSdkVersion 27
>    defaultConfig {
>        applicationId "jp.co.hba.milesmimi"
>        minSdkVersion 23
>        targetSdkVersion 27
>        versionCode 1
>        versionName "1.0"
>        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
>    }
>    buildTypes {
>        release {
>            minifyEnabled false
>            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
>        }
>    }
> 
>    applicationVariants.all { variant ->
> 
>        variant.javaCompiler.doLast {
>            String[] args = ["-showWeaveInfo",
>                             "-1.9",
>                             "-inpath", javaCompile.destinationDir.toString(),
>                             "-aspectpath", javaCompile.classpath.asPath,
>                             "-d", javaCompile.destinationDir.toString(),
>                             "-classpath", javaCompile.classpath.asPath,
>                             "-bootclasspath", 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:
>                    case IMessage.INFO:
>                        log.info message.message, message.thrown
>                        break
>                    case IMessage.DEBUG:
>                        log.debug message.message, message.thrown
>                        break
>                }
>            }
>        }
>    }
> 
>    packagingOptions {
>        exclude 'META-INF/DEPENDENCIES'
>        exclude 'META-INF/LICENSE'
>        exclude 'META-INF/LICENSE.txt'
>        exclude 'META-INF/license.txt'
>        exclude 'META-INF/NOTICE'
>        exclude 'META-INF/NOTICE.txt'
>        exclude 'META-INF/notice.txt'
>        exclude 'META-INF/ASL2.0'
>        exclude 'META-INF/INDEX.LIST'
>    }
> 
>    compileOptions {
>        sourceCompatibility JavaVersion.VERSION_1_8
>        targetCompatibility JavaVersion.VERSION_1_8
>    }
> }
> 
> dependencies {
>    implementation fileTree(dir: 'libs', include: ['*.jar'])
>    implementation 'com.android.support:support-v4:27.1.1'
>    implementation 'com.android.support:appcompat-v7:27.1.1'
>    implementation 'com.android.support.constraint:constraint-layout:1.1.0'
>    implementation 'com.journeyapps:zxing-android-embedded:3.6.0'
>    implementation 'com.fasterxml.jackson.core:jackson-databind:2.9.5'
>    implementation 'org.apache.httpcomponents:httpclient:4.5.5'
>    implementation 'com.squareup.retrofit2:retrofit:2.4.0'
>    implementation 'com.squareup.retrofit2:converter-jackson:2.4.0'
>    implementation 'io.reactivex.rxjava2:rxandroid:2.0.2'
>    implementation 'io.reactivex.rxjava2:rxjava:2.1.14'
>    implementation 'com.google.dagger:dagger:2.16'
>    annotationProcessor 'com.google.dagger:dagger-android-processor:2.16'
>    annotationProcessor 'com.google.dagger:dagger-compiler:2.16'
>    implementation 'com.jakewharton:butterknife:8.8.1'
>    implementation 'org.aspectj:aspectjrt:1.9.1'
>    testImplementation 'junit:junit:4.12'
>    androidTestImplementation 'com.android.support.test:runner:1.0.2'
>    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
> }
> 
> MyLog.java(Excerpt)
> package milesmimi.util;
> 
> import ...
> 
> @Aspect
> public class MyLog {
> 	@Pointcut("execution(* *(..)) && !within(milesmimi.util.MyLog) && if()")
> 	public static boolean isRun() {
> 		StackTraceElement[] stackTrace = new Exception().getStackTrace();
> 		return stackTrace.length >= 3;
> 	}
> 
> 	@AfterReturning(value = "isRun()", returning = "returnValue")
> 	public void end(Object returnValue) {
> 		StackTraceElement ste = (new Throwable()).getStackTrace()[1];
> 		System.out.println("LineNumber=" + ste.getLineNumber());
> 	}
> }
> 
> Sample.java
> public class Sample {
> 	private static Sample instance;
> 	public static Sample getInstance() {
> 		if (instance != null) {
> 			return instance;	// <- I can not get the line number when I end here
> 		} else {
> 			instance = new Sample();
> 			return instance;	
> 		}
> 	}
> }
> 
> Thank you.
> yuuya
> _______________________________________________
> aspectj-users mailing list
> aspectj-users@xxxxxxxxxxx
> To change your delivery options, retrieve your password, or unsubscribe from this list, visit
> https://dev.eclipse.org/mailman/listinfo/aspectj-users



Back to the top