arturdm / jacoco-android-gradle-plugin

Gradle plugin that creates JaCoCo test reports for Android unit tests
Apache License 2.0
562 stars 111 forks source link

Build failing on Gradle 8.0 #102

Open kevalpatel2106 opened 1 year ago

kevalpatel2106 commented 1 year ago

When trying to build the project with gradle 8.0, and plugin version 0.1.5, gradle throws following exception:

Caused by: org.codehaus.groovy.runtime.metaclass.MissingMethodExecutionFailed: No signature of method: org.gradle.api.reporting.internal.TaskGeneratedSingleFileReport.enabled() is applicable for argument types: (Boolean) values: [false]
Caused by: org.gradle.internal.metaobject.AbstractDynamicObject$CustomMessageMissingMethodException: Could not find method enabled() for arguments [false] on Report csv of type org.gradle.api.reporting.internal.TaskGeneratedSingleFileReport.
    at org.gradle.internal.metaobject.AbstractDynamicObject$CustomMissingMethodExecutionFailed.<init>(AbstractDynamicObject.java:190)
    at org.gradle.internal.metaobject.AbstractDynamicObject.methodMissingException(AbstractDynamicObject.java:184)
    at org.gradle.internal.metaobject.AbstractDynamicObject.invokeMethod(AbstractDynamicObject.java:167)
    at org.gradle.api.reporting.internal.TaskGeneratedSingleFileReport_Decorated.invokeMethod(Unknown Source)
    at com.dicedmelon.gradle.jacoco.android.JacocoAndroidPlugin$_createReportTask_closure2.doCall(JacocoAndroidPlugin.groovy:88)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at org.gradle.util.internal.ClosureBackedAction.execute(ClosureBackedAction.java:73)
    at org.gradle.util.internal.ConfigureUtil.configureTarget(ConfigureUtil.java:155)
    at org.gradle.util.internal.ConfigureUtil.configureSelf(ConfigureUtil.java:131)
    at org.gradle.api.reporting.internal.DefaultReportContainer.configure(DefaultReportContainer.java:61)
    at org.gradle.api.reporting.internal.DefaultReportContainer.configure(DefaultReportContainer.java:35)
    at org.gradle.util.internal.ClosureBackedAction.execute(ClosureBackedAction.java:65)
    at org.gradle.testing.jacoco.tasks.JacocoReport.reports(JacocoReport.java:77)
    at org.gradle.testing.jacoco.tasks.JacocoReport.reports(JacocoReport.java:72)
    at org.gradle.testing.jacoco.tasks.JacocoReport.reports(JacocoReport.java:35)
    at org.gradle.api.reporting.Reporting$reports.call(Unknown Source)
    at com.dicedmelon.gradle.jacoco.android.JacocoAndroidPlugin.createReportTask(JacocoAndroidPlugin.groovy:85)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at com.dicedmelon.gradle.jacoco.android.JacocoAndroidPlugin$_apply_closure1.doCall(JacocoAndroidPlugin.groovy:32)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at org.gradle.util.internal.ClosureBackedAction.execute(ClosureBackedAction.java:73)
    at org.gradle.util.internal.ConfigureUtil.configureTarget(ConfigureUtil.java:155)
    at org.gradle.util.internal.ConfigureUtil.configure(ConfigureUtil.java:106)
    at org.gradle.util.internal.ConfigureUtil$WrappedConfigureAction.execute(ConfigureUtil.java:167)
    at org.gradle.configuration.internal.DefaultUserCodeApplicationContext$CurrentApplication$1.execute(DefaultUserCodeApplicationContext.java:123)
    at org.gradle.api.internal.DefaultCollectionCallbackActionDecorator$BuildOperationEmittingAction$1.run(DefaultCollectionCallbackActionDecorator.java:110)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:29)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:26)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.run(DefaultBuildOperationRunner.java:47)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:68)
    at org.gradle.api.internal.DefaultCollectionCallbackActionDecorator$BuildOperationEmittingAction.execute(DefaultCollectionCallbackActionDecorator.java:107)
    at org.gradle.internal.ImmutableActionSet$SetWithManyActions.execute(ImmutableActionSet.java:329)
    at org.gradle.api.internal.DefaultDomainObjectCollection.doAdd(DefaultDomainObjectCollection.java:262)
    at org.gradle.api.internal.DefaultDomainObjectCollection.add(DefaultDomainObjectCollection.java:251)
    at com.android.build.gradle.AbstractAppExtension.addVariant(AbstractAppExtension.kt:64)
    at com.android.build.gradle.internal.ApiObjectFactory.create(ApiObjectFactory.java:119)
    at com.android.build.gradle.internal.plugins.BasePlugin.createAndroidTasks(BasePlugin.kt:726)
    at com.android.build.gradle.internal.plugins.BasePlugin$createTasks$2$1.call(BasePlugin.kt:580)
    at com.android.build.gradle.internal.profile.NoOpAnalyticsConfiguratorService.recordBlock(NoOpAnalyticsConfiguratorService.kt:53)
    at com.android.build.gradle.internal.plugins.BasePlugin$createTasks$2.accept(BasePlugin.kt:575)
    at com.android.build.gradle.internal.plugins.BasePlugin$createTasks$2.accept(BasePlugin.kt:572)
    at com.android.build.gradle.internal.crash.CrashReporting$afterEvaluate$1.execute(crash_reporting.kt:37)
    at com.android.build.gradle.internal.crash.CrashReporting$afterEvaluate$1.execute(crash_reporting.kt:35)
    at org.gradle.configuration.internal.DefaultUserCodeApplicationContext$CurrentApplication$1.execute(DefaultUserCodeApplicationContext.java:123)
    at org.gradle.configuration.internal.DefaultListenerBuildOperationDecorator$BuildOperationEmittingAction$1.run(DefaultListenerBuildOperationDecorator.java:171)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:29)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:26)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.run(DefaultBuildOperationRunner.java:47)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:68)
    at org.gradle.configuration.internal.DefaultListenerBuildOperationDecorator$BuildOperationEmittingAction.execute(DefaultListenerBuildOperationDecorator.java:168)
    at org.gradle.internal.event.BroadcastDispatch$ActionInvocationHandler.dispatch(BroadcastDispatch.java:97)
    at org.gradle.internal.event.BroadcastDispatch$ActionInvocationHandler.dispatch(BroadcastDispatch.java:85)
    at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:43)
    at org.gradle.internal.event.BroadcastDispatch$SingletonDispatch.dispatch(BroadcastDispatch.java:257)
    at org.gradle.internal.event.BroadcastDispatch$SingletonDispatch.dispatch(BroadcastDispatch.java:164)
    at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:83)
    at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:69)
    at org.gradle.internal.event.BroadcastDispatch$CompositeDispatch.dispatch(BroadcastDispatch.java:363)
    at org.gradle.internal.event.BroadcastDispatch$CompositeDispatch.dispatch(BroadcastDispatch.java:261)
    at org.gradle.internal.event.ListenerBroadcast.dispatch(ListenerBroadcast.java:148)
    at org.gradle.internal.event.ListenerBroadcast.dispatch(ListenerBroadcast.java:37)
    at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
    at jdk.proxy1/jdk.proxy1.$Proxy64.afterEvaluate(Unknown Source)
    at org.gradle.configuration.project.LifecycleProjectEvaluator$NotifyAfterEvaluate$1.execute(LifecycleProjectEvaluator.java:247)
    at org.gradle.configuration.project.LifecycleProjectEvaluator$NotifyAfterEvaluate$1.execute(LifecycleProjectEvaluator.java:244)
    at org.gradle.api.internal.project.DefaultProject.stepEvaluationListener(DefaultProject.java:1493)
    at org.gradle.configuration.project.LifecycleProjectEvaluator$NotifyAfterEvaluate.run(LifecycleProjectEvaluator.java:253)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:29)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:26)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.run(DefaultBuildOperationRunner.java:47)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:68)
    at org.gradle.configuration.project.LifecycleProjectEvaluator$EvaluateProject.lambda$run$0(LifecycleProjectEvaluator.java:114)
    at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.lambda$applyToMutableState$0(DefaultProjectStateRegistry.java:388)
    at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.lambda$fromMutableState$1(DefaultProjectStateRegistry.java:411)
    at org.gradle.internal.work.DefaultWorkerLeaseService.withReplacedLocks(DefaultWorkerLeaseService.java:345)
    at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.fromMutableState(DefaultProjectStateRegistry.java:411)
    at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.applyToMutableState(DefaultProjectStateRegistry.java:387)
    at org.gradle.configuration.project.LifecycleProjectEvaluator$EvaluateProject.run(LifecycleProjectEvaluator.java:100)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:29)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:26)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.run(DefaultBuildOperationRunner.java:47)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:68)
    at org.gradle.configuration.project.LifecycleProjectEvaluator.evaluate(LifecycleProjectEvaluator.java:72)
    at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:792)
    at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:156)
    at org.gradle.api.internal.project.ProjectLifecycleController.lambda$ensureSelfConfigured$2(ProjectLifecycleController.java:84)
    at org.gradle.internal.model.StateTransitionController.lambda$doTransition$13(StateTransitionController.java:247)
    at org.gradle.internal.model.StateTransitionController.doTransition(StateTransitionController.java:258)
    at org.gradle.internal.model.StateTransitionController.doTransition(StateTransitionController.java:246)
    at org.gradle.internal.model.StateTransitionController.lambda$maybeTransitionIfNotCurrentlyTransitioning$10(StateTransitionController.java:207)
    at org.gradle.internal.work.DefaultSynchronizer.withLock(DefaultSynchronizer.java:34)
    at org.gradle.internal.model.StateTransitionController.maybeTransitionIfNotCurrentlyTransitioning(StateTransitionController.java:203)
    at org.gradle.api.internal.project.ProjectLifecycleController.ensureSelfConfigured(ProjectLifecycleController.java:84)
    at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.ensureConfigured(DefaultProjectStateRegistry.java:362)
    at org.gradle.execution.TaskPathProjectEvaluator.configure(TaskPathProjectEvaluator.java:33)
    at org.gradle.execution.TaskPathProjectEvaluator.configureHierarchy(TaskPathProjectEvaluator.java:49)
    at org.gradle.configuration.DefaultProjectsPreparer.prepareProjects(DefaultProjectsPreparer.java:42)
    at org.gradle.configuration.BuildTreePreparingProjectsPreparer.prepareProjects(BuildTreePreparingProjectsPreparer.java:64)
    at org.gradle.configuration.BuildOperationFiringProjectsPreparer$ConfigureBuild.run(BuildOperationFiringProjectsPreparer.java:52)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:29)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:26)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.run(DefaultBuildOperationRunner.java:47)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:68)
    at org.gradle.configuration.BuildOperationFiringProjectsPreparer.prepareProjects(BuildOperationFiringProjectsPreparer.java:40)
    at org.gradle.initialization.VintageBuildModelController.lambda$prepareProjects$2(VintageBuildModelController.java:84)
    at org.gradle.internal.model.StateTransitionController.lambda$doTransition$13(StateTransitionController.java:247)
    at org.gradle.internal.model.StateTransitionController.doTransition(StateTransitionController.java:258)
    at org.gradle.internal.model.StateTransitionController.doTransition(StateTransitionController.java:246)
    at org.gradle.internal.model.StateTransitionController.lambda$transitionIfNotPreviously$11(StateTransitionController.java:221)
    at org.gradle.internal.work.DefaultSynchronizer.withLock(DefaultSynchronizer.java:34)
    at org.gradle.internal.model.StateTransitionController.transitionIfNotPreviously(StateTransitionController.java:217)
    at org.gradle.initialization.VintageBuildModelController.prepareProjects(VintageBuildModelController.java:84)
    at org.gradle.initialization.VintageBuildModelController.getConfiguredModel(VintageBuildModelController.java:64)
    at org.gradle.internal.build.DefaultBuildLifecycleController.lambda$withProjectsConfigured$1(DefaultBuildLifecycleController.java:116)
    at org.gradle.internal.model.StateTransitionController.lambda$notInState$4(StateTransitionController.java:154)
    at org.gradle.internal.work.DefaultSynchronizer.withLock(DefaultSynchronizer.java:44)
    at org.gradle.internal.model.StateTransitionController.notInState(StateTransitionController.java:150)
    at org.gradle.internal.build.DefaultBuildLifecycleController.withProjectsConfigured(DefaultBuildLifecycleController.java:116)
    at org.gradle.internal.build.DefaultBuildToolingModelController.locateBuilderForTarget(DefaultBuildToolingModelController.java:57)
    at org.gradle.internal.buildtree.DefaultBuildTreeModelCreator$DefaultBuildTreeModelController.lambda$locateBuilderForTarget$0(DefaultBuildTreeModelCreator.java:73)
    at org.gradle.internal.build.DefaultBuildLifecycleController.withToolingModels(DefaultBuildLifecycleController.java:185)
    at org.gradle.internal.build.AbstractBuildState.withToolingModels(AbstractBuildState.java:134)
    at org.gradle.internal.buildtree.DefaultBuildTreeModelCreator$DefaultBuildTreeModelController.locateBuilderForTarget(DefaultBuildTreeModelCreator.java:73)
    at org.gradle.internal.buildtree.DefaultBuildTreeModelCreator$DefaultBuildTreeModelController.locateBuilderForDefaultTarget(DefaultBuildTreeModelCreator.java:68)
    at org.gradle.tooling.internal.provider.runner.DefaultBuildController.getTarget(DefaultBuildController.java:157)
    at org.gradle.tooling.internal.provider.runner.DefaultBuildController.getModel(DefaultBuildController.java:101)
    at org.gradle.tooling.internal.consumer.connection.ParameterAwareBuildControllerAdapter.getModel(ParameterAwareBuildControllerAdapter.java:39)
    at org.gradle.tooling.internal.consumer.connection.UnparameterizedBuildController.getModel(UnparameterizedBuildController.java:113)
    at org.gradle.tooling.internal.consumer.connection.NestedActionAwareBuildControllerAdapter.getModel(NestedActionAwareBuildControllerAdapter.java:31)
    at org.gradle.tooling.internal.consumer.connection.UnparameterizedBuildController.findModel(UnparameterizedBuildController.java:97)
    at org.gradle.tooling.internal.consumer.connection.NestedActionAwareBuildControllerAdapter.findModel(NestedActionAwareBuildControllerAdapter.java:31)
    at org.gradle.tooling.internal.consumer.connection.UnparameterizedBuildController.findModel(UnparameterizedBuildController.java:81)
    at org.gradle.tooling.internal.consumer.connection.NestedActionAwareBuildControllerAdapter.findModel(NestedActionAwareBuildControllerAdapter.java:31)
    at org.gradle.tooling.internal.consumer.connection.UnparameterizedBuildController.findModel(UnparameterizedBuildController.java:66)
    at org.gradle.tooling.internal.consumer.connection.NestedActionAwareBuildControllerAdapter.findModel(NestedActionAwareBuildControllerAdapter.java:31)
