JetStream
JetStream

Reputation: 550

Maven, Spring configuration for multi-module project

I am looking to set up a multi module maven project (described below) that would scale well. I have some questions about the approach which is largely drawn from the Sonatype example.

I have done a certain amount of reading on maven multi module projects but couldn't find an example going beyond the basic level.

Questions:

  1. Is this (below) a good project structure to start with? Or does it smell of disaster right from the start - i.e. would lead to heavy restructuring when setting up builds? In short, I am looking to avoid setting up something that goes against the grain with Maven.
  2. I am expecting some modules to be quite independent, while most will be interrelated. Is it alright to start with each module as a Git repo and later refactor in together modules that are tightly linked?

Objectives:

  1. Good project structure for a modular Spring, JSF2, Maven based project, that would allow for builds involving a selection of modules and their dependencies.

  2. It should be possible to deploy an individual web module on a lightweight container like Tomcat/Jetty through Maven configuration (like jetty-maven-plugin). This should be able to pull in the necessary dependencies through Maven. That makes it easy during development to focus on the module being worked on (not having to run a full build and deployment) and deploy the full application only in a complete build.

  3. The setup should allow for multiple distributions based on a selection of modules to be included in the build. I take it this can be achieved through the use of build modules that will pull and package the corresponding modules.

Project structure

Core domain classes.  
somapp.core (maven project)  
 |- someapp.core (maven module)  
 |- someapp.core.tests  

Account Management Domain classes   
someapp.accountmgmt   
|- someapp.accountmgmt   
|- someapp.accountmgmt.tests   

component1 domain classes   
someapp.component1   
|- someapp.component1   
|- someapp.component1.tests

Service 1 - # account management (User login)
someapp.accountmgmt  
 |- someapp.accountmgmt.api  
 |- someapp.accountmgmt.impl  
 |- someapp.accountmgmt.mocks  
 |- someapp.accountmgmt.tests  

someapp.service2  
 |- someapp.service2.api  
 |- someapp.service2.impl  
 |- someapp.service2.mocks   
 |- someapp.service2.tests   
 |- someapp.service2.cli    # CLI access for service2

someapp.service3  
 |- like above  

someapp.accountmgmt.web  
 |- someapp.accountmgmt.web  

someapp.service2.web  
 |- someapp.service2.web  

someapp.service3.web  
 |- someapp.service3.web  

someapp.build1 # bundle accountmgmt and service2 into 1 war file  

someapp.build2 # bundle accountmgmt and service3 into 1 war file  

somapp.build3 # bundle  accountmgmt, service2 and service3 into 1 war file  

(i.e. someapp.accountmgmt.web.war, someapp.accountmgmt.jar, someapp.service2.web.war, someapp.service2.jar, someapp.service3.web.war, someapp.service3.jar, someapp.core.jar)

I understand project structures are not set in stone. I would like to set up one that is a good starting point. Suggestions / Links to examples are welcome.

Upvotes: 8

Views: 15732

Answers (2)

Michael Gower
Michael Gower

Reputation: 81

Well for the Spring part it's already discussed and an answer accepted at Spring Configuration in a multi-module project. As far as the general layout I've only seen one WAR per project and services only bundled together if they are related (e.g. UserLoginService would not go together with DomainObjectsService).

I would suggest breaking up the structure into several different projects, with the dependencies (business objects, etc) deployed as JAR projects to a local repo and listed as normal Maven dependencies in the (now different) projects that need them. Then in your app-server you can deploy the apps to different paths (e.g. yourdomain.com/app1, yourdomain.com/service2).

My compliments to your ambition though!

EDIT: There is a way to have multiple WARs if you wish, see this SpringSource blog post about Using a shared parent application context in a multi-war Spring application.

Upvotes: 3

user1016765
user1016765

Reputation: 3043

A hierarchy starting with Spring IO through to your artifacts can be done as a single build multi-module project.

Spring-IO (dependencies)
   - Your parent pom (custom and further dependency management, plugins etc)
      - someapp-parent (really just a container for each -independent- sub-module)
         someapp-api    (deploy as jar into Nexus
         someapp-remote (Implements API and makes REST calls to your web app - also an independent jar)
         someapp-web    ('war' Exposes REST - JSON - representations of your API domain objects)
         someapp-dashboar (Admin console working with the API/web app via remote so you can manage everything, also a 'war')

Spring IO is BTW really good as a blessed set of dependencies that work well together and avoid classloader issues. Well worth migrating your project to use it as the latest version looks pretty up-to-date. I'd also recommend using Spring Boot for your web app(s).

As outlined I think its worth having all your app-related modules build as one so versioning is easier and you can test everything in a single build command. I've recently worked on a project where we keep all these modules separate, and it just means 4x the effort to merge changes, build artifacts, deploy artifacts etc.

Upvotes: 0

Related Questions