Introduction
In this example we will see how to work with spring boot multi-module project and deploy them together in embedded Tomcat server. The Tomcat Server comes with the Spring Boot API, so we don’t need to include extra jar or library for it. The individual module is also deployable. You may also want to use other server like Jetty instead of Tomcat server in Spring Boot application.
In this example we have three modules email-service – responsible for sending email to the specific email address, user-service – responsible for handling user related activities and web-service – responsible for handling client request/response.
Why we need multi modules project?
Splitting the project into multiple modules is useful, for example, if the module needs to be deployed separately.
The idea of a multi-module build is if you have modules which belong together like an ear project which usually consists of several others like client, server, ejb, war, etc. Your modules share the same dependencies, in this case you will specify all the dependencies in the main pom, and all other modules can enjoy it and no need to specify for each module the same dependencies.
If you need to perform operations on multiple projects all together. You create a package from all projects, and ship it to a customer, so build them using the main pom, and package them as zip file using other maven plugin.
It makes the code easier to keep in order with big project, even if the code could technically be all in the same module.
Prerequisites
How to create multi-module maven project in Eclipse
Spring Boot 2.1.8.RELEASE
Creating Project
The name of the project is spring-boot-multi-module-project. But you need to refer to the prerequisites section for the link how to create multi module project in Eclipse.
The project structure could be shown as similar to the following image:

