Gradle未在发布的pom.xml中包含依赖项。

57

我有一个Gradle项目,我正在使用maven-publisher插件将我的Android库安装到本地maven仓库和maven仓库中。尽管它可以工作,但生成的pom.xml文件不包括任何依赖信息。是否有一种解决方法可以包含这些信息,或者我必须回到maven插件并进行所有需要的手动配置?


经过研究,我意识到我没有告诉发布物件其依赖项的位置,我只指定了输出/构建产物,因此我需要一种将这个MavenPublication与依赖项相关联的方法,但我还没有在文档中找到如何执行该操作。

------------------------------------------------------------
Gradle 1.10
------------------------------------------------------------
Build time: 2013-12-17 09:28:15 UTC Build number: none Revision: 36ced393628875ff15575fa03d16c1349ffe8bb6
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_60 (Oracle Corporation 24.60-b09) OS: Mac OS X 10.9.2 x86_64

相关的build.gradle部分:

//...
apply plugin: 'android-library'
apply plugin: 'robolectric'
apply plugin: 'maven-publish'

//...
repositories {
     mavenLocal()
     maven  {
         name "myNexus"
         url myNexusUrl
     }
     mavenCentral()
}

//...
android.libraryVariants
publishing {
    publications {
        sdk(MavenPublication) {
            artifactId 'my-android-sdk'
            artifact "${project.buildDir}/outputs/aar/${project.name}-${project.version}.aar"
        }
    }
    repositories {
        maven  {
            name "myNexus"
            url myNexusUrl
            credentials {
                username myNexusUsername
                password myNexusPassword
            }
        }
    }
}

生成的pom.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.example.android</groupId>
  <artifactId>my-android-sdk</artifactId>
  <version>gradle-SNAPSHOT</version>
  <packaging>aar</packaging>
</project>

“maven-publisher插件”:您是指“maven-publish插件”吗? - Mohan
7个回答

87

我通过使用 pom.withXml 让脚本直接向pom添加依赖项来解决了这个问题。

//The publication doesn't know about our dependencies, so we have to manually add them to the pom
pom.withXml {
    def dependenciesNode = asNode().appendNode('dependencies')

    //Iterate over the compile dependencies (we don't want the test ones), adding a <dependency> node for each
    configurations.compile.allDependencies.each {
        def dependencyNode = dependenciesNode.appendNode('dependency')
        dependencyNode.appendNode('groupId', it.group)
        dependencyNode.appendNode('artifactId', it.name)
        dependencyNode.appendNode('version', it.version)
    }
}

这对我的项目有效,但在其他项目中可能会有意想不到的后果。


6
+1 太棒了。我已经将它添加到我的 *(MavenPublication) 块中,现在我所有的依赖关系都在我的aar的pom中了。非常感谢。 - Dori
8
我需要添加一个检查,确保 it.groupit.name 不为 null 或未指定,以便跳过在 Android Studio 中对 lib 目录的默认依赖。如果没有这个检查,Gradle 会生成无效的 POM 文件并崩溃。 - Adwiv
3
假设aar有其他aar依赖关系,那么如何发布它们?我试过同样的方式。应用程序已构建,但出现崩溃(NoClassDefFoundError)。在将这些内部依赖项包含在应用程序中后,它可以正常运行。请问是否还有其他适当的方法? - gopalanrc
8
如果您切换到了4.1 Gradle版本/3.0.1 Cradle插件,可以将"compile"替换为"implementation"。请注意,翻译不会增加解释或其他信息。 - drdaanger
3
今天我的"compile"无法使用。可用的是"releaseCompileClasspath"。例如,要遍历依赖项,请使用"configurations.releaseCompileClasspath.allDependencies.each"。 - Sofi Software LLC
显示剩余9条评论

30

我升级了C.Ross的解决方案。这个例子将会生成pom.xml文件,其中包含编译配置和特殊构建类型的依赖项,例如你在发布或调试版本中使用不同的依赖项 (debugCompile 和 releaseCompile)。同时还会添加排除项。

