Vlastimil Brecka
05/12/2025, 7:15 PMimplementation platform(foo)
in a multi module project, do I need to add this line to every build.gradle
where a "child" of the BOM is added?
(Seems to be the case)
Isn't there a central place so I don't need to spam it everywhere?Chris
05/12/2025, 7:19 PMVlastimil Brecka
05/12/2025, 7:21 PMChris
05/12/2025, 7:25 PMVlastimil Brecka
05/12/2025, 7:26 PMChris
05/12/2025, 7:27 PMVlastimil Brecka
05/12/2025, 7:28 PMVlastimil Brecka
05/12/2025, 7:29 PMChris
05/12/2025, 7:45 PMVlastimil Brecka
05/12/2025, 7:46 PMallprojects
seems to work fineVampire
05/12/2025, 8:20 PMallproject { ... }
and also all other forms of cross-project configuration is immediately introducing project coupling which works against or disables some of the more sophisticated Gradle features or optimizations. And they make your builds harder to understand and harder to maintain.
Whether a composite build is recognizably slower on clean build, depends on the project setup. If you for example use build cache, the most time-intense tasks can be reused even on clean build.
Most time until task execution you save when using configuration cache, as the previous configuration result can simply be reused.
Also, how often do you do a clean build?
If it is only on CI, who cares if it needs 20 seconds more for building your convention plugin?
On local incremental build, you will hardly recognize any longer build time.
On the other hand, you can much better maintain your build logic, even test your build logic properly and so on, and save much headache of future-you.
---
Having said all that, if you anyway use that bad-practice allprojects { ... }
just add the BOM-using there, if it is applied to projects where it is not needed, it doesn't hurt either.
Or to stack more bad-practice on top, you can probably also use the BOM in your "bottom-most" project with api
instead of implementation
and then it should propagate to the other projects.
🤷♂️Vlastimil Brecka
05/12/2025, 8:41 PMallprojects { .. }
imo, not to spite gradle, but because its too much workVampire
05/12/2025, 9:07 PMallprojects { .. }
imo
Please show the statistic that shows this.
I seldomly see a build nowadays that uses allprojects { ... }
, and if the maintainers are told that this is not a good idea, most agree and switch to convention plugins.
> but because its too much work
It is not 🙂
Most people using allprojects { ... }
I talked to in the past just were not aware that it is bad practice and that there is a much better alternative.Chris
05/12/2025, 9:17 PMallprojects
that I cannot find an alternative for:
allprojects {
afterEvaluate { Project p ->
if (p.getPlugins().hasPlugin(BasePlugin)) {
assert p.getPlugins().hasPlugin(BaseConvention)
}
}
}
The main objective here is to ensure that this other bit of bad practice is executed:
project.afterEvaluate(p -> p.getPlugins().configureEach(plugin -> {
Collection<Class<? extends Plugin>> conventions = KNOWN_CONVENTIONS.entrySet().stream().filter(e -> e.getKey().isAssignableFrom(plugin.getClass())).flatMap(e -> e.getValue().stream()).collect(Collectors.toList());
if (!conventions.isEmpty() && conventions.stream().noneMatch(convention -> project.getPlugins().hasPlugin(convention))) {
throw new IllegalStateException("Cannot apply " + plugin.getClass() + " directly. You must use a registered convention plugin: " + conventions);
}
}));
This allows me to register all my convention plugins and fail the build if a plugin for which there is a convention is applied directly. With some care I think the afterEvaluate could be eliminated... but I cannot think of a way to "force" the application of a plugin everywhere.Vampire
05/12/2025, 9:20 PMallprojects
=> bad
afterEvaluate
=> bad
getPlugins()
=> bad (see its JavaDoc)
😄Vampire
05/12/2025, 9:24 PMgradle.projectsEvaluated { ... }
that the plugin that you expect is applied.
I did an auto-apply of our "base" plugin in the settings script some time ago, but changed it to just there verify the base plugin is applied to every project,
as at some point our "base" plugin started to apply a 3rd party plugin that itself uses bad-practice afterEvaluate
and at the point where it was applied this was no longer allowed.Vampire
05/12/2025, 9:26 PMgradle.projectsEvaluated {
gradle.allprojects {
if (pluginManager.hasPlugin("base")) {
assert pluginManager.hasPlugin("your.base")
}
}
}
or similarChris
05/12/2025, 9:27 PM