In a simple web architecture using Spring and Maven where it consists of following layers:

  • Controller
  • Service
  • Repository
  • Shared

Where in shared module all the classes that are used among different layers are kept.

When creating a flat Maven structure, should we add the Shared module as a dependency to Repository or to every layer?

If we add the Shared module to Repository module, since Service module includes Repository dependency, and Controller adds Service module as its dependency, then transitively, controller, and also Service, modules are going to have access to Shared artifacts.

However, is it better to add Shared dependency to every module individually? Or should we break artifact dependency between each layer into its module? For instance, objects/exceptions shared among Repository and Service into its own, and Service and Controller into its own, then another shared module for clients of Controller module?

1 Answer 1


See the first sentence of Introduction to the Dependency Mechanism, Transitive Dependencies:

Maven avoids the need to discover and specify the libraries that your own dependencies require by including transitive dependencies automatically.

That means the transitive dependency mechanism is intended for automatic behind-the-scenes handling of dependencies of dependencies of which you neither own. It is not intended for artifacts you develop yourself and use as dependencies in other of your projects.

Though it's possible technically I'd not rely on transitiveness in your case. A POM describes a project and it should be recognizable at first sight what the project uses directly. Without a declaration of such a dependency the life of the person(s) doing the job after (or besides) you will become a bit harder.

Another point is using a different version (SNAPSHOT vs. release, for instance) on occasion. With using a dependency solely transitively you're bound to the version that has been declared in the dependency and if you want to use a different one you have to declare it directly anyway.

Furthermore, I guess with "flat Maven structure" you mean projects without a parent POM, right? Why this? Project Inheritance is a powerful mechanism to DRY in POMs. In your case it's the Shared dependency you declare just once in a parent POM, rather than three times in the individual POMs. (Don't you use already an aggregating main POM to be able to build all the projects in one go?)

If I get your last paragraph right you're thinking of additional projects like SharedForRepositoryAndService, SharedForServiceAndController and SharedForClientsOfController. I'd not do this. Firstly, because the things Service needs would be spread across different artifacts (and there will be more scattering the more the software evolves, believe me) and secondly I bet quite a lot of my money that this differentiation is not going to hold for the software's entire lifetime. That means, what if clients once need something that Service uses already. Are you going to move it to another SharedForServiceAndClientsOfController? What if you introduce something that's only used by Service then? Where in the now existing three do you put it? Or are you going to introduce another SharedJustForService?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.