Prevent dependencies in multi module project based on arbitrary module type

Good morning,

We have a growing java multi module project. (Over 200 modules, over 60 war files, over 50 developers) And with growth come questions about standardisation, consistency, maintainability.

To help increase consistency, we are starting to formalise on types of modules. A simple example being a “service-definition”-type module for internal cross webapp service API’s. The idea is that these modules should only contain Interfaces describing services and bean definitions to go with it. This module can then be both be included in the client code as well as the server code.

What we see recently is that newer developers will make unwanted dependencies. For example making a dependency from a “service-definition” module to some generic module that should only be included in the server implementation. When they do this, typically the dependency tree for that service and everything that depends on it, increases unnecessarily. Also you will get client code in the server implementation and vice versa, and developers might make mistakes of calling the wrong classes every now and then.

We have room to monitor this, but as the codebase and developer count grows we feel it is worth the time to look into making this automatically prevented. And prevent that we solely rely on code reviews or unscheduled spot checks by developers aware of the issue.

After a few discussions we are now looking at the most efficient way to prevent this as early as possible for these module types we have a clear vision on.

We started experimenting with doing a gradle.afterProject implementation which for now reports on undesirable dependencies and later on we could make that assertions to completely prevent it. This works, but also feels inefficient.

We considered writing a plugin and doing apply plugin 'ServiceDefinitionStandardization, but then the question was raised on how to guarantee that every service definition module includes this plugin.
Can/should we add plugins from settings.gradle when we are defining the multi module project?

Are there smarter / better / more efficient ways?

Do all developers use the Gradle wrapper? You could create a custom gradle distribution with a custom settings.gradle packed inside. All wrapper.properties within your organisation could then point to the custom gradle dist(s)

Perhaps this isn’t possible on every developer machine but forcing all CI builds to use the custom gradle dist(s) might be a quick win

Hi Lance,

Thank you. I forgot to mention that we are talking in a mono-repo environment here. So this is one codebase with one project with before-mentioned amounts of submodules.

Ah, that’s much simpler then. You could do something in the root build.gradle like

allprojects.findAll { it.name.endsWith('-service')) }.each {
   it.apply plugin: 'ServiceDefinitionStandardization'
}