Issue in gradle build 5.6.4

My gradle exception:

Execution failed for task ‘:doJacocoOfflineInstrumentation’.

Could not get unknown property ‘classesDir’ for main classes of type org.gradle.api.internal.tasks.DefaultSourceSetOutput.

My jacocotask code:

jacocoOfflineSourceSets.each { sourceSetName ->
if (file(sourceSets[sourceSetName].output.classesDir).exists()) {
def instrumentedClassedDir = “{outputDir}/{sourceSetName}”
ant.‘jacoco:instrument’(destdir: instrumentedClassedDir) {
fileset(dir: sourceSets[sourceSetName].output.classesDir, includes: ‘**/*.class’)
}
//Replace the classes dir in the test classpath with the instrumented one
sourceSets.test.runtimeClasspath -= files(sourceSets[sourceSetName].output.classesDir)
sourceSets.test.runtimeClasspath += files(instrumentedClassedDir)
instrumented = true
}

Note: I am migrating from 4.4 to 5.6.4 and getting issue durig the same.

The classesDir property was removed in favor of classesDirs. This is called out in the Upgrading your build from Gradle 4.x to 5.0 notes.

Hi James,

I changed the property to classesDirs. Now getting the below error.

Execution failed for task ‘:doJacocoOfflineInstrumentation’.

Cannot convert the provided notation to a File or URI: [N:\NXUIPOPUPENH\btaf-selenium-automation-lib\build\classes\java\main, N:\NXUIPOPUPENH\btaf-selenium-automation-lib\build\classes\groovy\main].
The following types/formats are supported:
- A String or CharSequence path, for example ‘src/main/java’ or ‘/usr/include’.
- A String or CharSequence URI, for example ‘file:/usr/include’.
- A File instance.
- A Path instance.
- A Directory instance.
- A RegularFile instance.
- A URI or URL instance.

Thanks in advance for your help.

Your original error was because the property classesDir was removed. The new property classesDirs is a collection of directories now, not a single value. The following line only takes a single value:

fileset(dir: sourceSets[sourceSetName].output.classesDir, includes: '**/*.class')

which means you’re going to need to write code to call fileset() once for each value in the collection, not just change the classesDir to classesDirs. i.e.

sourceSets.main.output.classesDirs.each { classesDir ->
    fileset(dir: classesDir, includes: '**/*.class')
}

Hi James,

Thanks for your input. But now It says the method fileset() is not found as per below.

Execution failed for task ‘:doJacocoOfflineInstrumentation’.

Could not find method fileset() for arguments [{dir=N:\NXUIPOPUPENH\btaf-selenium-automation-lib\build\classes\java\main, includes=**/*.class}] on task ‘:doJacocoOfflineInstrumentation’ of type org.gradle.api.DefaultTask.

gradle code causing the error:

if ((sourceSets.main.output.classesDirs.each { classesDir -> fileset(dir: classesDir, includes: ‘**/*.class’)}).exists())

Thanks.

That line didn’t have fileset() before. The fileset() code was only for the line that’s inside of the ant.'jacoco.instrument' block that was using fileset(). It doesn’t make sense as part of the conditional.

You have custom logic here (even if someone else wrote it) for a specific use case. You need to understand what that use case is so that you know which parts of the code are relevant to maintaining that behavior. If there are multiple classesDirs, and only some exist what do you expect to happen? That would determine how to modify the rest of your code.