Maven - Add a maven module as dependency to other maven module - spring

I have 2 Spring boot maven projects(module A, Module B). And they both are added as modules to a parent project. Both Modules have some common dependencies and java classes(Domain objects), so I created third module Module C, and placed all the common java files and dependencies there.
I added the Module C to parent pom as one of the module. And added Module C as dependency to Module A and Module B. In Module A, B wherever the classes of Module C is referred there it was resolved and is pointing to Module C Classes (on ctrl+click).No error was shown in eclipse and maven dependencies are updated. But when I build the projects either from Parent pom or build Module A alone (after building the module c), I get cannot find symbol error in the places where module C classes were referenced.
Below are my pom.xml's
Parent 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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example.services</groupId>
<artifactId>cloud-services</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>ModuleC</module> <!-- Project where common dependencies and Common java classes are placed -->
<module>ModuleA</module>
<module>ModuleB</module>
</modules>
</project>
Module C Pom.xml - Common Project
<?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.example.services</groupId>
<artifactId>cloud-services</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>ModuleC</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>ModuleC</name>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR3</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencyManagement>
</project>
Module A Pom.xml - Dependent Project on Module C
<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>
<parent>
<groupId>com.example.services</groupId>
<artifactId>cloud-services</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>ModuleA</artifactId>
<dependencies>
<!-- Project where common dependencies and Common java classes are placed -->
<dependency>
<groupId>com.example.services</groupId>
<artifactId>ModuleC</artifactId>
<scope>compile</scope>
</dependency>
</dependencies>
</project>
Module B Pom.xml
Same as ModuleA.
Whats wrong with my configuration. Any help is much appreciated. Thanks.

If its a spring project the root folder of the jar would be BOOT-INF.
If you create a normal project jar it wouldn't be having BOOT-INF.
The way it works is if you have a Project A and it has dependency on x.jar
Say Project A needs com.x.y.ClassA.class from x.jar it will search in root folder of x.jar with this path x/y/ClassA.class.
In your case as it was a spring project the resolution didnt work and it was complaining about that.

I guess that the spring-boot-starter-parent is the culprit.
By using it as a parent POM to your parent POM, you are building all your modules with it. AFAIK, jars build with spring-boot-starter-parent cannot be used as dependencies because the classes are moved to a different directory inside the jar.
As I am not Spring expert, I cannot really offer you a good solution for this.

Related

How to find the source for an artifact version in Maven?

