How to find the source for an artifact version in Maven? - 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?

Related

Download Maven artifact with version range

I need download specific Maven artifact using version range e.g.:
GroupId:org.apache.logging.log4j
ArtifactId=log4j-api
Version=[2.17.1,)
Right now I need it in one CI job.
How can I do it?
I was hoping to find an easier solution, but at least this works:
Create pom.xml file
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cz.vondr</groupId>
<artifactId>maven-dependency-download</artifactId>
<version>1.0.0</version>
<properties>
<dep.group>org.apache.commons</dep.group>
<dep.artifact>commons-lang3</dep.artifact>
<dep.version>3.12.0</dep.version>
<dep.type>jar</dep.type>
<dep.classifier></dep.classifier>
</properties>
<dependencies>
<dependency>
<groupId>${dep.group}</groupId>
<artifactId>${dep.artifact}</artifactId>
<version>${dep.version}</version>
<type>${dep.type}</type>
<classifier>${dep.classifier}</classifier>
</dependency>
</dependencies>
</project>
And then use it to download artifact using command:
mvn dependency:copy-dependencies "-DoutputDirectory=./downloaded-dependencies" -Ddep.group="org.apache.logging.log4j" -Ddep.artifact="log4j-api" -Ddep.version="[2.17.1,)"
Additional information
Basic description is here:
http://vondrnotes.blogspot.com/2022/09/download-maven-artifact-with-version.html
Working example is here:
https://github.com/bugs84/download-maven-dependency-with-version-range

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.

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

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.

How to configure/override Maven property used as parent version in dependencies?

Suppose there are two 3rd-party Maven artifacts with the following POM.XMLs:
artifact1 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">
<modelVersion>4.0.0</modelVersion>
<groupId>group1</groupId>
<artifactId>artifact1</artifactId>
<version>${artifact1.version}</version>
<packaging>pom</packaging>
<properties>
<artifact1.version>0.0.1-SNAPSHOT</artifact1.version>
</properties>
<modules>
<module>../artifact2</module>
</modules>
artifact2 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">
<modelVersion>4.0.0</modelVersion>
<artifactId>artifact2</artifactId>
<parent>
<groupId>group1</groupId>
<artifactId>artifact1</artifactId>
<version>${artifact1.version}</version>
<relativePath>../artifact1</relativePath>
</parent>
They are built normally using
mvn clean install
Now, if I try to reuse artifact2 in a 3rd 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">
<modelVersion>4.0.0</modelVersion>
<groupId>group2</groupId>
<artifactId>artifact3</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>group1</groupId>
<artifactId>artifact2</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
After executing...
mvn clean install
...the build fails trying to locate group1:artifact1:pom:${artifact1.version}
[ERROR] Failed to execute goal on project artifact3: Could not resolve dependencies for project group2:artifact3:jar:0.0.1-SNAPSHOT: Failed to collect dependencies at group1:artifact2:jar:0.0.1-SNAPSHOT: Failed to read artifact descriptor for group1:artifact2:jar:0.0.1-SNAPSHOT: Could not find artifact group1:artifact1:pom:${artifact1.version} in central (https://repo.maven.apache.org/maven2) -> [Help 1]
And setting the property in the command-line doesn't work either:
mvn clean install -Dartifact1.version=0.0.1-SNAPSHOT
How can I use artifact2 as a dependency?
<parent> doesn't allow variables. Because in order to get a list of variables Maven first has to build Effective POM and for this it needs to resolve parents.
Even if there is some version of Maven that allowed such module to be installed it's not a working solution in general. Maven's ideology is that all the dependencies (including parent) could be downloaded from a repo and are not necessarily present on local FS/in the reactor. With properties in the parent dependency definition you violate this rule.

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

Resources