Community
Participate
Working Groups
Created attachment 247455 [details] A Maven project showing the ClassCastException when running tests. Hi, When compiling a simple project [1] using aspectj-maven-plugin, I get the error below. It only happens when the pointcut gets applied. If I make the pointcut intercept nothing [2], it compiles successfully. [ERROR] Failed to execute goal org.codehaus.mojo:aspectj-maven-plugin:1.7:compile (default) on project lambda-control-flow-poc: AJC compiler errors: [ERROR] error at (no source information available) [ERROR] /home/chous/github/LambdaControlFlowPoC/src/main/java/org/acmsl/pocs/lambdafor/ControlFlowDriver.java:0::0 Internal compiler error: java.lang.ClassCastException: org.aspectj.apache.bcel.classfile.ConstantUtf8 cannot be cast to org.aspectj.apache.bcel.classfile.ConstantInvokeDynamic at org.aspectj.apache.bcel.generic.InvokeDynamic.getSignature(InvokeDynamic.java:108) [ERROR] abort ABORT -- (ClassCastException) org.aspectj.apache.bcel.classfile.ConstantUtf8 cannot be cast to org.aspectj.apache.bcel.classfile.ConstantInvokeDynamic [ERROR] org.aspectj.apache.bcel.classfile.ConstantUtf8 cannot be cast to org.aspectj.apache.bcel.classfile.ConstantInvokeDynamic [ERROR] java.lang.ClassCastException: org.aspectj.apache.bcel.classfile.ConstantUtf8 cannot be cast to org.aspectj.apache.bcel.classfile.ConstantInvokeDynamic [ERROR] at org.aspectj.apache.bcel.generic.InvokeDynamic.getSignature(InvokeDynamic.java:108) [ERROR] at org.aspectj.apache.bcel.generic.InvokeDynamic.getReturnType(InvokeDynamic.java:99) [ERROR] at org.aspectj.apache.bcel.generic.InvokeInstruction.produceStack(InvokeInstruction.java:107) [ERROR] at org.aspectj.apache.bcel.generic.MethodGen.getMaxStack(MethodGen.java:988) [ERROR] at org.aspectj.apache.bcel.generic.MethodGen.setMaxStack(MethodGen.java:876) [ERROR] at org.aspectj.weaver.bcel.LazyMethodGen.pack(LazyMethodGen.java:1019) The context is: - Project uses lambda expressions. - Java 1.8.11 on gentoo linux 64b. - aspectjrt, aspectjtools 1.8.2 - aspectj-maven-plugin 1.7 [1] https://github.com/rydnr/LambdaControlFlowPoC [2] https://github.com/rydnr/LambdaControlFlowPoC/blob/master/src/main/aspect/org/acmsl/pocs/lambdafor/ForReplacer.aj I'm attaching the Maven project with a (hopefully) resolvable pom should it helps to figure out the issue. Just run mvn test. I've downloaded aspectj 1.8.2 sources, and when debugging, the invalid cast is produced by extracting "org/acmsl/pocs/lambdafor/ControlFlowCommand" String from the constant pool at index 62. I've no idea what could be causing this. I've tried adding some defensive programming hacks but it causes one NPE in the caller for each guarding condition. I think InvokeDynamic class is not prepared yet to handle ConstantUtf8 instances, but I'm far from solving this by myself. Thank you very much in advance. Jose.
Thanks for the test project, very useful. I think I've distilled it to this: === import java.util.*; public class Code { public void m() { } } aspect X { void around(): execution(* m(..)) { Arrays.asList(4, 5, 6).forEach((i) -> { System.out.println(i);}); } } === and it relates to the inlining of around advice (the constant pool isn't copied across properly for some reason). If you turn off inlining, that may change what you see (-XnoInline on the command... not sure in maven)
Inlining around advice that contains invokedynamic is non trivial. Unlike the other instructions there is more to 'copy over' to the target including the bootstrap methods and the method in the aspect that represents the lambda expression. It is not clear to me the lambda meta factory in the JDK will behave itself when the lambda expression method is copied over like this (I'm thinking about lambdas that capture 'this' for example). The quick solution is to mark advice that contains invokedynamic as not suitable for inlining.
I've committed my proposed changes. At least it shouldn't fail now but it will not be as optimal as inlining around advice. I will leave this bug open to cover doing the right thing when I have more time to craft a ton of tests.
With -XnoInline (<XnoInline>true</XnoInline> in Maven's pom.xml) works. Thanks Andy.
marking as fixed.