I have a working project that has a dependency on a maven artifact produced by a peer component like this:
repositories {
ivy {
url "../cnf/local"
}
}
configurations {
ejbTools
}
dependencies {
ejbTools 'test:com.ibm.ws.ejbcontainer.fat_tools:1.+'
}
The dependency test:com.ibm.ws.ejbcontainer.fat_tools:1.+
fails to resolve with Gradle 6.0 with the following error:
> Task :com.ibm.ws.ejbcontainer.async_fat:addEJBTools FAILED
FAILURE: Build failed with an exception.
* Where:
Build file '/Users/aguibert/dev/git/open-liberty/dev/com.ibm.ws.ejbcontainer.async_fat/build.gradle' line: 32
* What went wrong:
Execution failed for task ':com.ibm.ws.ejbcontainer.async_fat:addEJBTools'.
> Could not resolve all files for configuration ':com.ibm.ws.ejbcontainer.async_fat:ejbTools'.
> Could not find any matches for test:com.ibm.ws.ejbcontainer.fat_tools:1.+ as no versions of test:com.ibm.ws.ejbcontainer.fat_tools are available.
Searched in the following locations:
- https://repo.maven.apache.org/maven2/test/com.ibm.ws.ejbcontainer.fat_tools/maven-metadata.xml
- http://public.dhe.ibm.com/ibmdl/export/pub/software/olrepo/test/com.ibm.ws.ejbcontainer.fat_tools/maven-metadata.xml
- file:/Users/aguibert/dev/git/open-liberty/dev/cnf/local/test/com.ibm.ws.ejbcontainer.fat_tools/
- file:/Users/aguibert/dev/git/open-liberty/dev/cnf/local/test/com.ibm.ws.ejbcontainer.fat_tools/1.0.33.201909241016/ivy-1.0.33.201909241016.xml
Required by:
project :com.ibm.ws.ejbcontainer.async_fat
Currently my project is using Gradle 5.5 and can be built with Java 8, 11, or 12. I am trying to get it working with Java 13 too so I am trying to upgrade to Gradle 6.0.
It seems that there is a general behavior change with the way wildcarded dependencies work in Gradle now (for example com.foo:bar:1.+
).
A published Ivy module can be consumed by Gradle (see Declaring Dependencies) and other tools that understand the Ivy format. You can learn about the fundamentals of publishing in Publishing Overview.
In most cases, a project relies on reusable functionality in the form of libraries or is broken up into individual components to compose a modularized system. Dependency management is a technique for declaring, resolving and using dependencies required by the project in an automated fashion.
Gradle 6.0 fails to resolve artifacts from the mavenLocal () repository. The artifact was published using the maven-publish plugin. In the local maven repository metadata was published as maven-metadata-local.xml (as before). However Gradle 6.0 seems to be exclusively looking for a file named maven-metadata.xml - which isn't there.
For Maven repositories, Gradle will use the maven-metadata.xml which provides information about the available versions. For Ivy repositories, Gradle will resort to directory listing. This process results in a list of candidate versions that are then matched to the dynamic version expressed.
Given a required dependency, with a version, Gradle attempts to resolve the dependency by searching for the module the dependency points at. Each repository is inspected in order. Depending on the type of repository, Gradle looks for metadata files describing the module (.module,.pom or ivy.xml file) or directly for artifact files.
Apache Ivy is a very flexible dependency management tooling. It offers the possibility to customize dependency resolution, including conflict resolution. This flexibility comes with the price of making it hard to reason about. Gradle will consider all requested versions, wherever they appear in the dependency graph.
According to this Gradle issue, there is a breaking change in behavior in Gradle 6.0. Before, Gradle would automatically check for artifact metadata (e.g. maven-metadata.xml
), but in order to improve performance it seems that Gradle 6.0 no longer does this by default.
There are 2 possible solutions to this problem:
Use specific dependency coordinates instead of wildcarded versions like 1.+
(which is best practice IMO)
Update the repositories.[maven|ivy].metadataSources
configuration. In Gradle 5.X the defaults were:
repositories {
maven {
url "http://repo.mycompany.com/repo"
metadataSources {
mavenPom()
artifact()
}
}
ivy {
url "http://repo.mycompany.com/repo"
metadataSources {
ivyDescriptor()
artifact()
}
}
}
But in Gradle 6.0 they are now:
repositories {
maven {
url "http://repo.mycompany.com/repo"
metadataSources {
mavenPom()
}
}
ivy {
url "http://repo.mycompany.com/repo"
metadataSources {
ivyDescriptor()
}
}
}
So to revert back to previous behavior, add the artifact()
configuration to the repositores.[maven|ivy].metadataSources
config block.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With