jarrodrobins commented 1 year ago

Unfortunately it looks like this repo is abandoned. I've spent the last few days bashing away at replacing this plugin for my own project and seem to have gotten my own script working. There are many, many similar examples online but most of them are out of date (Android Gradle Plugin/Gradle seem to break things every major release 🙄), so as of May 2023 the following works for my project.

Import the following into each of your module build.gradles by adding

apply from: "$rootProject.projectDir/jacoco.gradle"

I'm currently using Gradle 8.0 and Jacoco 0.8.8 (I have this defined in the root project's build.gradle)

buildscript {
    ext {
        jacocoVersion = '0.8.8'
   }
}

jacoco.gradle I only ever run this Gradle task on my project's internalDebug build. If you don't have build flavors or want to do something different, you may need to modify this slightly.

apply plugin: 'jacoco'

jacoco {
    toolVersion = "$jacocoVersion"
}

// Force Jacoco Version

subprojects {
    configurations.all {
        resolutionStrategy {
            eachDependency { details ->
                if ('org.jacoco' == details.requested.group) {
                    details.useVersion "$jacocoVersion"
                }
            }
        }
    }
}

project.afterEvaluate { project ->

    tasks.withType(Test) {
        jacoco.includeNoLocationClasses = true
        jacoco.excludes = ['jdk.internal.*']
    }

    final flavor = "internal"
    final buildType = "debug"
    final variant = "$flavor${buildType.capitalize()}"
    final taskName = "jacocoTest${variant.capitalize()}UnitTestReport"

    task "$taskName"(type: JacocoReport, dependsOn: "test${variant.capitalize()}UnitTest") {

        reports {
            csv.required = false
            xml.required = true
            html.required = true
        }

        final fileFilter = [
                // data binding
                '**/databinding/*',
                'android/databinding/**/*.class',
                '**/android/databinding/*Binding.class',
                '**/android/databinding/*',
                '**/androidx/databinding/*',
                '**/BR.*',
                // android
                '**/R.class',
                '**/R$*.class',
                '**/BuildConfig.*',
                '**/Manifest*.*',
                '**/*Test*.*',
                'android/**/*.*',
                // kotlin
                '**/*MapperImpl*.*',
                '**/*$ViewInjector*.*',
                '**/*$ViewBinder*.*',
                '**/BuildConfig.*',
                '**/*Component*.*',
                '**/*BR*.*',
                '**/Manifest*.*',
                '**/*$Lambda$*.*',
                '**/*Companion*.*',
                '**/*Module*.*',
                '**/*Dagger*.*',
                '**/*Hilt*.*',
                '**/*MembersInjector*.*',
                '**/*_MembersInjector.class',
                '**/*_Factory*.*',
                '**/*_Provide*Factory*.*',
                '**/*Extensions*.*',
                // sealed and data classes
                '**/*$Result.*',
                '**/*$Result$*.*',
                // adapters generated by moshi
                '**/*JsonAdapter.*',
                // Hilt
                '**/*Module.kt',
                '**/di/**',
                'dagger.hilt.internal/*',
                'hilt_aggregated_deps/*',

                '**/*$Result.*', /* filtering `sealed` and `data` classes */
                '**/*$Result$*.*',/* filtering `sealed` and `data` classes */
                '**/*Args*.*', /* filtering Navigation Component generated classes */
                '**/*Directions*.*', /* filtering Navigation Component generated classes */
                '**/*inlined*.class', /* filtering inlined classes */
                '**/composables/**'
                /* INSERT ANY OTHER JUNK YOU WANT FILTERED OUT HERE */
        ]

        final androidKotlinTree = fileTree(dir: "${project.buildDir}/tmp/kotlin-classes/${variant}", excludes: fileFilter)
        final kotlinTree = fileTree(dir: "${project.buildDir}/classes/kotlin/main", excludes: fileFilter)
        final javacTree = fileTree(dir: "${project.buildDir}/intermediates/javac/${variant}/classes", excludes: fileFilter)

        final mainSrc = "${project.projectDir}/src/main/java"
        final productFlavorSrc = "${project.projectDir}/src/${flavor}/java"
        final buildTypeSrc = "${project.projectDir}/src/${buildType}/java"

        sourceDirectories.setFrom files([mainSrc, productFlavorSrc, buildTypeSrc])
        classDirectories.setFrom files([androidKotlinTree, kotlinTree, javacTree])
        executionData.setFrom fileTree(dir: project.buildDir, includes: [
                "jacoco/test${variant.capitalize()}UnitTest.exec",
                "outputs/unit_test_code_coverage/${variant}UnitTest/test${variant.capitalize()}UnitTest.exec",
        ])
    }
}

Note: that this script does NOT put the output files in the same directory that the plugin does. This is important if you're passing the coverage information off to something like Sonar.

If you're using Sonar, I'm setting the xmlReportPaths property to -

property 'sonar.coverage.jacoco.xmlReportPaths', "**/build/reports/jacoco/**/*.xml"

If set up correctly, running ./gradlew jacocoTestInternalDebugUnitTestReport (or similar, depending on your build flavors) should generate the coverage information.

Note for the future - inevitably, Gradle/Android Gradle Plugin will probably break this again. Chances are, the sourceDirectories, classDirectories or executionData directories have changed. Note: I'm also not gathering coverage from integration tests, only unit tests, so if you need that, you'll probably need to add another path to the executionData array. At one point this directory was 'outputs/code-coverage/connected/*coverage.ec' but I have no idea if it still is, as I don't need to gather it in my project so haven't looked into it.

Hope this helps someone.

mxalbert1996 commented 1 year ago

I rewrote this plugin and removed all the usages of deprecated APIs (and also migrated to the new AGP variant API). It's working well with AGP 8.0.1 / Gradle 8.1.1 for me. I've published it to Maven Central so feel free to use it 😉 https://github.com/mxalbert1996/jacoco-android-gradle-plugin