How to configure multi module spring application - maven

Here is my project structure :
I have two spring-boot modules. In auth module I implement spring security. And I have Auth controller that allows us to sign up and sign in(returns jwt token).
In account-management module I want to get user profile and I should use auth module. I should have different databases.
Here is my parent pom :
<groupId>com.social.network</groupId>
<artifactId>social-network</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>social-network-auth</module>
<module>social-network-account-management</module>
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
Here is auth module's pom :
<groupId>com.social.network.auth</groupId>
<artifactId>social-network-auth</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>social-network-auth</name>
<description>Authentication module for SocialNetwork</description>
<parent>
<groupId>com.social.network</groupId>
<artifactId>social-network</artifactId>
<version>1.0-SNAPSHOT</version>
<!--<relativePath>../pom.xml</relativePath>-->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<jwt.version>0.6.0</jwt.version>
<swagger.version>2.7.0</swagger.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
And here is my account-management's pom
<groupId>com.social.network.account.management</groupId>
<artifactId>social-network-account-management</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>social-network-account-management</name>
<description>Account management module for SocialNetwork</description>
<parent>
<groupId>com.social.network</groupId>
<artifactId>social-network</artifactId>
<version>1.0-SNAPSHOT</version>
<!--<relativePath>../pom.xml</relativePath>-->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>com.social.network.auth</groupId>
<artifactId>social-network-auth</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
I want to run all my modules.
But build fails. I am getting Failed to execute goal org.apache.maven.plugins:maven-deploy-plugin:2.8.2:deploy (default-deploy) on project egs-social-network: Deployment failed: repository element was not specified in the POM inside distributionManagement element or in -DaltDeploymentRepository=id::layout::url parameter -> [Help 1]

First of all you should understand that two different application could not be running on the same port. So you thought in the right way, but the main goal is to separate logical parts to different modules, my congatulations, you have already done it. So now, just make the right dependency chain. (child -> parent!) And also the child module could not be a spring boot application. It could be some kind of additional sets of classes or library for your main module. And please read the answer How to make one module depend on another module artifact?. You can have multiply controllers in one application, but with different mappings, you don't need for this purposes two different applications.
By the way, first off all please run mvn package and install =)

You have to call
mvn spring-boot:run
in each module to run the applications.
You find the goal under "Plugins".
But as you are using IntelliJ there is a Spring Boot Run Dashboard where you can run all applications.

Related

Create EAR Project With SpringBoot module

