2.8, 2.9 mavenDeployer doesn't honour uniqueVersion=false in maven uploadArchives

gradle-3405
issue-acknowledged

(Warren Muller) #1

I’m trying to upgrade from 2.4 to 2.9 but my uploadArchives task is generating a pom with a timestamp, making all our snapshots unique. We use a non-unique policy so we set
uniqueVersion=false

I reverted to 2.4 and tried to go through the versions step by step:
2.5,2.6,2.7 all failed to deploy as per [2.7-rc-2] Cannot deploy using Maven plugin (No connector available)
2.8,29 work but add the extra timestamp which I don’t want, e.g.

<metadata>
<groupId>com.spindrift</groupId>
<artifactId>Common-Commerce</artifactId>
<version>1.0.12-SNAPSHOT</version>
<versioning>
<snapshot>
<timestamp>20151218.064219</timestamp>
<buildNumber>152</buildNumber>
</snapshot>
<lastUpdated>20151218064219</lastUpdated>
</versioning>
</metadata>

This causes downstream project dependency failures because they can’t find the non-unique snapshot (i.e. without timestamp).

The maven repository uses scpexe protocol so I can’t use the newer maven-publish plugin as an alternative.


(Warren Muller) #2

I found this issue, which I think highlights the same thing:
https://issues.gradle.org/browse/GRADLE-2711
but that was back at version 1.4
We’ve been using the uniqueVersion=false for a long time and it still works for 2.4 but seems broken since 2.8


#3

I think this could be an unforeseen result of upgrading to use the Maven 3 libraries for publishing, which happened in Gradle 2.5.

To clarify, do the artifacts get published with the correct extension? Is it just the maven-metadata.xml that is incorrectly generated, in that it contains a timestamp element? If so, how does this affect the downstream consumers of the publication?

We have integration test coverage for the uniqueVersion setting, but this doesn’t validate the content of maven-metadata.xml.


(Warren Muller) #4

I think the issue is a little clouded by the upgrade from M2 to M3 which I had missed.

do the artifacts get published with the correct extension

Yes they still get published with the same format as before, just the maven-metadata.xml that now includes a timestamp. I think under M2 it would actually publish to a separate endpoint with the timestamp, but with the upgrade and using the same configuration it does not publish with a timestamp endpoint, but because of the timestamp in the metadata a dependency consumer fails with:

error 05-Jan-2016 08:38:54 > Could not find com.spindrift:Common-Commerce:1.0.12-SNAPSHOT. error 05-Jan-2016 08:38:54 https://myrepo/com/spindrift/Common-Commerce/1.0.12-SNAPSHOT/maven-metadata.xml error 05-Jan-2016 08:38:54 https://myrepo/com/spindrift/Common-Commerce/1.0.12-SNAPSHOT/Common-Commerce-1.0.12-20160105.083609-185.pom error 05-Jan-2016 08:38:54 https://myrepo/com/spindrift/Common-Commerce/1.0.12-SNAPSHOT/Common-Commerce-1.0.12-20160105.083609-185.jar

I’ve looked at https://cwiki.apache.org/confluence/display/MAVEN/Maven+3.x+Compatibility+Notes#Maven3.xCompatibilityNotes-VersionComparison
and it says:

Snapshot Updates
Due to implementation differences, Maven 3 and Maven 2 use different files in the local repository to track metadata. For users that employ Maven 2 and Maven 3 (or integrators of Maven 3 like M2Eclipse) side by side on the same projects, this causes both Maven versions to independently check for updates of snapshot artifacts. In other words, even if one Maven version just checked for snapshot updates, the other Maven version will do again.

Non-unique Snapshot Deployments
The setting false for a distribution repository has no effect in version 3.x, snapshot artifacts will always be deployed using a timestamped version.

So our old configuration of setting false for the upload is no longer supported by M3.

The curious thing is that using gradle 2.10 and uploading the jars they were not added with a timestamp end-point that the consumer expected (unless its my misunderstanding of what that format is).

The way we were using snapshots was simply like a release and each snapshot simply got overwritten on each CI build so each consumer always got the latest release. I think we were implicitly relying on Gradle to ensure the snapshot dependencies were up to date by using --refresh-dependencies. So from what I can make of this is that our snapshot policy and the way we use them is no longer supported under M3 and we need to refactor the way we use snapshots going forward before we can upgrade. I will assume this is the case so please correct me if I’m wrong.
Thanks


(Rocky) #5

Daz - I’m having a similar problem. The short answer is yes to both. My thinking is that maven-metadata.xml is being generated incorrectly. When the time comes to resolve the dependency, it appears that Gradle follows the timestamp and buildNumber elements. So if those are set to 2016-02-18-163800 and 2, it would look for my-dep-SNAPSHOT-2016-02-18-163800-2.jar instead of just my-dep-SNAPSHOT.jar. Do you know of any workaround for this?


(Mark Vieira) #6

This is correct. This is mainly a result of our upgrade to using Maven 3 libraries internally where support for this feature has been dropped. This is an open issue and there have been other discussions on possible ways to fix this. Unfortunately there is no workaround.


#7

I’ve created GRADLE-3405 for this issue.


(Randy) #8

Hi all. This fixed my issue that I believe is similar to the ones above. The problem I see is that each publication in the publishing config gets a new timestamp for the upload. I am using Spring Boot and its plugin as well. So by adding the extra artifacts ( from the Jar tasks) to the one publication, it worked. All items have the same timestamp that matches and the metadata.xml file appears to work such that a dependent project can now access the api objects. See this example:

task apiJar(type: Jar) {
    classifier = 'api'
    from(sourceSets.main.output) {
        include "com/company/app/dto/**"
    }
}

task sourceJar(type: Jar, dependsOn: classes) {
    classifier = 'sources'
    from sourceSets.main.allSource
}

task apiSourceJar(type: Jar, dependsOn: classes) {
    classifier = 'api-sources'
    from(sourceSets.main.allSource) {
        include "com/company/app/dto/**"
    }
}

publishing {
    publications {
        mavenJava(MavenPublication) {
            from components.java
            pom.withXml {
                asNode().appendNode('description', 'APP Sprint Boot App')
            }
            artifact apiJar
            artifact sourceJar
            artifact apiSourceJar
        }
    }
    repositories {
        maven {
            credentials {
                username = 'username'
                password = 'password'
            }
            if(project.version.endsWith('-SNAPSHOT')) {
                url "http://server:9081/artifactory/libs-snapshot-local"
            } else {
                url "http://server:9081/artifactory/libs-release-local"
            }
        }
    }
}

(Warren Muller) #9

I may be wrong but I don’t think this is the same problem. The issue is that with the underlying Maven 2 framework when using uniqueVersion is false there are no timestamps at all, so every -SNAPSHOT build simply overwrites the previous version. The consuming project simply requests the snapshot version without any further qualifiers (date, latest, etc). With Maven 3 now it always generates timestamps so any consuming builds don’t work as they can’t find the unqualified snapshot anymore.