I am facing a confusing issue with gradle. I have my dependencies declared where I have a jar from my private repository. Recently I released a new version of my private lib, and when I try to import the dependency gradle automatically changes it to the SNAPSHOT version.
implementation group: "com.company.name", name: "my-library", version: "0.11.0"
and when I run the dependency tree
com.company.name:my-library:0.11.0 -> 0.11.0-SNAPSHOT
I tried forcing the version like this
implementation (group: "com.company.name", name: "my-library") {
version {
strictly '0.11.0'
}
}
and still the result was
com.company.name:my-library:{strictly 0.11.0} -> 0.11.0-SNAPSHOT
I cleaned all the caches and refreshed the dependencies, I still get the same thing.
The version was set in the dependencies.lock
Related
I have a gradle Project where I have a dependency on "hudson-core 3.3.3"
compile group: 'org.eclipse.hudson', name: 'hudson-core', version: '3.3.3'
This works without a problem when using Gradle 5.6.2
When I upgrade to Gradle 6.0.1 I receive the following error:
Could not resolve org.eclipse.hudson:hudson-remoting:3.0.3.
Required by:
project : > org.eclipse.hudson:hudson-core:3.3.3
project : > org.eclipse.hudson:hudson-core:3.3.3 > org.eclipse.hudson:hudson-cli:3.3.3
> Could not resolve org.eclipse.hudson:hudson-remoting:3.0.3.
> inconsistent module metadata found. Descriptor: org.eclipse.hudson:hudson-remoting:3.0.4-SNAPSHOT Errors: bad version: expected='3.0.3' found='3.0.4-SNAPSHOT'
The Repository is always the same:
repositories {
mavenCentral()
maven {
url 'http://repo.jenkins-ci.org/public/'
}
}
Any Ideas why this error happens?
As said by #ToYonos, the problem is in the dependency itself.
Not perfect solutions, but 2 workarounds can be done as explained in Gradle's documentation (v6.7.1):
Exclude that transitive dependency, for example in the current Gradle versions using implementation instead of compile:
implementation('org.eclipse.hudson:hudson-core:3.3.3') {
exclude group: 'org.eclipse.hudson'
exclude module: 'hudson-remoting'
}
Override that transitive dependency version:
implementation('org.eclipse.hudson:hudson-remoting') {
version {
strictly '3.0.2' // As 3.0.3 is having the issue
}
}
In the pom.xml file of hudson-remoting 3.0.3, the version is <version>3.0.4-SNAPSHOT</version>
The issue is quite clear.
I tried with an old Gradle 4.4.1 and I am having the exact same issue. Likewise with Gradle 5.1.1 and your version, 5.6.2
I'm quite sure that if you clean your artefact cache for Gradle 5.6.2, it won't work anymore.
The error is on the repository side.
Another option is to define a repository that will download only a jar:
repositories {
mavenCentral() {
name = "Download only jar repo"
metadataSources { artifact() }
content {
// Use this repository only for org.eclipse.hudson:hudson-remoting
includeVersion("org.eclipse.hudson", "hudson-remoting", "3.0.3")
}
}
mavenCentral()
}
Also since pom is not downloaded you would have to add hudson-remoting dependencies by hand to build.gradle. But luckily for this particular case hudson-core already contains the only dependency commons-codec:commons-codec:1.4 that hudson-remoting needs, so this is not needed.
Note: the order of repositories is important, although in that case it will work either way. If you don't want to care about the order when using repositories with filter check exclusive content filtering.
When publishing snapshots to artifactory/mavenLocal, projects won't pick up the latest snapshot. This requires deleting the jar from ~/.gradle/cache
Maven has a feature to set timestamps for snapshots. how would this work with gradle cache?
There are two things to consider in resolving your issue:
How Gradle handles/recognizes snapshots
How to override Gradle's default behavior
Some background on how Gradle recognizes/handles snapshots
By default, Gradle will refresh a snapshot dependency every 24 hours.
Gradle will automatically recognize a dependency as a snapshot if the version ends with the -SNAPSHOT suffix. For example:
dependencies {
compile group: "aGroup", name: "anArtifact", version: "1.0-SNAPSHOT"
}
However, if the dependency's version string does not end with -SNAPSHOT Gradle needs to be told it's a snapshot with the changing parameter. For example:
dependencies {
compile group: "aGroup", name: "anArtifact", version: "1.0", changing: true
}
Overriding how often Gradle downloads snapshots
The only mechanism for overriding the default 24 hour policy is to configure Gradle to invalidate dependency cache (and thus download a new SNAPSHOT) more frequently. For example:
configurations.all {
resolutionStrategy.cacheChangingModulesFor 0, 'seconds'
}
Dynamically versioned dependency cache will need to be configured separately
If you're using any dynamic versions, such as:
dependencies {
compile group: "aGroup", name: "anArtifact", version: "1.+", changing: true
}
You'll need to configure cache invalidation for those dependencies separately, like this:
configurations.all {
resolutionStrategy.cacheChangingModulesFor 0, 'seconds'
resolutionStrategy.cacheDynamicVersionsFor 0, 'seconds'
}
Build performance impact
One thing to note is that the shorter the period of time a dependency is cached the more frequently Gradle will retrieve that artifact. If caching is disabled altogether, it will grab the dependency during each execution.
I'm creating a web project using Gradle (buildship) in Eclipse (WTP). I've put the libraries I need as "implementation" dependencies in my build.gradle, however they are not copied to Tomcat when I try to run the project from within Eclipse. When I build the WAR file (with gradle war), however, all the jar files are there.
I can't find anywhere the solution for this. It's beeing awful to manually (and redundantly) copying every jar and its dependency to WEB-INF/libs just to be able to run the app from Eclipse).
I've found a workaround here: https://github.com/eclipse/buildship/issues/496
It's adding this to build.gradle:
eclipse {
wtp {
component {
libConfigurations += [configurations.runtimeClasspath]
}
}
}
With this everything gets properly deployed.
UPDATE!
Gradle 5.3 has just been released and includes a fix for this issue and the hack above is not needed anymore.
The only thing that worked for me was changing
dependencies {
implementation group: 'org.projectlombok', name: 'lombok', version: '1.18.4'
}
too
dependencies {
compile group: 'org.projectlombok', name: 'lombok', version: '1.18.4'
}
I have project A and B. Project B depends on A.
If I build a snapshot for B, it will trigger a snapshot build on A. The issue is that when the latest snapshot of A gets pushed, B doesn't pick up the latest snapshot. Rather, it picks up the one before that.
Is there any reason why? And can I pull the latest snapshot every time ?
If your dependencies do not have the "-SNAPSHOT", you can specifically tell gradle that the dependency is a changing one like this:
dependencies {
compile group: "group", name: "artifact", version: "1.0", changing: true
}
However even changing dependencies are cached for 24 hours by default. To make sure you will always get the latest one, use:
configurations.all {
resolutionStrategy.cacheChangingModulesFor 0, 'seconds'
}
In a gradle project, I have my dependencies set as:
dependencies {
compile group: 'com.our_organization.lib', name: 'Libraries', version: '5.+'
compile group: 'commons-io', name: 'commons-io', version: '2.4'
}
which uses the latest released version of Libraries, and works perfectly.
I then release my built jar to Artifactory via:
artifactory {
contextUrl = artifactory_contextUrl
publish {
repository {
repoKey = publicationRepoKey
username = artifactory_user
password = artifactory_password
maven = true
}
}
}
which for the most part works fine.
However, when I go to artifactory and get the xml for any given version, it's dependencies are listed as
<dependencies>
<dependency org="com.our_organization.lib" name="Libraries" rev="5.+" />
<dependency org="commons.io" name="commons.io" rev="2.4" />
</dependencies>
which means I am unable to link my version to the specific Libraries version that was used for its build.
What I'd like to do is have the dependency version given to artifactory be the specific resolved version that is used in the build.
I've scoped a couple of things, all very hacky, and feel there has to be a better way.
Here's what I've thought of / tried:
Resolving the dependency myself and setting the specific version in the gradle dependency dsl, so to gradle it looks like a specific version. Using ivy to get the resolved version of a dependency of proving to be harder that it should.
Mucking the xml after its written but before it's sent to artifactory. This is just bad on so many levels and prone to breaking in the future.
Using a seperate gradle project to determine the resolved version and write that to a properties file which is then used similarly to #1. This feels like overkill.
Overall, this seems like a simple for which, for the life of me, I can't find an appropriate solution.
I am not sure what Gradle will do with it in pom.xml, but you might try using the Artifactory's functionality to retrieving the latest version, instead of Gradle's one.
The post
In Gradle, how can I generate a POM file with dynamic dependencies resolved to the actual version used?
exactly solves this problem. But you have to use the maven-publish Plugin instead of the Artifactory Plugin.