I need to create an EAR file to be deployed on JBoss EAP 7. I considered to build a project structure like the following:
- rootproject
-- ear (ear)
-- web (war)
Therefore for the rootproject I have created a new Simple Maven project (using Eclipse 06/2020), with the following .pom.xml:
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>jboss_test</groupId>
<artifactId>jboss_test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>jboss_ear_test</name>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.11.RELEASE</version>
</parent>
<profiles>
<profile>
<id>default</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<modules>
<module>ear</module>
<module>web</module>
</modules>
</profile>
</profiles>
</project>
Therefore, inside it, I have created a SpringBoot 2.2.11 project (WEB) with the following .pom.xml:
....
....
<parent>
<artifactId>jboss_test</artifactId>
<groupId>jboss_test</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>web</artifactId>
<packaging>war</packaging>
<name>web-test</name>
<description>Spring Boot JBOSS</description>
.... // some dependencies
And a Maven module used the ear with the following .pom.xml:
....
....
<parent>
<artifactId>jboss_test</artifactId>
<groupId>jboss_test</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>ear</artifactId>
<packaging>ear</packaging>
<name>ear-test</name>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-ear-plugin</artifactId>
<version>2.6</version>
<configuration>
<finalName>JBOSS-TEST_EAR</finalName>
<version>6</version>
<defaultLibBundleDir>lib</defaultLibBundleDir>
<modules>
<webModule>
<groupId>jboss_test</groupId>
<artifactId>web</artifactId>
<bundleFileName>JBOSS-TEST.war</bundleFileName>
<contextRoot>/TEST</contextRoot>
</webModule>
</modules>
</configuration>
</plugin>
</plugins>
</build>
When I try to build the project from its root I obtain the following error:
Artifact[war:jboss_test:web] is not a dependency of the project
Can you help me to find out whats wrong??
Thank you
Thanks a lot to #khmarbaise for his response, I solved as follows:
Creating rootproject as Simple Maven project, .pom.xml:
<groupId>it.coding.jboss.deployment</groupId>
<artifactId>jbdeployment</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.11.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<modules>
<module>ear-test</module>
<module>web-test</module>
</modules>
Creating ear-test as Maven module, .pom.xml:
<parent>
<groupId>it.coding.jboss.deployment</groupId>
<artifactId>jbdeployment</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>ear-test</artifactId>
<packaging>ear</packaging>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-ear-plugin</artifactId>
<version>2.6</version>
<configuration>
<finalName>TEST-EAR</finalName>
<version>6</version>
<defaultLibBundleDir>lib</defaultLibBundleDir>
<modules>
<webModule>
<groupId>it.coding.jboss.deployment</groupId>
<artifactId>web-test</artifactId>
<bundleFileName>WEB-TEST.war</bundleFileName>
<contextRoot>/WEB-TEST</contextRoot>
</webModule>
</modules>
<archive>
<addMavenDescriptor>false</addMavenDescriptor>
<manifestEntries>
<Implementation-Title>JBOSS-TEST</Implementation-Title>
<Implementation-Version>1.0</Implementation-Version>
<Implementation-Vendor>CODING</Implementation-Vendor>
<Built-By></Built-By>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>it.coding.jboss.deployment</groupId>
<artifactId>web-test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<type>war</type>
</dependency>
</dependencies>
Creating web-test as SpringBoot 2.2.11 project, .pom.xml:
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>it.coding.jboss.deployment</groupId>
<artifactId>jbdeployment</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>web-test</artifactId>
<packaging>war</packaging>
<name>web-test</name>
<description>Spring Boot JBOSS</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
// dependencies
</dependencies>
...
...
</project>
Maven build goes fine and EAR is created.. Than I would like to ask one more thing: do you think I have to define all the dependecies inside my ear-test pom?? Also those of the web-test project related to Spring, Hibernate etc.. ?
Thanks a lot

Why does a maven plugin work even if it's only defined in the pluginManagement section of the parent POM?

If I define a parent POM like this:
<project ...>
<groupId>com.example</groupId>
<artifactId>parent-test</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.5.6.RELEASE</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
And a project POM like this:
<project ...>
<groupId>com.example</groupId>
<artifactId>parent-test-project</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>com.example</groupId>
<artifactId>parent-test</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
</project>
The goal spring-boot:help, among others, are available from the parent-test-project root directory. Why doesn't the plugin need to be included in a <plugins> block in the project to use the plugin? Even the spring docs suggest that this should be necessary.
Same result with another plugin: https://codehaus-cargo.github.io/cargo/Maven2+Plugin+Installation.html
Related, but seems different since I'm asking about running a goal directly, as opposed to binding to a lifecycle phase: "Implicit" plugins - why does a Maven build run tests via surefire even if it is not mentioned in the POM?

spring boot multi modules package

I am trying to use Maven to package Spring Boot with multi modules,Here my main module pom.xml :
<modules>
<module>my-data-services</module>
<module>my-message-services</module>
<module>my-common</module>
</modules>
<groupId>com.my</groupId>
<artifactId>my-multi-services</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.2.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencyManagement>....</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
my-common pom.xml:
<parent>
<artifactId>my-multi-services</artifactId>
<groupId>com.my</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>my-common</artifactId>
<packaging>jar</packaging>
<dependencies>....</dependencies>
and my-data-services pom.xml:
<parent>
<artifactId>my-multi-services</artifactId>
<groupId>com.my</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>my-data-services</artifactId>
<dependencies>
<dependency>
<groupId>com.my</groupId>
<artifactId>my-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
my-common module is just a common utils lib not a runnable module,but when i trying to mvn clean package,exception throws below:
Execution default of goal org.springframework.boot:spring-boot-maven-p
lugin:1.4.2.RELEASE:repackage failed: Unable to find main class
then i add a main class,this module can package,but its not a lib jar, its like a runnable spring boot jar
-BOOT-INF
|
-META-INF
|
-org
and the exception throws
Failed to execute goal org.apache.maven.plugins:maven-compiler- plugin:3.1:compile (default-compile) on project my-data-services: Compilation failure: Compilation failure: package com.my.common.utils does not exist;
com.my.common.utils is in module my-common
How do i fix this problem, and in spring boot multi modules project,how to package a common utils lib without BOOT-INF
This happens because your modules will have the 'spring-boot-maven-plugin' added to them because it's defined in their parent.
What you need to do is move everything into submodules, even your application starter class. How I do this usually:
my-parent-module
my-service-module
my-common-module
my-web-module (or my-runtime-module in a non-web app)
The my-parent-module will have 'spring-boot-starter-parent' as it's parent but it not going to have an src folder because everything is moved into submodules.
The my-web-module will depend on the other modules and will have the 'spring-boot-maven-plugin'. You will be able to run the app with 'mvn spring-boot:run' in the my-web-module folder.

