gradle-plugins icon indicating copy to clipboard operation
gradle-plugins copied to clipboard

Post-compile weaving fails when Kotlin class extends Java type

Open halfninja opened this issue 5 years ago • 3 comments

In a mixed-source project, when a Kotlin class declares on a Java type in a particular way (mainly as a supertype), the post-compile weaver can't resolve the Java type to check it for relevance.

Demo - https://github.com/halfninja/aspectj-mixed-weaving

$ ./gradlew compileJava
> Task :compileKotlin FAILED
w: /home/nick/code/mixed-weaving/src/main/java/main.kt: (3, 10): Parameter 'args' is never used
<Unknown> [warning] Found @DeclareAnnotation while current release does not support it (see 'org.aspectj.weaver.bcel.AtAjAttributes')

/home/nick/code/mixed-weaving/build/classes/kotlin/main/MainKt.class [error] can't determine implemented interfaces of missing type Nice
when processing declare parents ContentImpl
when processing type mungers
when weaving
when batch building BuildConfig[null] #Files=0 AopXmls=#0
 [Xlint:cantFindType]
(no source information available)
        [Xlint:cantFindType]

1 error, 1 warning

FAILURE: Build failed with an exception.

If Nice.java is converted into Nice.kt then it works, but this isn't always practical in our codebase. I've tried various ways of coaxing the inpath to make this happy, but it either doesn't work or breaks incremental builds in confusing ways. Can this ever work with the actions all being separate in each compile task, or would it need to run once in a separate task against all the compiled output across all types of source?

halfninja avatar Jan 20 '21 20:01 halfninja

I was thinking about refactoring into something that ran once per SourceSet, as a separate task after all AbstractCompile tasks had run and pulling all their combined classpath and class output. What do you think, does that sound vaguely sensible?

halfninja avatar Jan 23 '21 07:01 halfninja

Thanks for the demo project.

It seems like the kotlin compiler is is reading Nice.java in order to compile the .kt files, but is not actually compiling it to Nice.class. Thats why ajc can't resolve it. (In the current setup ajc would expect Nice.class either on the classpath of the kotlin compiler or in its output directory)

larsgrefer avatar Jan 29 '21 00:01 larsgrefer

Yep I think that's how the Kotlin compiler handles mixed source. I tried adding src/main/java as a sourceroot to the AspectJ action, but then it also tries (and fails) to compile that Java source as well, and isn't post-compile weaving in any case. I don't think there's a way to tell aspectj to look at some sources just to get type information.

We've ended up biting the refactoring bullet and just converting enough Java to Kotlin to make it know about the types it needs, eventually converting everything to Kotlin.

halfninja avatar Feb 01 '21 16:02 halfninja