Creating Multi-Modules
The parent pom.xml file of spring boot multi-module project contains three modules email-service, user-service and web-service and of course these sub-modules or sub-projects must exist in the parent pom file under <modules>
tag, otherwise you would get exceptions.
We have also added spring boot dependencies and maven compiler plugin.
Related Posts:
Notice also we have packaging type as pom
for parent’s pom file because it is basically a container of submodules and each submodule is represented by a subdirectory in the same directory as we have parent project’s pom.xml with pom packaging.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.roytuts</groupId>
<artifactId>spring-boot-multi-module-project</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.8.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>12</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<modules>
<module>email-service</module>
<module>user-service</module>
<module>web-service</module>
</modules>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
The following three individual modules are explained step by step for spring boot multi-module project.
Submodule: email-service
For email-service submodule notice that we have not added any spring boot dependencies or plugin because these dependencies will be inherited from parent’s pom file.
If we need any dependency that is required for email-service then we have to add it to email-service‘s pom.xml file.
Notice for this module we have specified packaging type as jar.
Build File – pom.xml
<?xml version="1.0"?>
<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.roytuts</groupId>
<artifactId>spring-boot-multi-module-project</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>email-service</artifactId>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
</dependencies>
</project>
Service Class
Create below service layer code to send the email to a specific email address.
This method will not really send an email until you configure with email API.
package com.roytuts.email.service;
import org.springframework.stereotype.Service;
@Service
public class EmailService {
public void sendEmail(final String toAddress) {
// send email to toAddress
System.out.println("Email successfully sent");
}
}
Main Class
As we have already said that in multi-module project, individual module is independently deployable so we are creating below main class in order to deploy the spring boot project – email-service.
package com.roytuts.email.service.app;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication(scanBasePackages = "com.roytuts.email.service")
public class EmailServiceApp {
public static void main(String[] args) {
SpringApplication.run(EmailServiceApp.class, args);
}
}
Submodule: user-service
For user-service module notice that we have not added any spring boot dependencies or plugin because these dependencies will be inherited from parent’s pom file and if we need any dependency that is required for user-service then we have to add it to user-service‘s pom.xml file.
Notice for this module we have specified packaging type as jar.
There is another thing in this pom file, i.e., we have added email-service as a dependency to the user-service‘s pom file in order to use the email-service.
Build File – pom.xml
<?xml version="1.0"?>
<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.roytuts</groupId>
<artifactId>spring-boot-multi-module-project</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>user-service</artifactId>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.roytuts</groupId>
<artifactId>email-service</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>
DTO Class
The DTO class represents a blue print of the user to hold some user details or information.
The User
class contains four attributes – id, firstName, lastname and email address.
package com.roytuts.user.service.model;
public class User {
private int id;
private String firstName;
private String lastName;
private String email;
public User(int id, String firstName, String lastName, String email) {
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
Service Class
Create below service layer code to retrieve a user information and to send an email to user’s email address.
We have created some dummy data with some users and initialize these dummy data using spring’s @PostConstruct
annotation so that after construction of the userService
object the list – users
– will automatically be populated with user
objects.
package com.roytuts.user.service;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.roytuts.email.service.EmailService;
import com.roytuts.user.service.model.User;
@Service
public class UserService {
@Autowired
private EmailService emailService;
private final List<User> users = new ArrayList<>();
@PostConstruct
public void init() {
users.add(new User(1000, "Soumitra", "Roy", "contact@roytuts.com"));
users.add(new User(1001, "Sudipto", "Bhowmick", "sudipto.bhowmick@email.com"));
users.add(new User(1002, "Gautam", "Roy", "gautam.roy@email.com"));
users.add(new User(1003, "Soumitra", "Sarkar", "contact@roytuts.com"));
}
public User getUserById(final int id) {
return users.stream().filter(user -> user.getId() == id).findFirst().get();
}
public void sendEmail(User user) {
emailService.sendEmail(user.getEmail());
}
}
Main Class
As we have already said previously that in multi-modules project, individual module is independently deployable so we are creating below main class in order to deploy the spring boot project – user-service.
package com.roytuts.user.service.app;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication(scanBasePackages = "com.roytuts")
public class UserServiceApp {
public static void main(String[] args) {
SpringApplication.run(UserServiceApp.class, args);
}
}
Submodule: web-service
For web-service module also, notice that we have not added any spring boot dependencies or plugin because these dependencies will be inherited from parent’s pom file and if we need any dependency that is required for web-service then we have to add it to web-service‘s pom.xml file.
Notice for this module we have specified packaging type as jar. If you want you may also put packaging type as war but as this is a Spring Boot application so this does not make difference from application deployment.
In this pom file we have added email-service and user-service as dependencies to the web-service’s pom file in order to use email-service and user-service.
Build File: pom.xml
<?xml version="1.0"?>
<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.roytuts</groupId>
<artifactId>spring-boot-multi-module-project</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>web-service</artifactId>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.roytuts</groupId>
<artifactId>user-service</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.roytuts</groupId>
<artifactId>email-service</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>
REST Controller Class
Create below REST Controller class to handle client’s request/response.
Here we have published some REST endpoints to use email-service and user-service.
package com.roytuts.web.service.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.roytuts.email.service.EmailService;
import com.roytuts.user.service.UserService;
import com.roytuts.user.service.model.User;
@RestController
public class WebRestController {
@Autowired
private EmailService emailService;
@Autowired
private UserService userService;
@GetMapping("user/{id}")
public User getUser(@PathVariable int id) {
return userService.getUserById(id);
}
@PostMapping("user/")
public ResponseEntity<String> sendEmail(@RequestBody User user) {
userService.sendEmail(user);
return new ResponseEntity<>("Email Successfully sent", HttpStatus.OK);
}
@PostMapping("email/{toAddress}")
public ResponseEntity<Void> sendEmail(@PathVariable String toAddress) {
emailService.sendEmail(toAddress);
return new ResponseEntity<Void>(HttpStatus.OK);
}
}
Main Class
Create below main class to deploy spring boot multi-module project as a whole.
package com.roytuts.web.service.app;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication(scanBasePackages = "com.roytuts")
public class WebServiceApp {
public static void main(String[] args) {
SpringApplication.run(WebServiceApp.class, args);
}
}
Testing the Application
Now run the above main class in web-service module, the email-service and user-service module will be deployed also.
You can now hit below URLs in REST client or Postman to test the services:
Request Method: GET
URL: http://localhost:8080/user/1000
Response
{
"id": 1000,
"firstName": "Soumitra",
"lastName": "Roy",
"email": "contact@roytuts.com"
}
Request Method: POST
URL: http://localhost:8080/user/
Headers: Content-Type : application/json
Body
{"id":1000,"firstName":"Soumitra","lastName":"Roy","email":"contact@roytuts.com"}
Response: Email Successfully sent
Request Method: POST
URL: http://localhost:8080/email/contact@roytuts.com
Response Headers: Status : 200
That’s all. You have successfully built the spring boot multi-module project.
Source Code
Thanks for reading.
Can i add my email-service jar & user-service jar in another spring starter project . If yes please help with the process.
Very neatly explained the multi module spring boot configuration. If we have a angular as a dependency we just add one more module. But we want this module to be compiled based on profile as its time consuming to build angular everytime. Is this possible in maven ?
Hi,
First of all thank for your tutorial.
I have questions, I haveto access to a database, and I want to deploy the three module as a one monolithic application.
– The starter should be only in the main module, webservice ?
– the application.properties for the database access should be in the Dao module or with the starter in the main module ?
-should I create a configuration class in each module to declare the scanned packages, enabled configurations ? how to regroup all the class confgurations in a one class.
thank you in advance
So you want to create only one main class for webservice module then you create configuration class in that module. You don’t need to create any configuration class in other module as the other module will be used as dependent module.
Sorry the post is really misleading :(
You had the small amount of time to create a better example…
(Web) Service (MicroService) means an application to allow machine-to-machine communication.
Sorry but your code and your description does not resolve the problem – just another multi module project with with app and 2 libs
To solve the project – email and user service have to provide a transport interface like http and mq that is getting called by web service. In this case you have to define a client to provide the web service a consuming functionallity….
Just remove email dependency from user and user dependency from web and deploy all 3 modules seprately…
Challenge failed :( pity
The name “spring-microservice” is misleading but this project is multi-module project nothing else.
I tried removing the dependency of email service from user service and create a new method in email service, that gets directly called from web service. Even then I had to use to port configured in user service to call it. Why is that so? Why only port configured in user service works? Is this coded somewhere?
you can download and run the project.
Is the source code available for download. If so, what is the download link
At the end you will find download link.
Hi….
Do you really think…”email service” and “user Service” will get called from individually deployed instance ?
Here, you are using other 2 modules as a dependency, not as service…..
Regards,
Radhakanta Ghosh
do you think that this is a real application you would use? this is just an example on usage of multi module projects, nothing else.
Very good article. Can you tell me how to deploy them individually
If you want to deploy individually then you have to create main class for individual module and start each main class.
Thanks for your reply. This article was really helpful. I have few questions related to the above deployment. Can you help me ?
please share your contact detail to javaknight.era@gmail.com