Gradle not handling Maven parent POMs with version-range - gradle

I have a Gradle build that needs to fetch dependencies from a Nexus repo that has been populated using Maven. Some of the POMs there use version-ranges when specifying a parent POM.
In my build.gradle I put a dependency:
compile group: 'com.company.platform', name: 'abc-common', version: '[11.0,12.0['
The Gradle logs show that a request is made for the versions of abc-common, and its POM and its parent's POM are fetched:
abc-common-11.0.7-17042111.pom:
<parent>
<groupId>com.company.platform</groupId>
<artifactId>abc-parent</artifactId>
<version>11.0.7-17042111</version>
<relativePath>..</relativePath>
</parent>
abc-parent-11.0.7-17042111.pom:
<parent>
<groupId>com.company.corporate</groupId>
<artifactId>corporate-parent</artifactId>
<version>[11.0.7,11.0.8)</version>
<relativePath/>
</parent>
But Gradle fails to fetch the corporate-parent POM. Instead of requesting what versions are present on the repo, it tries to fetch using the version-range literal:
Loading http://nexus.company.com:8081/.../corporate-parent/[11.0.7,11.0.8)/corporate-parent-[11.0.7,11.0.8).pom
Am I doing something wrong? Is this a known problem with Gradle? Is there a work-around?
Any help is much appreciated. This is a show-stopper for me. If I can't find a solution, it's back to Maven.

Related

Arquillian ShrinkWrap cannot find parent with dynamic version

