I'm using AspectJ 1.8.8 compile-time weaving and I have a block like this
@SomeAnnotation(value="someValue")
public List doSomething(String someArg) {
...
}
where @SomeAnnotation
is implemented with an "Around" advice.
Looking at the bytecode with JD-GUI, I see the following generated code (slightly formatted):
public class SomeClass {
private static Annotation ajc$anno$5;
...
@SomeAnnotation(value="someValue")
public List doSomething(String someArg)
{
String str = someArg;
JoinPoint localJoinPoint = Factory.makeJP(ajc$tjp_5, this, this, str);
Object[] arrayOfObject = new Object[3];
arrayOfObject[0] = this;
arrayOfObject[1] = str;
arrayOfObject[2] = localJoinPoint;
Annotation tmp56_53 = ajc$anno$5;
if (tmp56_53 == null) {
tmp56_53;
}
return (List)new SomeClass.AjcClosure11(arrayOfObject).linkClosureAndJoinPoint(69648).around(tmp56_53, (SomeAnnotation)(ajc$anno$5 = SomeClass.class.getDeclaredMethod("doSomething", new Class[] { String.class }).getAnnotation(SomeAnnotation.class)));
}
}
I was wondering why that condition (if (tmp56_53...)
) even exists as it appears to be doing nothing (And is also syntactically incorrect Java? Maybe because this was generated by ajc?). I'm curious about this because it's causing "branch misses" in a coverage tool (JaCoCo).
Edit 1
Here is the raw Java machine code from javap:
0: aload_1
1: astore_2
2: getstatic #480 // Field ajc$tjp_10:Lorg/aspectj/lang/JoinPoint$StaticPart;
5: aload_0
6: aload_0
7: aload_2
8: invokestatic #312 // Method org/aspectj/runtime/reflect/Factory.makeJP:(Lorg/aspectj/lang/JoinPoint$StaticPart;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Lorg/aspectj/lang/JoinPoint;
11: astore_3
12: invokestatic #339 // Method com/foo/SomeAspect.aspectOf:()Lcom/foo/SomeAspect;
15: iconst_3
16: anewarray #2 // class java/lang/Object
19: astore 4
21: aload 4
23: iconst_0
24: aload_0
25: aastore
26: aload 4
28: iconst_1
29: aload_2
30: aastore
31: aload 4
33: iconst_2
34: aload_3
35: aastore
36: new #484 // class com/foo/SomeClass$AjcClosure21
39: dup
40: aload 4
42: invokespecial #485 // Method com/foo/SomeClass$AjcClosure21."<init>":([Ljava/lang/Object;)V
45: ldc_w #327 // int 69648
48: invokevirtual #333 // Method org/aspectj/runtime/internal/AroundClosure.linkClosureAndJoinPoint:(I)Lorg/aspectj/lang/ProceedingJoinPoint;
51: getstatic #488 // Field ajc$anno$10:Ljava/lang/annotation/Annotation;
54: dup
55: ifnonnull 86
58: pop
59: ldc #75 // class com/foo/SomeClass
61: ldc_w #489 // String someArg
64: iconst_1
65: anewarray #348 // class java/lang/Class
68: dup
69: iconst_0
70: ldc #171 // class java/lang/String
72: aastore
73: invokevirtual #352 // Method java/lang/Class.getDeclaredMethod:(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;
76: ldc_w #341 // class com/foo/SomeAnnotation
79: invokevirtual #358 // Method java/lang/reflect/Method.getAnnotation:(Ljava/lang/Class;)Ljava/lang/annotation/Annotation;
82: dup
83: putstatic #488 // Field ajc$anno$10:Ljava/lang/annotation/Annotation;
86: nop
87: checkcast #341 // class com/foo/SomeAnnotation
90: invokevirtual #362 // Method com/foo/SomeAspect.around:(Lorg/aspectj/lang/ProceedingJoinPoint;Lcom/foo/SomeAnnotation;)Ljava/lang/Object;
93: pop
94: return
Looks like ifnonnull
could be conditional in question, but I am not familiar at all with JVM instructions, and I still don't know why AspectJ would generate logic like this.