Task A uses this output of task B without declaring an explicit or implicit dependency

I have been trying to solve this implicit/explicit dependency warning that started after Gradle 7.4 upgrade (from Gradle 6).
I was able to fix it, but I thought I should share it here if anyone has more information about this and to share.
In summary, I created a plugin to be used with Java projects and one of its features is to - behind the scenes - add download a library - jar - and rename it to strip the version number and bundle it in the project’s fat jar.

I have included a stripped down version of my plugin and used Google gson as an example of a jar in this post for simplicity
The warning was caused by this line project.getDependencies().add(“compile”, fromTree) which is in the code snippet below and I can repro with it, but the warning will disappear if this line is replaced by project.getDependencies().add(“compile”, task.getOutputs().getFiles().getAsFileTree())

Below is the whole class code for this example


import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import org.apache.commons.lang3.StringUtils;
import org.gradle.api.Action;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.Task;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.file.FileTree;
import org.gradle.api.logging.Logger;
import org.gradle.api.tasks.TaskContainer;
import org.gradle.api.tasks.TaskProvider;

import java.nio.file.Paths;
import java.util.Objects;

/**
 * Plugin used to ...
 */
public class MyGradlePackagePlugin implements Plugin<Project> {

    public static final String JAR_NAME = "gson.jar";
    public static final String ADD_DEPENDENCY = "addMyDependency";

    @Override
    public void apply(final Project project) {
        final Logger logger = project.getLogger();
        Objects.requireNonNull(project, "project cannot be null.");
        final MyGradlePackagePluginExtension ext = project.getExtensions().create(
                "mygradleplugin", MyGradlePackagePluginExtension.class);

        final Configuration myconfig =
                project.getConfigurations().create("addDependencyPlugin").setTransitive(false);

        project.afterEvaluate(p -> {
            myconfig.getDependencies().add(project.getDependencies().create(ImmutableMap.of(
                    "group", "com.google.code.gson",
                    "name", "gson",
                    "version", "2.9.0"
            )));
        });

        final TaskProvider<Task> addDependency = project.getTasks().
                register(ADD_DEPENDENCY, Task.class, task -> {
                    final String destinationDir = StringUtils.isBlank(ext.getCopyToDir())
                            ? project.getBuildDir().toPath().resolve("libs").toString() :
                            ext.getCopyToDir();
                    final FileTree fromTree = project.fileTree(destinationDir,
                            tree -> tree.include("gson.jar"));
                    task.getOutputs().file(Paths.get(destinationDir).resolve(JAR_NAME));
                    //noinspection Convert2Lambda
                    task.doLast(new Action<Task>() {
                        @Override
                        public void execute(final Task task) {
                            project.getLogger().info("Copying jar from: " + myconfig.getAsPath() +
                                                             " into " + destinationDir);
                            project.copy(copy -> {
                                copy.from(myconfig)
                                        .into(destinationDir)
                                        .rename((name) -> JAR_NAME);
                            });
                        }
                    });
                    // To fix the execution optimization issue, we had to use task.getOutputs()....
                    // project.getDependencies().add("compile", task.getOutputs().getFiles().getAsFileTree());

                    // This line causes warning
                    // Execution optimizations have been disabled for task '***' to ensure correctness due to the
                    // following reasons:
                    // - Gradle detected a problem with the following location:
                    // '.......gson.jar'. Reason: Task '****' uses this output of task ':addMyDependency' without declaring
                    // an explicit or implicit dependency. This can lead to incorrect results being produced, depending on
                    // what order the tasks are executed. Please refer to https://docs.gradle.org/7.4/userguide/validation_problems.html#implicit_dependency for more details about this problem.
                    project.getDependencies().add("compile", fromTree);
                });

        project.afterEvaluate(p -> {
            // Had to keep this dependency, otherwise jar in not bundled in Gradle7 projects
            // When complete migration to Gradle 7 is done, we should revisit this
            final ImmutableList<String> gradleTasks = ImmutableList.of("assemble");
            final TaskContainer tasks = project.getTasks();
            // add the new assemble task dependency
            tasks.stream().filter(task -> gradleTasks.contains(task.getName())).forEach(
                    task -> task.dependsOn(addDependency));
        });
    }
}