DevOps / Gradle8 Interview Questions
Why should exclude and dependency substitution be used carefully?
Both exclude and dependency substitution let you override what Gradle would otherwise resolve for a dependency, but they act globally on the resolution graph, which means they're easy to apply too broadly and silently affect parts of the build that weren't the actual target.
configurations { implementation { exclude group: 'commons-logging', module: 'commons-logging' } } configurations.all { resolutionStrategy.dependencySubstitution { substitute module('log4j:log4j') using module('org.slf4j:log4j-over-slf4j:2.0.9') } }
An exclude applied at the configuration level removes that transitive dependency for every library pulling it in, not just the one you were thinking about when you added it — if a different, unrelated dependency actually needed that excluded module, it can now fail at runtime with a missing-class error that's confusing to trace back to the exclude. Dependency substitution has a similar risk: swapping one artifact for another assumes API compatibility that may not actually hold for every consumer in the graph. Both are legitimate, sometimes necessary tools, but they're best scoped as narrowly as possible (per-configuration or per-dependency rather than globally) and documented with a comment explaining why, since the effect is easy to forget and hard to rediscover later.
More Related questions...