Get war module when running the parent maven project

Is there a way to run a war module automatically when I run the parent project?
To make it clear, I did three separate maven project (db, core and presentation), then I made a parent project which include the 3 projects mentioned before.
I'd like to get the presentation module running when I run the parent project.
Also, I want to know if it's possible to save the hole work from the parent project to my git account.
<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.project.xxxxxxx</groupId>
<artifactId>parent-project</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>parent-project</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<targetJdk>1.7</targetJdk>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.0</version>
<configuration>
<port>8080</port>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${targetJdk}</source>
<target>${targetJdk}</target>
<showDeprecation>true</showDeprecation>
</configuration>
</plugin>
</plugins>
</build>
<modules>
<module>../project-db</module>
<module>../project-core</module>
<module>../project-presentation</module>
</modules>
<dependencies>
</dependencies>
</project>
You need to specify the sub-project under tag.
You may refer http://books.sonatype.com/mvnex-book/reference/multimodule-sect-simple-parent.html for example
Your modules should be unter your parent in the file structure. Like
parent-project
pom.xml
project-db
pom.xml
project-core
pom.xml
project-presentation
pom.xml
Then you have to change the parent pom:
<modules>
<module>project-db</module>
<module>project-core</module>
<module>project-presentation</module>
</modules>

Dependency management does not work for multi-module project

I have a Maven project with multiple modules and I'm trying to set it up so that module dependencies are automatically built to the correct lifecycle phase needed for building depending modules to the requested lifecycle phase.
In the example, the module plugin builds a Maven plugin, which is used to generate source code and is used by the module main. If I just try to use mvn -am -pl main compile, the module plugin is compiled but the process-classes lifecycle phase is not executed (which is necessary for a plugin to be usable). Compiling the module main then fails then with the following error:
[ERROR] Failed to parse plugin descriptor for example:plugin:1.0.0-SNAPSHOT (/Users/ims/Dropbox/IMS/Projects/PARITy_R4/codegen-test-simple/plugin/target/classes): No plugin descriptor found at META-INF/maven/plugin.xml -> [Help 1]
Is Maven, or a plugin for it, capable of resolving the dependencies of modules in a multi-module project and build them to stage necessary by other modules? And if so, how do I need to set up the project for this to work?
These are the POMs of my project:
pom.xml:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<groupId>example</groupId>
<artifactId>project</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>plugin</module>
<module>main</module>
</modules>
</project>
plugin/pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<groupId>example</groupId>
<artifactId>plugin</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>maven-plugin</packaging>
<parent>
<groupId>example</groupId>
<artifactId>project</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-annotations</artifactId>
<version>3.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-plugin-plugin</artifactId>
<version>3.2</version>
<configuration>
<goalPrefix>configurator</goalPrefix>
</configuration>
<executions>
<execution>
<id>default-descriptor</id>
<goals>
<goal>descriptor</goal>
</goals>
<phase>process-classes</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
main/pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<groupId>example</groupId>
<artifactId>main</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>jar</packaging>
<parent>
<groupId>example</groupId>
<artifactId>project</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<build>
<plugins>
<plugin>
<groupId>example</groupId>
<artifactId>plugin</artifactId>
<version>1.0.0-SNAPSHOT</version>
<executions>
<execution>
<goals>
<goal>codegen</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
If you look at the reference documentation for the Maven lifecycle, you'll see that compile is before process-classes.
If you want this step to happen, you need to use mvn -am -pl main process-classes instead.
But I suggest that you always use mvn ... install - it also runs the tests and makes sure that the plugin which main uses is actually the one you think it should: Without install, the build will use an old/outdated version from the local repository (Maven will not magically determine "oh, there is a plugin in my reactor, I'll use that instead of the version from the local repo").

Resources