Reading a maven settings.xml when building with gr

2020-05-16 05:35发布

问题:

I have a maven settings.xml located in:

 /home/u123/.m2/settings.xml

where I specify a remote maven repository:

<?xml version="1.0" encoding="UTF-8"?>
<settings>
  <profiles>
    <profile>
      <id>default</id>
      <repositories>
          <repository>
              <id>my.repo</id>
               <url>http://myrepo/ </url>
          </repository>
      </repositories>
    </profile>
  </profiles>
  <activeProfiles>
    <activeProfile>default</activeProfile>
  </activeProfiles>
</settings>

In this repo I have deployed an artifact - actually its a gradle plugin.

Now I try to build another project that needs to use this plugin/artifact using the below build.gradle file:

apply plugin: 'java'
apply plugin: 'maven'

buildscript {
    dependencies {
        classpath 'com.test:my-gradle-plugin:1.0.0-SNAPSHOT'
    }
}

But the build fails:

...
> Could not find group:com.test, module:my-gradle-plugin, version:1.0.0-SNAPSHOT.
...

Gradle cannot find my-gradle-plugin even though I have the above settings.xml file pointing to the remote maven repository.

If I instead specify the repository inside my build.gradle file it works:

buildscript {
    repositories {
        maven {
            url "http://myrepo/"
        }
    }
    dependencies {
        classpath 'com.test:my-gradle-plugin:1.0.0-SNAPSHOT'
    }
}

Based on this post:

http://forums.gradle.org/gradle/topics/have_mavenlocal_check_m2_home_conf_settings_xml

it seems that gradle considers the settings.xml file so what is wrong?

回答1:

There is an open ticket related to this that will be hopefully implemented:

http://issues.gradle.org/browse/GRADLE-2365

But as a workaround you can use some groovy scripting in the build.gradle to achieve this. In my case I needed the authentication information from settings.xml. But this could easily be adapted to get repository info.

Example:

def getMavenSettingsCredentials = {
    String userHome = System.getProperty( "user.home" );
    File mavenSettings = new File(userHome, ".m2/settings.xml")
    def xmlSlurper = new XmlSlurper()
    def output = xmlSlurper.parse(mavenSettings)
    return output."servers"."server"
}

def getCredentials = {
    def entries = getMavenSettingsCredentials()
    for (entry in entries) {
        if ( entry."id".text() == "my-server" ) {
            return [username: entry.username.text(), password: entry.password.text()]
    }
  }
}
uploadArchives {
def creds = getCredentials()
repositories.mavenDeployer {
    configuration = configurations.deployerJars
    repository(url: "http://my-release-repository/releases/") {
        authentication(userName: creds["username"], password: creds["password"])
    }
    snapshotRepository(url: "http://my-snapshot-repository/snapshots/") {
        authentication(userName: creds["username"], password: creds["password"])
    }


  }
}


回答2:

You have to declare all repositories in your Gradle build script. settings.xml is only used to find the location of the local Maven repository, for example when resolving repositories { mavenLocal() }.



回答3:

gradle-maven-settings-plugin works for me (at least in my Windows environment)

One should add

buildscript {
    repositories {
        maven {
            url "https://plugins.gradle.org/m2/"
        }
    }
}

plugins {
    id 'net.linguica.maven-settings' version '0.5'
}

to the build.gradle and then can add repository like this:

repositories {
    maven {
        name = 'myRepo' // should match <id>myRepo</id> of appropriate <server> in Maven's settings.xml
        url = 'https://intranet.foo.org/repo'
    }
}

which will use myRepo credentials from the Maven's settings.xml to access the https://intranet.foo.org/repo repository



回答4:

I used maven-publish, maven-publish-auth plugins to accomplish this without parsing the settings by hand

How can Gradle Use Repository Settings From Maven's Settings.xml to publish artifacts

Hope it is of use.

Peter



回答5:

See: https://github.com/ci-and-cd/maven-settings-decoder

I use it in gradle build script to avoid expose nexus password in build.gradle or environment variable.

buildscript {
  repositories {
    ...
    mavenCentral()
  }
  dependencies {
    ...
    classpath 'cn.home1.tools:maven-settings-decoder:1.0.5.OSS'
  }
}
...
ext.mavenSettings = new cn.home1.tools.maven.SettingsDecoder();
ext.nexusSnapshotsUser = mavenSettings.getText("//server[id='${nexus}-snapshots']/username/text()")
ext.nexusSnapshotsPass = mavenSettings.getText("//server[id='${nexus}-snapshots']/password/text()")
println "${nexus}-snapshots username: " + mavenSettings.getText("//server[id='${nexus}-snapshots']/username/text()")
println "${nexus}-snapshots password: " + mavenSettings.getText("//server[id='${nexus}-snapshots']/password/text()")
...


回答6:

Please use mavenLocal() in your repositories section of build.gradle file. This should read ~/.m2/settings.xml file in your home directory.

repositories {
    mavenCentral()
    mavenLocal()
}


标签: maven gradle