Maven settings.xml property is not resolved in transitive dependency - maven

I have a property in settings.xml,
fwk.version = "2.0.001"
Other side, a multiproject with two projects, earmodule and ejbmodule.
ejbmodule has a dependency:
<dependency>
<groupId>shared-lib</groupId>
<artifactId>proxi2.fwk.comuns</artifactId>
<version>${fwk.version}</version>
<type>pom</type>
</dependency>
and it's works correctly
but earmodule has a dependency on ejbmodule
<dependencies>
<dependency>
<groupId>projectGroup</groupId>
<artifactId>ejbmodule</artifactId>
<version>1.0</version>
<type>ejb</type>
</dependency>
</dependencies>
and it tries to solve the dependency and it fails:
[WARNING] Missing POM for shared-lib:proxi2.fwk.comuns:pom:${fwk.version}
instead trying to download
shared-lib:proxi2.fwk.comuns:pom:2.0.001
It happens when i try to package parent project.
Looks like a bug in Maven3
Do you know why?
Thx
EDIT:
Our solution/workaround has been defining in parent pom a dependencyManagement section because in this level works ok.
Then in subproject ejbmodule, we have an "independent version" dependency because uses parent definition in dependencyManagement
settings.xml:
<fwk.version>2.0.001</fwk.version>
parent pom:
<dependencyManagement>
<dependency>
<groupId>shared-lib</groupId>
<artifactId>proxi2.fwk.comuns</artifactId>
<version>${fwk.version}</version>
<type>pom</type>
</dependency>
</dependencyManagement>
ejbmodule pom:
<dependency>
<groupId>shared-lib</groupId>
<artifactId>proxi2.fwk.comuns</artifactId>
<type>pom</type>
</dependency>
I hope this would help other

Looks like there is an open maven bug related to this.

I see a similar problem only in a different situation. I used a property to define a URL where to send my created javadocs like this
<distributionManagement>
<site>
<id>javadocs</id>
<name>Java Documentation</name>
<url>scp://${javadocs.url}/${project.groupId}/${project.artifactId}/${project.version}</url>
</site>
</distributionManagement>
And of course I set the property in my settings.xml in a profile
</settings>
.
.
<profiles>
<profile>
<id>develop</id>
<properties>
<environment.type>develop</environment.type>
<javadocs.url>javadocs.server.com/home/javadocs/javadocs</javadocs.url>
</properties>
.
.
<activeProfiles>
<activeProfile>develop</activeProfile>
</activeProfiles>
</settings>
The distributionManagement section was put into the pom of project parent which was used as parent in the project child
When doing
mvn site-deploy
in the child project I got this error:
[ERROR] Failed to execute goal
org.apache.maven.plugins:maven-site-plugin:3.0:deploy (default-deploy)
on project child: Error uploading site: Cannot connect. Reason:
java.net.UnknownHostException: ${javadocs.url} -> [Help 1]
So clearly the property was not set anymore.
The only workaround I can think of is to put the properties in the parent pom. I know this is terrible because if you want to change them you need to redeploy.

Following the fact that this issue seems due a bug of Maven and it is apparently not expected to be fixed soon, I have found a simple workaround that seems work for me.
Instead that defining a variable with dot notation like fwk.version, try a snake case like fwk_version. I tried it tp define in my settings.xml url of repositories and it works.
Reference: I found this from this post http://maven.40175.n5.nabble.com/Settings-properties-not-resolved-when-used-in-repository-element-td5746974.html
I hope it can help also in transitive dependencies.

Related

Are Maven repository declarations transitive?

