Hello! I am attempting to run `./gradlew assembleD...
# community-support
m
Hello! I am attempting to run
./gradlew assembleDebug
but I am running into issues with task dependencies. Initially, the error was
Copy code
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.
Copy code
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
Copy code
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
Copy code
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!
v
Some notes: •
afterEvaluate
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 impossible
d
In the past for this in Android projects, I had been given the advice from gradle folks to use the
afterEvaluate
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.
v
Sometimes you hardly come around using
afterEvaluate
, 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. 🙂