Unexpected "Duplicate path" warning in :processFuncTestResources task

After upgrade to Gradle 6.3 I started to see number of the following warning (for different paths):

> Task :processFuncTestResources
Copying or archiving duplicate paths with the default duplicates strategy has been deprecated.
This is scheduled to be removed in Gradle 7.0. Duplicate path: 
"testProjects/junit5simple/src/test/java/pitest/test/LibraryJUnit5Test.java".
Explicitly set the duplicates strategy to 'DuplicatesStrategy.INCLUDE' if you want to allow duplicate paths.
Consult the upgrading guide for further information: https://docs.gradle.org/6.3/userguide/upgrading_version_5.html#implicit_duplicate_strategy_for_copy_or_archive_tasks_has_been_deprecated
Copying or archiving duplicate paths with the default duplicates strategy has been deprecated.
This is scheduled to be removed in Gradle 7.0. Duplicate path: 
"testProjects/junit5simple/src/main/java/pitest/test/Library.java".
Explicitly set the duplicates strategy to 'DuplicatesStrategy.INCLUDE' if you want to allow duplicate paths.
Consult the upgrading guide for further information: https://docs.gradle.org/6.3/userguide/upgrading_version_5.html#implicit_duplicate_strategy_for_copy_or_archive_tasks_has_been_deprecated
...

I don’t use copy or zip tasks explicitly. I’m not sure why those files in funcTest resources are considered as duplicated.

My funcTest sourceDirs configuration (and some lines below):

The content on the resources dir with some sample projects:

How to avoid those warnings?

Should I report a bug on it?

Sorry for the topic revival, but I had encountered exactly the same issue today and I’ll post the fix for other people who might run into it as well.

By default SourceSets are preconfigured to find sources and resources in conventional directories src/name/language and src/name/resources (at least with java, groovy … plugins).

The method srcDir adds new directories to the existing ones. And since the directories given are the same as the default ones, one obtains a duplicated path warning.

Either use setSrcDirs which overrides existing directories with given ones srcDirs = ['foo/bar'] // note the = leading to the call to setSrcDirs or, even better in this very case, keep the default ones:

sourceSets {
    funcTest {
        groovy {
            compileClasspath += sourceSets.main.compileClasspath // required to compile groovy
        }
    }
}

Thanks for a reminder. I reported it as a regression: https://github.com/gradle/gradle/issues/13578

Gradle 7.0 is on its way…

@Pierre1 My case has been resolved by a suggestion by @sterling to use:

sourceSets {
    funcTest
}

Your case seems to be different, so you probably need to report another issue (most likely before 7.0 is released).

For anyone coming here from google (one of the top results for this error):

This error can also happen in the processResources task if you have a task that generates files and places them into src/main/resources. The processResources incremental build code gets confused by the newly generated files and doesn’t recognize them as the “same” as the files it copied into the build folder last time. So it complains that it’s found two files with the same name (one copy in the source dir, one copy in the dest dir), and all that’s actually different is the timestamp (usually) but it can’t figure that out.

A solution for this is to redirect whatever task is outputting to src/main/resources to instead output to processResources.destinationDir (usually build/resources/main, but not always). You could also set DuplicatesStrategy.INCLUDE, since the new files will overwrite the old ones. BUT, this breaks incremental build detection, and tasks will run even when they should be up-to-date. That might be a small slowdown or a very large slowdown.

This issue applies to versions 6.4 through and including 7.5.1 (current).

Your suggested solutions are not just slowdowns, they can also lead to incorrect builds, incorrect build-cache entries and so on.
You should never have overlapping task outputs for two tasks.
So if you have a ProcessResources task like processResources that has the whole build/resources/main directory as output directory, then no other task should ever put additional files in there or modify files that are present there.

And you should imho also never generate things into the checked-in directories.

Better generate to some distinct folder like layout.buildDirectory.dir(task.name) and register the task as resource source directory like:

sourceSets {
    main {
        resources {
            srcDir(tasks.generateMyResources)
        }
    }
}

This way the defined outputs of the task are automatically considered resources by all tasks that consume the resources and also immediately have the necessary task dependencies automatically. Because practically every time you do a manual dependsOn (without a lifecycle task on the left-hand side) you are adding a code smell. :wink: