Skip to content

Unable to exclude classes (Method too large Exception) #1902

@PranayD1807

Description

@PranayD1807

JAVA VERSION: 17

I am trying to run instrumentation tests on Android (Kotlin) with JaCoCo after enabling > > testCoverageEnabled. The build fails with the following error:

Execution failed for task ':app:mergeExtDexQa'.
Could not resolve all files for configuration ':app:qaRuntimeClasspath'.
   > Failed to transform vivalink-libs-core-1.8.aar (vigo.vivalink.libs:vivalink-libs-core:1.8) to match attributes {artifactType=android-dex, asm-transformed-variant=NONE, dexing-enable-desugaring=true, dexing-enable-jacoco-instrumentation=true, dexing-is-debuggable=true, dexing-min-sdk=26, org.gradle.category=library, org.gradle.libraryelements=jar, org.gradle.status=release, org.gradle.usage=java-runtime}.
      > Execution failed for JacocoTransform: /Users/pranay/.gradle/caches/transforms-3/2e2b3475e8ab3f48b14d748f6cbd2367/transformed/jetified-vivalink-libs-core-1.8-runtime.jar.
         > org.gradle.internal.operations.BuildOperationInvocationException (no error message)

The root cause appears to be:

Caused by: org.objectweb.asm.MethodTooLargeException: Method too large: com/ihealth/communication/ins/POMethod.a ()Ljava/util/HashMap;

I have followed this https://thsaravana.github.io/blog/jacoco-single-coverage-for-multi-module/ to implement it

My Files:

  1. root/jacoco/project.gradle
apply plugin: 'jacoco'

jacoco {
    toolVersion '0.8.10'
}

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

project.afterEvaluate {
    def variants = ["qa"]

    tasks.create(name: "generateCoverageReport", type: JacocoReport) {

        group = "Reporting"
        description = "Generate overall Jacoco coverage report for the selected builds."

        reports {
            html.required.set(true)
            xml.required.set(true)
        }

        def excludes = [
                '**/R.class',
                '**/R$*.class',
                '**/BuildConfig.*',
                '**/Manifest*.*',
                '**/*Test*.*',
                'android/**/*.*',
                'androidx/**/*.*',
                '**/*$ViewInjector*.*',
                '**/*Dagger*.*',
                '**/*MembersInjector*.*',
                '**/*_Factory.*',
                '**/*_Provide*Factory*.*',
                '**/*_ViewBinding*.*',
                '**/AutoValue_*.*',
                '**/R2.class',
                '**/R2$*.class',
                '**/*Directions$*',
                '**/*Directions.*',
                '**/*Binding.*'
        ]

        def jClasses = subprojects.collect { proj ->
            variants.collect { variant ->
                "${proj.buildDir}/intermediates/javac/$variant/classes"
            }
        }.flatten()
        def kClasses = subprojects.collect { proj ->
            variants.collect { variant ->
                "${proj.buildDir}/tmp/kotlin-classes/$variant"
            }
        }.flatten()

        def javaClasses = jClasses.collect { path ->
            fileTree(dir: path, excludes: excludes)
        }
        def kotlinClasses = kClasses.collect { path ->
            fileTree(dir: path, excludes: excludes)
        }

        classDirectories.from = files([javaClasses, kotlinClasses])
        def sources = subprojects.collect { proj ->
            variants.collect { variant ->
                ["${proj.projectDir}/src/main/java", "${proj.projectDir}/src/main/kotlin",
                 "${proj.projectDir}/src/$variant/java", "${proj.projectDir}/src/$variant/kotlin"]
            }.flatten()
        }.flatten()
        sourceDirectories.from = files(sources)

        def executions = subprojects.collect { proj ->
            variants.collect { variant ->
                def path = "${proj.buildDir}/jacoco/test${variant.capitalize()}UnitTest.exec"
                if ((new File(path)).exists()) path else null
            }
        }.flatten()
        executions.removeAll([null])

        executionData.from = files(executions)
    }
}
  1. root/jacoco/modules.gradle
apply plugin: 'jacoco'

jacoco {
    toolVersion '0.8.10'
}

tasks.withType(Test) {
    jacoco.includeNoLocationClasses = true
    jacoco.excludes = ['jdk.internal.*', 'vigo.mobile.vigoandroidlibs.*']
    jacoco.destinationFile = file("$buildDir/jacoco/${name}.exec")
}

project.afterEvaluate {
    (android.hasProperty('applicationVariants') ? android.'applicationVariants' : android.'libraryVariants')
            .all { variant ->
                def variantName = variant.name
                def capVariantName = variantName.capitalize()
                def testTaskName = "test${capVariantName}UnitTest"
                tasks.create(name: "${variantName}Coverage", type: JacocoReport, dependsOn: testTaskName) {

                    group = "Reporting"
                    description = "Generate Jacoco coverage reports for the ${variantName} build."

                    reports {
                        html.required.set(true)
                        xml.required.set(true)
                    }

                    def excludes = [
                            '**/R.class',
                            '**/R$*.class',
                            '**/BuildConfig.*',
                            '**/Manifest*.*',
                            '**/*Test*.*',
                            'android/**/*.*',
                            'androidx/**/*.*',
                            '**/*$ViewInjector*.*',
                            '**/*Dagger*.*',
                            '**/*MembersInjector*.*',
                            '**/*_Factory.*',
                            '**/*_Provide*Factory*.*',
                            '**/*_ViewBinding*.*',
                            '**/AutoValue_*.*',
                            '**/R2.class',
                            '**/R2$*.class',
                            '**/*Directions$*',
                            '**/*Directions.*',
                            '**/*Binding.*'
                    ]

                    def jClasses = "${project.buildDir}/intermediates/javac/${variantName}/classes"
                    def kClasses = "${project.buildDir}/tmp/kotlin-classes/${variantName}"
                    def javaClasses = fileTree(dir: jClasses, excludes: excludes)

                    def kotlinClasses = fileTree(dir: kClasses, excludes: excludes)

                    classDirectories.from = files([javaClasses, kotlinClasses])
                    def sourceDirs = ["${project.projectDir}/src/main/java", "${project.projectDir}/src/main/kotlin",
                                      "${project.projectDir}/src/${variantName}/java", "${project.projectDir}/src/${variantName}/kotlin"]

                    sourceDirectories.from = files(sourceDirs)

                    executionData.from = files(["${project.buildDir}/jacoco/${testTaskName}.exec"])
                }
            }

    tasks.register('coverAllVariants') {
        dependsOn(provider {
            tasks.findAll { task -> task.name.endsWith('Coverage') }
        })
    }
}
  1. project level build.gradle
buildscript {
    ext.kotlin_version = '1.9.10'
    ext.protobufVersion = '3.12.0'
    apply from: 'jacoco/project.gradle'

    repositories {
        google()
...
  1. app level build.gradle
dependencies {
}

apply plugin: 'com.google.gms.google-services'
apply from: '../jacoco/modules.gradle'

// Exclude the problematic library
configurations.all {
    ...
}

I have also tried in jacoco/project.gradle:

configurations {
    jacocoAgent
}

dependencies {
    jacocoAgent "org.jacoco:org.jacoco.agent:0.8.10"
}

tasks.configureEach { task ->
    if (task.name.startsWith("test") && task.name.endsWith("UnitTest")) {
        task.doFirst {
            task.jvmArgs += [
                    "-javaagent:${configurations.jacocoAgent.singleFile}=excludes=vigo/mobile/vigoandroidlibs/**"
            ]
        }
    }
}

however, I still get that error. I am still unable to exclude this problem causing class/module

Originally posted by @PranayDVigo in #4

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions