There is an gradle plugin in my submodule. This plugin will generate some files in the afterEvaluate callback and put them in the assets folder. The main project will package these files into the apk when compiling. These codes work when using gradle 7.5 and agp 7.4.2.
When I upgrade gradle to 8.0+, agp to 8.2.2 and compile again, the log shows: Reason: Task ‘:app:mergeProductFreeDebugAssets’ uses this output of task ‘:app:costomTask’ without declaring an explicit or implicit dependency. This can lead to incorrect results being produced, depending on what order the tasks are executed.
Where ‘Product’ and ‘free’ are my productFlavors. So mergeProductFreeDebugAssets is a predefined task of agp.
I tried to set the dependencies between tasks in buildSrc. However, the following two methods cannot be compiled and still report the above error.
I modified the plugin code of the submodule to generate those files in the apply function instead of in the afterEvaluate callback. And set the dependencies between tasks in buildSrc. Then I recompiled the main project, and this time it compiled and installed normally.
Is there any way to compile normally without modifying the submodule plugin, just modify the main project buildSrc code?
The main problem is, that you have afterEvaluate at all.
The main earnings for using it are ordering problem, timing problems, and race conditions.
Using afterEvaluate instead of finding a proper alternative way to do something is like calling Platform.runLater or SwingUtilities.invokeLater to “fix” a GUI problem.
It usually just shifts the problem to a later more hard to find, more hard to debug, more hard to reproduce, and more hard to fix point in time.There are rare cases where afterEvaluate is necessary nowadays, for example if you need to interact with some plugin that itself badly uses afterEvaluate with which you have to cooperate, or if you need to bridge Property -based things with legacy primitive-based things.
Additionally, the advice to add a task dependency is not really a good one in this situation, as it almost always is also just a duct tape kind of symptom treatment instead of a proper fix.
If you get his error, it usually is a sign that you either have tasks with overlapping outputs, or that task outputs are not properly wired to task inputs which would automatically carry the necessary task dependencies if necessary.
How to solve it properly in your concrete case I cannot say without seeing the code.
But to your tries to solve it, in “taskgraph whenready” it is way too late to add a dependency, as the task graph is already calculated so adding a dependency is not going to be considered anymore. I even wonder why this does not fail, I guess Gradle folks should add some error when trying to do so.
The second try with the afterEvaluate could maybe work, but again, using afterEvaluate is bad.
And actually it should not even be necessary, assuming from the variable name that customTaskName is a variable holding the task name as a String as that is then evaluated late anyway and thus does not need afterEvaluate to work. Why it does not work is hard to say without an MCVE.
But the proper solution would be to 1. get rid of afterEvaluate and 2. properly wire task outputs and task inputs together instead of declaring a dependency explicitly. Practically any explicit dependsOn that does not have a lifecycle task on the left-hand side is a code-smell and is usually a sign that you do not wire things together properly.