Assuming I have Maven pom (let's say Maven 3.8) like this:
<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>
<parent>
<groupId>some.group</groupId>
<artifactId>my-parent</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>my-app</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>some.group</groupId>
<artifactId>my-artifact</artifactId>
</dependency>
</dependencies>
</project>
...where my-parent has a dependency management section, maybe bom imports and further parents up the chain with it's own dependency management sections, how can I find the source of the version of some.group:my-artifact that actually used in the child pom?
Let's say, I build this and see that the effective pom contains version 1.2.3 for this artifact, how can I find out the pom that actually contains that version?

I found mvn dependency transitive not work, why it happened?

my project A import a dependency jar B, and B import dependency jar C.they all use compile scope.
when I use "mvn dependency:tree" command to show all the dependencies, I could not found
the jar C in my project. And i also could not saw any jar C in my IDE External Libraries.
Is there some special mechanism in mvn?
I display the code below.
1、project A dependency gfintertrade-common-service-nearby
<parent>
<groupId>com.alipay.findataprod.service</groupId>
<artifactId>findataprod-parent</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.alipay.findataprod.service</groupId>
<artifactId>findataprod-biz-service-impl</artifactId>
<version>1.0-SNAPSHOT</version>
<name>Alipay findataprod-biz-service-impl</name>
<description>Alipay findataprod</description>
<url>http://home.alipay.com</url>
<packaging>jar</packaging>
<dependencies>
<!-- project depends -->
<dependency>
<groupId>com.alipay.gfintertrade</groupId>
<artifactId>gfintertrade-common-service-nearby</artifactId>
<version>1.0.0.20200930</version>
</dependency>
</dependencies>
2、gfintertrade-common-service-nearby dependency cryptprod-common-service-crypto
<parent>
<groupId>com.alipay.gfintertrade</groupId>
<artifactId>gfintertrade-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.alipay.gfintertrade</groupId>
<artifactId>gfintertrade-common-service-nearby</artifactId>
<version>1.0.0.20200930</version>
<name>Alipay gfintertrade-common-service-nearby</name>
<description>Alipay gfintertrade-common-service-nearby</description>
<url>http://home.alipay.net</url>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>com.alipay.cryptprod</groupId>
<artifactId>cryptprod-common-service-crypto</artifactId>
<version>1.2.2.20180516</version>
</dependency>
</dependencies>
3、I found project A not dependency cryptprod-common-service-crypto
gfintertrade-common-service-nearby is from remote repository

Maven pom version inheritance

I have 3 projects Parent,Child,SubChild.
Project Parent pom is as follows:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.3.RELEASE</version>
</parent>
<groupId>mu.parent</groupId>
<artifactId>parent-system</artifactId>
<version>1.0</version>
<packaging>pom</packaging>
....
Project Child pom is defined below and its Parent is defined follows:
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>mu.parent</groupId>
<artifactId>parent-system</artifactId>
<version>1.0</version>
</parent>
<groupId>mu.dummy.child</groupId>
<artifactId>child-backend</artifactId>
<name>child-backend</name>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>subChild-app</module>
</modules>
...
Now subChild pom is as follows and the child is defined as parent for subChild :
<parent>
<groupId>mu.dummy.child</groupId>
<artifactId>child-backend</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>mu.dummy.subchild</groupId>
<artifactId>subchild-backend</artifactId>
<name>subchild-backend</name>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<dependencies>
<dependency>
<groupId>org.project.test</groupId>
<artifactId>project</artifactId>
<version></version> --version of parent-system???
</dependency>
</dependencies>
Is it possible to get version of parent-system(1.0) in subchild-backend please without hardcoding it?
You can use CI-friendly versions and write ${revision} for the versions, setting this property in the main pom (from which you build everything).
You need to use the flatten Maven plugin, though, to get proper POMs in the repository.
I asked a similar question a while back and determined that tthe groovy-maven-plugin works for this. See this answer.

Transitive dependency jars are not resolved from maven nexus repository

I created my own maven project (project 1) where I have added dependencies like junit, spring, etc. and deployed the jar (name it as jar1 ) in my nexus maven repository.
Now when I add jar1 as dependency to my new project 2, only jar1 is getting downloaded from the maven repository and the transitive dependencies such as junit ,spring are not downloaded.
pom - project1
<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>Project1</groupId>
<artifactId>Project1</artifactId>
<version>Dev.0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
pom - project2
<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>Project2</groupId>
<artifactId>Project2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>Project1</groupId>
<artifactId>Project1</artifactId>
<version>Dev.0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
As per above pom configuration, project2 should automatically resolve junit jar right?.
But project2 only resolves Project1.jar and not the junit jar. Please let know what am I missing.
Not all scopes are transitive, especially test and provided dependencies are not.
Look at the table in https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html

Custom spring boot starter for specifying distribution management

We have a spring boot application which has its parent defined as spring-boot-starter-parent. But in our project, we have a parent pom with distribution management defined in it, and all the submodules in the project inherit from it. Now, since the spring boot application already inherits from spring-boot-starter-parent, and I do not want to duplicate the distribution management, I thought of having a custom spring boot starter module just to be able to define the distribution management in there and then include this custom spring boot starter as a dependency in the spring boot application. But when I do a mvn clean install deploy of the spring boot application it fails with the error shown below:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-deploy-plugin:2.8.
2:deploy (default-deploy) on project crs-acc-eve-gridgain-load-app: Deployment f
ailed: repository element was not specified in the POM inside distributionManage
ment element or in -DaltDeploymentRepository=id::layout::url parameter -> [Help
1]
Is it the right way to achieve this? or there any other recommended ways of doing it?
Given below are the poms of custom spring boot starter parent module:
<?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">
<parent>
<artifactId>crs-micro-services</artifactId>
<groupId>com.ing.crs</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>crs-spring-boot-starter-parent</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring-boot.version>1.3.5.RELEASE</spring-boot.version>
</properties>
<modules>
<module>crs-spring-boot-starter</module>
</modules>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<distributionManagement>
<repository>
<id>XXXX</id>
<name>XXXX</name>
<url>XXXX</url>
</repository>
<snapshotRepository>
<id>XXXX</id>
<name>XXXX</name>
<url>XXXX</url>
<uniqueVersion>false</uniqueVersion>
</snapshotRepository>
</distributionManagement>
</project>
And this..for the starter module
<?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">
<parent>
<artifactId>crs-spring-boot-starter-parent</artifactId>
<groupId>com.ing.crs</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<version>1.0-SNAPSHOT</version>
<artifactId>crs-spring-boot-starter</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
</dependencies>
</project>
And the sprng boot application has this dependency
<dependency>
<groupId>com.ing.crs</groupId>
<artifactId>crs-spring-boot-starter</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>import</scope>
</dependency>
Thanks and regards,
Priya
There is no requirement that your build should be configured with the spring-boot-starter-parent. If you already have a parent with some distribution management, feel free to keep it. You'll need to adapt the parent a bit. Here are couple of options:
If the whole project is spring boot based, maybe your parent could inherit from the Spring Boot starter parent? This may not work if you have a parent that is used within the entire organization
You can keep your parent as it is and use the spring-boot-dependencies BOM instead. See the documentation for more details. You'll have to copy the bits of the parent that you use (such as the plugin definition) but it's not a ton of work.
Your proposal will never work. BOM only imports <dependencyManagement>. What you're looking for is mixin and it's not supported by Maven yet.

Resources