publishing {
    publications {
        // Create different publications for every build types (debug and release)
        android.buildTypes.all { variant ->
            // Dynamically creating publications name
            "${variant.name}Aar"(MavenPublication) {

                def manifest = new XmlSlurper().parse(project.android.sourceSets.main.manifest.srcFile);
                def libVersion = manifest['@android:versionName'].text()
                def artifactName = project.getName()

                // Artifact properties
                groupId GROUP_ID
                version = libVersion
                artifactId variant.name == 'debug' ? artifactName + '-dev' : artifactName

                // Tell maven to prepare the generated "*.aar" file for publishing
                artifact("$buildDir/outputs/aar/${project.getName()}-${variant.name}.aar")

                pom.withXml {
                    //Creating additional node for dependencies
                    def dependenciesNode = asNode().appendNode('dependencies')

                    //Defining configuration names from which dependencies will be taken (debugCompile or releaseCompile and compile)
                    def configurationNames = ["${variant.name}Compile", 'compile']

                    configurationNames.each { configurationName ->
                        configurations[configurationName].allDependencies.each {
                            if (it.group != null && it.name != null) {
                                def dependencyNode = dependenciesNode.appendNode('dependency')
                                dependencyNode.appendNode('groupId', it.group)
                                dependencyNode.appendNode('artifactId', it.name)
                                dependencyNode.appendNode('version', it.version)

                                //If there are any exclusions in dependency
                                if (it.excludeRules.size() > 0) {
                                    def exclusionsNode = dependencyNode.appendNode('exclusions')
                                    it.excludeRules.each { rule ->
                                        def exclusionNode = exclusionsNode.appendNode('exclusion')
                                        exclusionNode.appendNode('groupId', rule.group)
                                        exclusionNode.appendNode('artifactId', rule.module)
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

谢谢你的代码片段!我怀疑我将不得不自己管理变量(如果我有可用的东西,我会更新这个线程)。 - Kikiwa
与之前为uploadArchives任务创建的POM相比,它似乎缺少scope属性。是否有一种简单的方法可以在上面的代码中轻松包含它? - amadib
在pom.xml中,scope应与configurationName相同。代码如下: def configurationNames = ["${variant.name}Compile", 'compile'] 要跳过debugCompile和releaseCompile,但是需要在作用域属性中使用编译配置名称compile。 要创建带有所有作用域依赖项的pom文件,您需要将它们全部添加到该数组中(runtime等),然后在循环中仅检查是否不为debugCompile或releaseCompile append节点范围。 exclusionNode.appendNode('scope', configurationName) - cooperok

9

在Gradle 3中引入了implementation。将compile替换为implementation。请改用这个。

pom.withXml {
    def dependenciesNode = asNode().appendNode('dependencies')
    configurations.implementation.allDependencies.each {
        def dependencyNode = dependenciesNode.appendNode('dependency')
        dependencyNode.appendNode('groupId', it.group)
        dependencyNode.appendNode('artifactId', it.name)
        dependencyNode.appendNode('version', it.version)
    }
}

5

下面是 Kotlin DSL 版本的已接受答案:

    create<MavenPublication>("maven") {
        groupId = "com.example"
        artifactId = "sdk"
        version = Versions.sdkVersionName
        artifact("$buildDir/outputs/aar/Example-release.aar")
        pom.withXml {
            val dependenciesNode = asNode().appendNode("dependencies")
            val configurationNames = arrayOf("implementation", "api")
            configurationNames.forEach { configurationName ->
                configurations[configurationName].allDependencies.forEach {
                    if (it.group != null) {
                        val dependencyNode = dependenciesNode.appendNode("dependency")
                        dependencyNode.appendNode("groupId", it.group)
                        dependencyNode.appendNode("artifactId", it.name)
                        dependencyNode.appendNode("version", it.version)
                    }
                }
            }
        }
    }

这个答案肯定很快会流行起来。 - Logan Guo

3

我猜这与指令from components.java有关,可以在指南中看到。我曾经有过类似的设置,将该行添加到发布块中对结果产生了影响:

publications {
    mavenJar(MavenPublication) {
        artifactId 'rest-security'
        artifact jar
        from components.java
    }
}

2
这在使用.jar输出时有效,但据我所知,对于aar则无效。显然,目前(gradle插件1.2.2)对于aar存在问题。 - Dori
@Dori 遇到了同样的问题.. aar 没有依赖项,需要删除 md5/sha 文件,因为被覆盖的 pom - kagali-san
Android Gradle插件的1.5.0版本仍缺少指令。如果你在你的Android项目的build.gradle文件中添加它,当尝试解析该文件时你将会看到这个错误信息:"Could not find property 'java' on SoftwareComponentInternal set." - Adil Hussain
版本 2.1.0 对于 aar 文件也无法工作。有没有解决方法? - amadib
这救了我的命! - Marcello DeSales
如果包含多个JAR文件,则必须在每个JAR文件上声明“classifier”以避免错误https://github.com/gradle/gradle/issues/1624#issuecomment-330821182。我将主要的JAR文件声明为“default”的分类器,并成功发布了源代码和主要的JAR文件! - Marcello DeSales

0

我正在使用 maven-publish 插件来发布我的 aar 依赖项,实际上在我的情况下我无法使用 maven 任务。因此,我使用了由 maven-publish 插件提供的 mavenJava 任务,并按照以下方式使用。

apply plugin 'maven-publish'

publications {
    mavenAar(MavenPublication) {
        from components.android
    }

    mavenJava(MavenPublication) {
        pom.withXml {
            def dependenciesNode = asNode().appendNode('dependencies')
            // Iterate over the api dependencies (we don't want the test ones), adding a <dependency> node for each
            configurations.api.allDependencies.each {
                def dependencyNode = dependenciesNode.appendNode('dependency')
                dependencyNode.appendNode('groupId', it.group)
                dependencyNode.appendNode('artifactId', it.name)
                dependencyNode.appendNode('version', it.version)
            }
        }
    }
}

我希望这能帮助到正在寻求如何使用 maven-publish 插件发布 aarpom 文件的人。


0

现在编译已经被弃用,我们必须使用实现。

pom.withXml {
def dependenciesNode = asNode().appendNode('dependencies')
    configurations.implementation.allDependencies.each {
    def dependencyNode = dependenciesNode.appendNode('dependency')
    dependencyNode.appendNode('groupId', it.group)
    dependencyNode.appendNode('artifactId', it.name)
    dependencyNode.appendNode('version', it.version)
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接