javamockitogradle-pluginaspectcompile-time-weaving

AspectJ cannot find .raw superclass


Background

A project uses Aspects for logging. The particulars:

The build.gradle file resembles:

apply plugin: "io.freefair.aspectj.post-compile-weaving"

dependencies {
    compileOnly group: 'javax.servlet', name: 'javax.servlet-api', version: '4.0.1'
    compileOnly group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.12.1'
    compileOnly group: 'org.osgi', name: 'org.osgi.framework', version: '1.9.0'
    compileOnly group: 'org.mockito', name: 'mockito-core', version: '2.25.1'

    inpath project(":company.project.main")
}

Problem

When the application is compiled, AspectJ cannot find MockMethodDispatcher, and reports an error:

.../mockito-core-2.25.1.jar [error] can't determine superclass of missing type org.mockito.internal.creation.bytebuddy.inject.MockMethodDispatcher
when weaving type org.mockito.internal.creation.bytebuddy.MockMethodAdvice
when weaving classes 
when weaving 
when batch building BuildConfig[null] #Files=0 AopXmls=#0
 [Xlint:cantFindType]
(no source information available)
        [Xlint:cantFindType]
.../org.mockito/mockito-core/2.25.1/e8fa2864b65c0b6fbb20daa436a94853bcd17e5e/mockito-core-2.25.1.jar [warning] can't find type org.mockito.internal.creation.bytebuddy.inject.MockMethodDispatcher whilst determining signatures of call or execution join point for java.util.concurrent.Callable org.mockito.internal.creation.bytebuddy.MockMethodAdvice.handle(java.lang.Object, java.lang.reflect.Method, java.lang.Object[]), this may cause a pointcut to fail to match at this join point 
when weaving type org.mockito.internal.creation.bytebuddy.MockMethodAdvice
when weaving classes 
when weaving 
when batch building BuildConfig[null] #Files=0 AopXmls=#0
 [Xlint:cantFindTypeAffectingJPMatch]

I suspect this is because the file is stored as a .raw file rather than a .class file (as per issue 845):

1778 Mon Jul 08 13:47:02 PDT 2019 org/mockito/internal/creation/bytebuddy/inject/MockMethodDispatcher.raw

Question

How would you update the Gradle file to instruct the post-compile-weaving plugin to ignore weaving (or scanning) Mockito classes altogether?

Notes

From the command-line, weaving appears to work:

java -cp aspectjtools-1.9.4.jar:aspectjrt-1.9.4.jar org.aspectj.tools.ajc.Main \
-inpath application.jar \
-aspectpath ../aspects/build/classes/java/main \
-Xlint:warning \
-verbose \
-showWeaveInfo \
-log aop.log \
-outjar woven.jar

Though the output classes in woven.jar should be injected into application.jar.

Addendum

Note:

Related

Attempts

When calling compileJava as follows:

compileJava {
    ajc {
        enabled = true
        classpath = configurations.aspectj
        options {
            aspectpath = configurations.aspect
            compilerArgs = [""]
        }
    }
}

Gradle reports the following error:

Cannot set the value of read-only property 'classpath' for object of type io.freefair.gradle.plugins.aspectj.AjcAction.

Using:

compileJava {
  ajc {
    options {
      compilerArgs = [""]
    }
  }
}

Gradle reports:

Could not find method options() for arguments [...] on object of type io.freefair.gradle.plugins.aspectj.AjcAction.

The source code on master seems to expose different names for its "configurable things":

task.getInputs().property("ajcArgs", this.getOptions().getCompilerArgs())

Solution

  • The declared dependency is transitive:

    inpath project(":company.project.main")
    

    This will pass the complete runtime classpath of :company.project.main (the classes produced by said project and all its dependencies) into the -inpath of ajc. (See the build/tmp/compileJava/ajc.options file to confirm.)

    To avoid weaving advices into external classes, declare a non-transitive dependency as follows:

    inpath(project(":company.project.main")) { 
        transitive = false
    }
    

    Depending on your exact requirements and your project structure, it might be a better approach to apply the io.freefair.aspectj.post-compile-weaving plugin directly to the :company.project.main project.