uploadArchives ignoring user's maven settings

When using the install task, my /USER_HOME/.m2/settings.xml configuration is taken into account. However, when I use the uploadArchives task, those same user settings are ignored.

This appears to be caused by this:

org.gradle.api.publication.maven.internal.ant.AbstractMavenResolver (line 75)

protected MavenSettingsSupplier mavenSettingsSupplier = new EmptyMavenSettingsSupplier();

The install task works because it overrides the mavenSettingsSupplier:

org.gradle.api.publication.maven.internal.ant.BaseMavenInstaller (line 31)

mavenSettingsSupplier = new MaybeUserMavenSettingsSupplier();

Is there a reason that the AbstractMavenResolver is not using the MaybeUserMavenSettingsSupplier in all cases? It falls back to the EmptyMavenSettingsSupplier, so it seems like it should be safe. It seems like a bug to me.

Here is what my environment looks like:

------------------------------------------------------------
Gradle 1.8
------------------------------------------------------------
  Build time:
 2013-09-24 07:32:33 UTC
Build number: none
Revision:
   7970ec3503b4f5767ee1c1c69f8b4186c4763e3d
  Groovy:
     1.8.6
Ant:
        Apache Ant(TM) version 1.9.2 compiled on July 8 2013
Ivy:
        2.2.0
JVM:
        1.7.0_45 (Oracle Corporation 24.45-b08)
OS:
         Mac OS X 10.8.5 x86_64

The same thing is failing on centos linux…

In which ways would you expect the Maven settings file to be taken into account? As far as I know, the only thing that’s taken into account is the location of the local Maven repository, which is only necessary when installing to that repository. Apart from that, the idea is to configure everything on Gradle’s side, without having this information polluted with some Maven files that may be lying around on someone’s machine.

I think the location of the local maven repo is the only part it should worry about.

That makes perfect sense to me.

The problem is that the uploadArchives does not take that location into account. That is the only part that is missing, and it appears that it works differently for the install task than it does in the uploadArchives task. The install takes does take that location into account.

Why would ‘uploadArchives’ need to know about the local Maven repository? Installing into the local Maven repository is the responsibility of the ‘install’ task.

I ran

gradlew install

from a project, and it put the artifacts into my custom maven location. (as defined in the USER_HOME/.m2/settings.xml)

I then ran

gradlew uploadArchives

from the same project and it put the artifacts into the standard maven location.

In looking at the code in a debugger, at runtime uploadArchives used the EmptyMavenSettingsSupplier from AbstractMavenResolver, but the install task, used the BaseMavenInstaller.

I don’t think the maven plugin uses the same install task in both cases…

Sounds like you haven’t configured ‘uploadArchives’ correctly. It isn’t meant to be used to install to a local Maven repository.

This is the only configuration we have for uploadArchives.

uploadArchives {
        repositories.mavenDeployer {
            configuration = configurations.deployerJars
            snapshotRepository(url: "http://OUR_SNAPSHOTS_URL") {
                authentication(userName: project.snapshotRepoUserName, password: project.snapshotRepoPassword)
            }
            repository(url: "http://OUR_RELEASES_URL") {
                authentication(userName: project.releaseRepoUserName, password: project.releaseRepoPassword)
            }
            uniqueVersion = true
        }
    }

At one time we did have this:

uploadArchives.dependsOn install

But I took that out, and it still puts the archives in the default maven location (USER_HOME/.m2/repository)

Here is the entirety of our build.gradle