The POM of a submodule starts like that
<project>
<parent>
<groupId>mygroup</groupId>
<artifactId>mygroup-parent</artifactId>
<version>${revision}</version>
</parent>
The property revision is defined in the parents` POM. For Maven this is no Problem, but ShrinkWrap does not read the Project from bottom up.
When i try to find the dependencies with
Maven
.configureResolver()
.workOffline()
.useLegacyLocalRepo(true)
.withMavenCentralRepo(false)
.fromFile(getSettingsFile())
.loadPomFromFile("pom.xml")
.resolve()
.withTransitivity();
it fails with
Could not find artifact mygroup:mygroup-parent:pom:${revision}
Because the revision property is only known in the main module-pom.
Is there a way to point it first to the main pom or to set the property in any otherway?

Invalid spring-boot-dependency version when using jgitver and local repo in maven

When I use spring-boot-starter-parent combined with local repository and jgitver I get the following error:
[ERROR] The project tmplsvcpkg:TMPL_SVC_NAME-parent:0.0.0-27-a592e4fb-feature_gitlabci-dirty (/home/user/git/service-template/pom.xml) has 1 error
[ERROR] Non-resolvable parent POM for org.springframework.boot:spring-boot-starter-parent:[unknown-version]: Could not find artifact org.springframework.boot:spring-boot-dependencies:pom:0.0.0-27-a592e4fb-feature_gitlabci-dirty in internal-repository (https://mvnrepo) # org.springframework.boot:spring-boot-starter-parent:[unknown-version], /home/user/git/service-template/.m2/repository/org/springframework/boot/spring-boot-starter-parent/2.2.0.RELEASE/spring-boot-starter-parent-2.2.0.RELEASE.pom, line 3, column 11 -> [Help 2]
Note unknown-version for spring-boot-starter-parent and 0.0.0-27-a592e4fb-feature_gitlabci-dirty for spring-boot-dependencies. The 0.0.0-27-... version is the version calculated by the jgitver. It looks like the version resolution gets messed up somehow. If I change the local repository to any directory outside of my project it starts working again. If I supress jgitver it starts working again. If I define the local repo even deeper in my project (like maven.repo.local=x/y/z/.m2/repository, the error is still present.
I defined the parent in my pom.xml in this way:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.0.RELEASE</version>
</parent>
And I run my maven in this way:
mvn compile -Dmaven.repo.local=.m2/repository -U
If I add jgitver.skip=true, everything works.
I suspect it might have something to do with the fact that spring-boot-starter parent defines it's parent (spring-boot-dependencies) as relative to it's position:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.2.0.RELEASE</version>
<relativePath>../../spring-boot-dependencies</relativePath>
</parent>
Has anyone any ideas why it might be happening and how to fix it?
It turns out it's a well known issue and is resolved by a certain configuration of the plugin (you have to exclude the .m2 directory in plugin config). More details are in this issue:
https://github.com/jgitver/jgitver-maven-plugin/issues/60

Maven fails to download parent pom because it appends wrong version?

When maven tries to build a project that includes dependency A, it fails because it can't find the correct version of the parent pom P.
Note that in this case, the child pom A is a different version from the parent. What I see in the logs is that it is trying to download the parent pom, but with the wrong version.
Child pom:
<parent>
<artifactId>foo-parent</artifactId>
<groupId>org.foo</groupId>
<version>3.0.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>foo-bar</artifactId>
<version>3.0.1</version>
In the logs, the build then shows:
Failed to collect dependencies at org.foo:foo-bar:jar:3.0.1: Failed to read artifact descriptor for org.foo:foo-bar:jar:3.0.1: Could not find artifact org.foo:foo-parent:pom:3.0.1 in nexus
I would've expected it to look for the pom of 3.0.0, not 3.0.1, which does exist in the remote (nexus).

Maven "conditional" parent POM?

What's the best structure for a (multi-module) Maven project which should build "in the wild" without any Maven repository manager and can easily build within my organization where deployments should happen to my Maven repository manager?
Ideally, I would have two different paren POMs for each situation.
But unfortunately, I can't use a Maven property to pass the correct value for each situation, because the property expression in the parent POM reference doesn't get interpolated, if I try something like
<parent>
<groupId>org.example</groupId>
<artifactId>${root.pom}</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath/>
</parent>
...
<properties>
<root.pom>wild-parent</root.pom>
</properties>
Added a minimalistic project which shows a crude approach to solve this by patching the parent POM via sed.
This response on the maven-users mailing list pointed me in the direction to use Maven properties to pass in the in-house specifics.
I updated the example project.

What does the parent tag in Maven pom represent?

E.g.:
<parent>
<groupId>mycompany.trade.com</groupId>
<artifactId>mycompany.trade.</artifactId>
<version>1.1.1.0-SNAPSHOT</version>
</parent>
Does it mean that Maven will search for parent pom?
If yes, where, in which order? May be in folder up 1 level? Or in local repository or in repo?
Yes, maven reads the parent POM from your local repository (or proxies like nexus) and creates an 'effective POM' by merging the information from parent and module POM.
See also Introduction to the POM
One reason to use a parent is that you have a central place to store information about versions
of artifacts, compiler-settings etc. that should be used in all modules.
The common dependencies,Properties,constants etc can be definded in central parent project pom.xml
The main important thing is the parent project cannot be distributed and it looks quite similar to a regular "pom.xml" except that it also has a packaging tag
<groupId>com.company.demo</groupId>
<artifactId>MavenInheritance</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
The child now able to inherit this using
<parent>
<groupId>com.company.demo</groupId>
<artifactId>MavenInheritance</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
As the name suggests, we can point out a parent pom.xml file for the current pom.xml file. Doing so, dependencies, properties, constants and many more defined at the parent pom.xml file also get merged with the current pom.xml (child pom.xml) file. Say you have a parent tag in your projects pom.xml that looks like below:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.8.RELEASE</version>
</parent>
Then maven reads that parent POM from your local repository (or from repository managers like sonatype, jfrog, etc that you have configured) and creates a Resultant POM by combining the parent POM and your module’s POM.
To see the combined result use the following mvn command:
mvn help:effective-pom
This is the practice that is used in multi-modules projects where we need to inherit the dependencies from the parent projects.

Resources