How to best model dependencies between modules under the same topic?

Please consider one topic to be e.g. a concrete application of some kind containing different modules for different purposes: Some model to manage some data, some layer to access a database, some view implemented as web-UI, some daemons doing tasks in the background etc. One needs to build and release the web-UI independently of the daemons, the layer to access the database is part of some independent backend as well, but all of those e.g. use the same model to manage data.

What’s the preferred way to model dependencies like this?

From my understanding, Gradle supports multi-project builds, composite builds and publishing artifacts to some kind of repository. But all of those seem to have their own downsides and no approach seems to work flawlessly.

Multi-project builds for example put everything into one directory and are not very well supported by Eclipse Buildship regarding task views and stuff. Composite builds in my opinion are an enhancement to those multi-project builds because they don’t combine various different modules into one project and are more aligned to with how modern IDEs seem to understand the concepts of projects vs. workspaces/topics. OTOH, those composite builds are not very well supported in Buildship as well: Loading projects with lots of includeBuild-statements for each other is error-prone and slow as hell, while Eclipse itself could easily manage those dependencies on project level fast.

The good thing for both project types is fast turnaround times in theory: One can simply change individual projects, build and test them in the IDE without needing to care about version numbers of artifacts, publishing into some repo using snapshots etc. When things are finished, one is able to commit and publish everything at once as needed.

The last way of modeling dependencies seems to be instead of using composite builds, simply manage individual projects publishing their artifacts to some repo and let other builds consume those. So instead of using includeBuild in settings.gradle, one would simply make the repo available and let Gradle download things. That seems to be supported pretty well in Buildship, seems to be reasonably fast because of independent, small builds etc.

But turnaround times when changing more than one module under the same topic/app are pretty bad: One always needs to publish to some repo and needs to take care of version numbers, if coworkers using the same repo see the work-in-progress already, if version numbers clash etc. Additionally, depending on the repo-target, its OS and the OS of the clients, one is forced to use some special repo manager because Gradle does not create intermediate directories and stuff like that.

So, after using Gradle for a while now, there seems to be no way to manage one app including all its modules in a simple, reliable way. I’m running into problems all of the time, reconsidering approaches and need to accept their downsides. My experiences with somewhat complex Maven-builds aren’t much better, though, but I hoped the experiences with Gradle would be.

So again: What’s the preferred way to model dependencies like described at the top? Thanks!

Hi @ams_tschoening,

Multi-projects is the preferred way in general. In theory composite builds might be suprior at some point in the future, but currently they still have some drawbacks. So I would only use them if I have other requirements, like the need to use multiple Git repositories.

At the moment, multi-project builds are more optimized and faster in most scenarios.

Publishing locally is something I would not recommend. You loose a lot of smartness and performance optimization by that.

I think the support in Buildship for multi-projects is fine in general. (I am not familiar with the task view issue you linked.) Also other IDEs like IDEA and Android Studio are optimized to work with multi-project builds.