apply plugin: 'project-report'
apply plugin: 'release'
  project.ext {
    defaultSitePublicationLocation = "file://${projectDir}/site"
}
  buildscript {
    //The following repositories are used only to resolve plugins for the build itself.
    repositories {
        mavenCentral()
        maven {
            url 'https://oss.sonatype.org/content/groups/public'
        }
        maven {
            url "http://OUR_SNAPSHOT_URL"
        }
        maven {
            url "http://OUR_RELEASES_URL"
        }
    }
      dependencies {
        classpath(
                [group: 'org.gradle.api.plugins', name: 'gradle-clover-plugin', version: project.cloverPluginVerison],
                [group: 'au.com.ish.gradle', name: 'release', version: project.releasePluginVersion],
        )
          classpath(group:'org.oclc.gradle', name:'gradle-site-plugin', version: project.sitePluginVersion) {
            exclude group: 'xerces', module: 'xercesImpl'
        }
    }
}
  allprojects {
      project.ext {
        sitePublicationLocation = ''
    }
      if(project.mavenSiteLocation) {
        project.sitePublicationLocation = project.mavenSiteLocation
    }
    else {
        project.sitePublicationLocation = project.defaultSitePublicationLocation
    }
      apply plugin: 'site'
    site {
        siteLocation = project.sitePublicationLocation
        dependsOnTasks = ['groovydoc', 'javadoc', 'test', 'pmdMain', 'pmdTest', 'findbugsMain', 'findbugsTest']
    }
      release {
        failOnSnapshotDependencies = true
        scm = 'svn'
        username = project.svnUserName
        password = project.svnPassword
    }
      group = 'org.oclc.instrumentation'
    version = release.projectVersion
}
  subprojects {
    apply plugin: 'java'
    apply plugin: 'maven'
      sourceCompatibility = new BigDecimal(project.javaVersion as String)
    targetCompatibility = new BigDecimal(project.javaVersion as String)
      compileJava {
        sourceCompatibility = project.javaVersion
        targetCompatibility = project.javaVersion
        options.fork = true
        options.forkOptions.executable = "${project.javaJdkHome}/bin/javac"
        options.encoding = "UTF-8"
    }
      apply plugin: 'checkstyle'
    checkstyle {
        toolVersion = project.checkstyleVersion
        configFile = rootProject.file('config/checkstyle/checkstyle.xml')
        configProperties = [
                'checkstyle.cache.file': rootProject.file('build/checkstyle.cache'),
        ]
        sourceSets = [sourceSets.main]
    }
      apply plugin: 'findbugs'
    findbugs {
        ignoreFailures = false
    }
      apply plugin: 'pmd'
    pmd {
        ignoreFailures = false
    }
      apply plugin: 'clover'
    clover {
        licenseLocation = "${rootProject.projectDir}/config/clover/clover.license"
        targetPercentage = '100%'
          report {
            xml = true
        }
    }
      configurations {
        deployerJars
    }
      repositories {
        mavenCentral()
        maven {
            url "http://OUR_SNAPSHOT_URL"
        }
        maven {
            url "http://OUR_RELEASES_URL"
        }
    }
      dependencies {
        clover([group: "com.cenqua.clover", name: "clover", version: project.cloverVersion])
        deployerJars([group: 'org.apache.maven.wagon', name: 'wagon-http', version: project.wagonHttpVersion])
        testCompile(
                [group: 'junit', name: 'junit', version: project.junitVersion],
                [group: 'org.mockito', name: 'mockito-all', version: project.mockitoVersion]
        )
    }
      check.dependsOn cloverGenerateReport
  //
  install.dependsOn check
//
//
  uploadArchives.dependsOn install
      uploadArchives {
        repositories.mavenDeployer {
            configuration = configurations.deployerJars
            snapshotRepository(url: "http://OUR_SNAPSHOT_URL") {
                authentication(userName: project.snapshotRepoUserName, password: project.snapshotRepoPassword)
            }
            repository(url: "http://OUR_RELEASES_URL") {
                authentication(userName: project.releaseRepoUserName, password: project.releaseRepoPassword)
            }
            uniqueVersion = true
        }
    }
      task sourcesJar(type: Jar, dependsOn: classes) {
        classifier = 'sources'
        from sourceSets.main.allSource
    }
      task javadocJar(type: Jar, dependsOn: javadoc) {
        classifier = 'javadoc'
        from javadoc.destinationDir
    }
      artifacts {
        archives sourcesJar
        archives javadocJar
    }
      /**
     * Allows clients to see where dependencies are being fetched from.
Useful in debugging dependency problems.
     */
    task showMeCache << {
        configurations.each { config ->
            println "${config.name}--------------------------"
            config.each { println it }
            println "----------------------------------------"
        }
    }
}
  apply plugin: 'idea'
idea.project {
    jdkName = project.javaVersion
}
  /**
 * Allows gradle to packaged as part of the build.
This generates infrastructure files to be committed once.
 * Then the build itself will use (or download) the correct version of gradle.
 */
task wrapper(type: Wrapper) {
    gradleVersion = project.gradleVersion
}

If you see something wrong in our configuration, I would be happy to change it.

I still think though that I don’t see any reason for org.gradle.api.publication.maven.internal.ant.AbstractMavenResolver to use the EmptyMavenSettingsSupplier, when the MaybeUserMavenSettingsSupplier exists.

Are you saying that running ‘gradle uploadArchives’ publishes the artifact to a local directory rather than the configured remote repository? Which Gradle version are you using?

uploadArchives correctly is putting the artifacts in the remote repository, but it is ALSO publishing to the local repo, and it is ignoring my override of the local repository from my USER_HOME/.m2/settings.xml.

Running gradlew install works correctly. It pays attention to my USER_HOME/.m2/settings.xml.

Using gradle 1.8

------------------------------------------------------------
Gradle 1.8
------------------------------------------------------------
Build time:
 2013-09-24 07:32:33 UTC
Build number: none
Revision:
   7970ec3503b4f5767ee1c1c69f8b4186c4763e3d
Groovy:
     1.8.6
Ant:
        Apache Ant(TM) version 1.9.2 compiled on July 8 2013
Ivy:
        2.2.0
JVM:
        1.7.0_45 (Oracle Corporation 24.45-b08)
OS:
         Mac OS X 10.8.5 x86_64

That’s a bug then. ‘uploadArchives’ should only publish to the configured repository. I’ve heard about this one before. You could have a look in JIRA; perhaps it was already fixed in 1.9.

I will try and switch a small project to see if the issue is resolved in 1.9. If it is not, would you like me to open a jira?

If you don’t find it in JIRA, let me know, and I’ll open an issue.

I have verified that this is still broken in gradle 1.9.

I did a quick search in the jira project, but did not see this exact problem. Would you like me to enter a new jira?

The right place to report issues is here; only Gradle devs can promote them to JIRA. The issue you are describing was already promoted as GRADLE-2711.

Cool, thank you for your patience.

I agree with what you are saying here, but I am seeing the exact opposite behavior in Gradle 1.10 through 1.12. I have configured a repository in the uploadArchives task of my build.gradle file but the repository in the Maven settings.xml is being used instead. This seems like a bug to me.