Micah Arnson-Serotta
05/17/2024, 11:29 PM./gradlew assembleDebug
but I am running into issues with task dependencies.
Initially, the error was
A problem was found with the configuration of task ':app:checkAlphaDebugAarMetadata' (type 'CheckAarMetadataTask').
- Gradle detected a problem with the following location: '/Users/micah/app/node_modules/@react-native-firebase/messaging/android/build/intermediates/aar_metadata/debug/aar-metadata.properties'.
Reason: Task ':app:checkAlphaDebugAarMetadata' uses this output of task ':@react-native-firebase_messaging:writeDebugAarMetadata' without declaring an explicit or implicit dependency. This can lead to incorrect results being produced, depending on what order the tasks are executed.
I updated my /android/app/build.gradle
file to have the following.
afterEvaluate {
tasks.matching { it.name == 'checkAlphaDebugAarMetadata' }.all { task ->
task.dependsOn(':@react-native-firebase_messaging:writeDebugAarMetadata')
}
}
After running ./gradlew clean
and ./gradlew assembleDebug
again, I continued to run into more task dependency issues. Ultimately, I ended up adding the following the the above file
afterEvaluate {
tasks.matching { it.name == 'checkAlphaDebugAarMetadata' }.all { task ->
task.dependsOn(':@react-native-firebase_messaging:writeDebugAarMetadata')
}
tasks.matching { it.name == ':react-native-firebase_messaging:packageDebugResources' }.all { task ->
task.dependsOn(':@react-native-firebase_messaging:compileDebugRenderscript')
task.dependsOn(':@react-native-firebase_messaging:generateDebugResValues')
}
tasks.matching { it.name == ':@react-native-firebase_messaging:generateDebugResValues' }.all { task ->
task.dependsOn(':react-native-firebase_messaging:packageDebugResources')
}
tasks.matching { it.name == ':@react-native-firebase_messaging:extractDebugAnnotations' }.all { task ->
task.dependsOn(':react-native-firebase_messaging:compileDebugAidl')
}
}
Surprisingly, now when I run the same command, I am getting the error
Reason: Task ':react-native-firebase_messaging:packageDebugResources' uses this output of task ':@react-native-firebase_messaging:generateDebugResValues' without declaring an explicit or implicit dependency. This can lead to incorrect results being produced, depending on what order the tasks are executed.
even though it is being set above!
I fear I am chasing down the wrong issue, but at this point I'm not sure where to refocus my efforts. Any help here would be great!Vampire
05/21/2024, 12:19 PMafterEvaluate
is evil and should be avoided at almost any cost. Especially in this case, you use API that works on all existing tasks and tasks added in the future, so it does not really have an effect anyway
• tasks.matching { ... }.all { ... }
is super-evil, it totally breaks task-configuration avoidance for each and every task so wastes time on practically every build invocation as each and every task needs to be configured. If needing something like that, at least use tasks.matching { ... }.configureEach { ... }
which is task-configuration avoidance safe
• Adding explicit dependsOn
between tasks is practically always a code smell unless the left-hand task is a lifecycle task. The advise by the Gradle error is imho a very false friend. Adding explicit dependsOn
is at most symptom treatment and very seldomly a proper fix. Usually, you should instead make sure that task outputs are properly wired to task inputs, so that the necessary task dependency is implicitly added automatically wherever it is needed
• If you configuration would be effective, you would have introduced a circular dependency, because you try to make :@react-native-firebase_messaging:generateDebugResValues
depend on :react-native-firebase_messaging:packageDebugResources
and at the same time the other way around resulting in a chicken-and-egg situation
• Your configuration is not effective, because tasks
only contains the tasks of the project that currently configure, so the matching for tasks in the project :react-native-firebase_messaging
and :@react-native-firebase_messaging
will never find the task you intend to find. You would need to configure the tasks within those projects if really necessary and as those are probably tasks in included builds you get from dependencies with that strange react-native tactic, you would need to patch those dependency builds or get them to fix their builds, to not do cross-project or even cross-build configuration which is even more evil or even impossibleDaniel B Duval
06/12/2024, 5:37 PMafterEvaluate
in the context of onVariants
and not purely in the stand alone afterEvaluate
. Not sure if this would still fall under Vampire’s evil concept though 🙂
When I’ve seen this in the past is when I’ve added a custom task that I want to do in the middle of the build process. Say, for example, I do not like the default output of an AAR or APK, but would rather have it in a cleaner path (such as project/artifacts
for a less parameterized downstream CI stage that needs the upstream artifacts.
If you’re not injecting a task like this, I’d wonder why you’d need to add this sort of item as I haven’t run into a case where I’d need to without adding a task into the AGP build itself.Vampire
06/12/2024, 5:41 PMafterEvaluate
, especially if also some plugins use it and you have to do something after that and don't find a reactive way.
But the main effect of afterEvaluate
is, to introduce ordering problems, timing problems, and race conditions.
And in many cases it is just symptom treatment like using Platform.runLater
to "fix" a GUI issue and just moves problems to a later, harder to reproduce, harder to diagnose, and harder to fix point in time. 🙂