Suppose I have the following project, a library which declares some 3rd party repository that it needs to use to grab an artifact.
<project ...>
<groupId>com.mygroup</groupId>
<artifactId>library</artifactId>
<version>1.0.0</version>
<repositories>
<repository>
<id>some-id</id>
<url>https://some.repo.com</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>com.thirdparty</groupId>
<artifactId>used-at-compile-time</artifactId> <!-- like Lombok, say -->
<version>1.0.0</version>
<scope>provided</scope> <!-- so, not transitive -->
</dependency>
</dependencies>
</project>
Then I have a totally separate project which depends upon that library
<project ...>
<groupId>com.mygroup</groupId>
<artifactId>some-app</artifactId>
<version>2.0.0</version>
<dependencies>
<dependency>
<groupId>com.mygroup</groupId>
<artifactId>library</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
</project>
Does Maven try to include the repository definition in all dependent projects? Will some-app ever try to access https://some.repo.com?
I'd always been under the impression that this didn't happen, but I've started seeing build failures which contract that belief.
It might initially seem convenient if that's how it worked, but what if the repo was internal and was not publicly accessible over the internet? The project which declared it might use it for some compile-time dependencies, like in my example above. If that repo were dragged in, the dependent project might try to access a repository that it can't for some other non-Maven Central dependencies.
So I can see valid reasons for either behaviour, but as far as I can see, the documentation for repositories doesn't say one way or another what happens, and neither does the POM reference.
Repositories are context aware, in the context of their pom. Dependencies from com.mygroup:library can use the repo's central and some-id.
On the other hand, dependencies from com.mygroup:some-app will only use central.
When running Maven from the commandline, you'll see the repositories it'll try to download the artifacts from (in case the first one fails, it'll go for the next).
When publishing to Central, there are several requirements. However, based on the last paragraph repositories are not banned, you're advised not to use them.
You might wan't to read this classic article: Why Putting Repositories in your POMs is a Bad Idea

Maven copy parents declared in the POMs

My final goal is to create a Maven repository in a certain directory containing only a certain set of artifacts and all their dependencies.
For this I use the following command:
mvn.bat dependency:copy-dependencies -f dependencies.pom
-DoutputDirectory=localRepoDir -Dmdep.useRepositoryLayout=true
-Dmdep.copyPom=true -Dmdep.addParentPoms=true
dependencies.pom being:
<project>
<modelVersion>4.0.0</modelVersion>
<description>Dependencies</description>
<groupId>com.dummy</groupId>
<artifactId>dummy</artifactId>
<version>1.0.0</version>
<dependencies>
<dependency>
<groupId>com.dependency1</groupId>
<artifactId>dep1</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.dependency2</groupId>
<artifactId>dep2</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
</project>
When doing this, I notice that parents declared in the dependencies' poms are not copied from the .m2 Local maven repository to the destination directory.
Perhaps I'm missing something and there's a better way to do this, since it's kind of a hack to use a pom file to declare the artifacts I want to copy (together with their dependencies).
Turns out that maven was using version 2.8 as default for the dependency plugin. When explicitly indicating it to use the latest version (2.10), it worked just fine.
The addParentPoms parameter was already introduced on 2.8 for copy-dependencies, so I guess it must be a bug in the 2.8 release.
mvn org.apache.maven.plugins:maven-dependency-plugin:2.10:copy-dependencies

Maven plugin dependency cannot use parent pom property

I'm hitting a weird edge use case with Maven & curious why it's behaving the way it does.
I'm defining a property in my parent project like so:
<properties>
<some.property.version>1.0.0.0</some.property.version>
</properties>
Now, in a module, I set a version of a dependency for a plugin like so:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>bob</artifactId>
<version>1.0.0.0</version>
<dependencies>
<dependency>
<groupId>org.example</groupId>
<artifactId>example</artifactId>
<version>${some.property.version}</artifactId>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
This causes Maven to spit out an error:
[ERROR] 'build.plugins.plugin[org.apache.maven.plugins:bob].dependencies.dependency.version' for org.example:example:jar must be a valid version but is '${some.property.version}'. # line 350, column 16
What's bizarre to me is if I move the property being defined down into the module itself, Maven compiles just fine. Is this a bug? Or are there restrictions of visibility to parent pom properties in a plugin for a module?
An insanely fast response from the Apache Maven's distribution list! The parent pom had been refactored, and the module was pointing to the stale parent's artifactId. Kudos to Robert!
Hi,
This makes me wonder if the "right" parent is used, so please double
check the groupId, artifactId and version. If both parent and module
are part of the same multi-module, be sure that the relativePath is
correct (defaults to ../pom.xml) You could also use "mvn
org.apache.maven.plugins:maven-help-plugin:2.2:effective-pom" to
verify that the property is really there with the expected value. If
this is all as expected, then it seems to be a bug.
thanks, Robert

Gradle cannot resolve dependency

In my build.gradle file I have a line in dependencies:
compile group: 'org.jboss.seam.validation', name: 'seam-validation-api', version:'3.1.0.Final'
When I try to run the project, e.g. 'test' task, I get an error:
> Could not resolve org.jboss.seam.validation:seam-validation-api:3.1.0.Final.
Required by:
com.smspl.mc5:mc5-web-ui:1.0.0-SNAPSHOT
com.smspl.mc5:mc5-web-ui:1.0.0-SNAPSHOT > com.smspl.mc5:mc5-common-rest:1.0.0-SNAPSHOT
> Could not parse POM /Users/amorfis/.m2/repository/org/jboss/seam/validation/seam-validation-api/3.1.0.Final/seam-validation-api-3.1.0.Final.pom
> Unable to resolve version for dependency 'javax.enterprise:cdi-api:jar'
> Could not parse POM https://nexus.softwaremill.com/content/groups/smlcommon-repos/org/jboss/seam/validation/seam-validation-api/3.1.0.Final/seam-validation-api-3.1.0.Final.pom
> Unable to resolve version for dependency 'javax.enterprise:cdi-api:jar'
I'm aware that the problem is that version of 'javax.enterprise:cdi-api:jar' is not specified in the seam-validation-api pom. It is specified in it's parent, and gradle probably has some problems figuring it out. The parent part of seam-validation-api pom looks like this:
<parent>
<groupId>org.jboss.seam.validation</groupId>
<artifactId>seam-validation-parent</artifactId>
<version>3.1.0.Final</version>
<relativePath>../pom.xml</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>javax.enterprise</groupId>
<artifactId>cdi-api</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
My gut feeling tells me the problem is in part. I also tried to add this parent dependency explicitely, by adding new line to build.gradle 'dependencies', but without any luck.
Anyone knows solution to this?
UPDATE: In the parent pom:
<groupId>org.jboss.seam.validation</groupId>
<artifactId>seam-validation-parent</artifactId>
<packaging>pom</packaging>
<version>3.1.0.Final</version>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.jboss.seam</groupId>
<artifactId>seam-bom</artifactId>
<version>${seam.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Here is a little research of the problem (only research, NOT a solution):
seam-validation-api-3.1.0.Final.pom has parent seam-validation-parent-3.1.0.Final.pom
seam-validation-parent-3.1.0.Final.pom has parent seam-parent-19.pom
The file seam-parent-4.pom contained version definition for cdi-api, but seam-parent-19.pom does not.
The file seam-validation-parent-3.0.0.Final.pom did contain dependencyManagement for cdi-api, but newer version seam-validation-parent-3.1.0.Final.pom does not.
I also looked into the code of GradlePomModuleDescriptorBuilder (the class that throws the abovementioned "Could not resolve..." exception). It seems that the class looks for DependencyManagement sections up the parent-pom chain, but it does not respect resolutionStrategy (or any other definitions from gradle script). So currently it is not possible to augment/override dependencyManagement of POM.
My advice: contact the developer(s) of seam framework and ask them to fix the dependencies.

How to generate Javadoc for Maven Dependencies

I have a maven project with the following POM snippet:
<modelVersion>4.0.0</modelVersion>
<artifactId>Foo-Deploy</artifactId>
<name>Foo-Deploy</name>
<packaging>pom</packaging>
<description>foobar</description>
<dependencies>
<dependency>
<groupId>de.foo.bar</groupId>
<artifactId>some-api</artifactId>
<version>${project.version}</version>
<classifier>doc</classifier>
<type>zip</type>
</dependency>
</dependencies>
The idea is to have a dependency defined in which some sources are (this is created successfully before).
Now I want to run javadoc on exactly THIS dependency. When I call
mvn javadoc:jar -DincludeDependencySources=true -DdependencySourceIncludes=de.foo.bar:some-api:*:doc:zip
it fails with the message
Not executing Javadoc as the project
is not a Java classpath-capable
package
what is wrong ? and would it work anyhow ?
or how can I generate javadoc from a specific dependency (assuming this project has more dependencies) ?
Thanks
To generate javadoc for dependent sources, a sequence of steps needs to be done. These are outlined in this link.
Essentially you need to ensure that the source files of the dependency is generated/available and <includeDependencySources> parameter is enabled.

Resources