当前位置: 首页 > 知识库问答 >
问题:

Gradle Maven插件为自定义配置生成不正确的POM依赖项

农鸿达
2023-03-14

我有一个Gradle项目,它做了两件正交的事情:

  1. 编译并运行一些Java。
  2. 生成并发布一个工件。

此工件与Java无关;它是由自定义JavaExec任务生成的。但是,自动生成的POM(来自Maven插件)似乎包含错误的依赖项。问题:如何防止这种情况?

我的build.gradle是这样的:

apply plugin: "java"
apply plugin: "maven"

configurations {
    foo  // Custom configuration for the artifact I want to build and publish
}

// Dependencies for Java configurations (nothing to do with foo)
dependencies {
    compile "foo:foo:1.1"
    testCompile "bar:bar:2.2"
}

// Custom task
task generateFoo(type: JavaExec) {
    ext.outputFile = new File(buildDir, "foo.bar")
    ...
}

artifacts {
    foo    file: generateFoo.outputFile, builtBy: generateFoo
}

uploadFoo {
    repositories {
        mavenDeployer { ... }
    }
}

我这样调用Gradle:

./gradlew uploadFoo

AFAICS,< code>foo配置与Java配置无关。所以我希望发布的POM不会列出任何依赖项。然而,我观察到了列出的所有不相关的依赖项。

Maven插件的Gradle文档暗示了使用<code>conf2ScopeMappings</code>的依赖关系映射,但我完全不清楚我应该用它做什么(如果有的话)。

共有1个答案

宇文修文
2023-03-14

我设法用< code>maven和< code > maven-publish gradle插件设置了类似的配置。

在我的例子中,我使用了带有自定义配置的自定义Jar任务,但它应该可以工作,因为工件{…}在这两种情况下都使用。

使用< code>maven插件,您的< code>build.gradle将如下所示:

apply plugin: "java"
apply plugin: "maven"

configurations {
    foo  // Custom configuration for the artifact I want to build and publish
}

// Dependencies for Java configurations (nothing to do with foo)
dependencies {
    compile "foo:foo:1.1"
    testCompile "bar:bar:2.2"
}

// Custom task
task generateFoo(type: JavaExec) {
    ext.outputFile = new File(buildDir, "foo.bar")
    ...
}

artifacts {
    foo    file: generateFoo.outputFile, builtBy: generateFoo
}

uploadFoo {
    repositories {
        mavenDeployer { 
            pom.scopeMappings.with {
                mappings.clear()
                addMapping(300, configurations.foo, 'runtime')
            }
            pom.artifactId = 'other artifact id than main jar'
            ... 
        }
    }
}

该解决方案的灵感来自以下主题:
http://gradle.1045684.n5.nabble.com/pom-generation-and-inherited-dependencies-td1436197.html

注意这行:

addMapping(300, configurations.foo, 'runtime')

您也可以添加其他配置,或使用“运行时”范围以外的其他maven范围。
300代表优先级,在这种情况下并不重要。

这种解决方案的优点是,我们可以很好地控制依赖关系及其映射。缺点是这不适用于< code>install任务。我们需要为安装任务设置不同的POM,这可能是可能的,但这超出了我的知识范围。

替代使用maven-发布插件:

apply plugin: "java"
apply plugin: "maven-publish"

configurations {
    foo  // Custom configuration for the artifact I want to build and publish
}

// Dependencies for Java configurations (nothing to do with foo)
dependencies {
    compile "foo:foo:1.1"
    testCompile "bar:bar:2.2"
}

// Custom task
task generateFoo(type: JavaExec) {
    ext.outputFile = new File(buildDir, "foo.bar")
    ...
}

artifacts {
    foo    file: generateFoo.outputFile, builtBy: generateFoo
}

publishing {
    publications {
        foo(MavenPublication) {
            from new org.gradle.api.internal.java.JavaLibrary(\
                configurations.api.artifacts.toArray()[0], \
                configurations.api.allDependencies)
            artifactId 'other artifact id than main jar'
        }
    }
    repositories {
        maven { ... }
    }
}

gradle任务将为您提供可能的发布命令:

publish - Publishes all publications produced by this project.
publishFooPublicationToMavenLocal - Publishes Maven publication 'foo' to the local Maven repository.
publishFooPublicationToMavenRepository - Publishes Maven publication 'foo' to Maven repository 'maven'.
publishToMavenLocal - Publishes all Maven publications produced by this project to the local Maven cache.
...

maven-publish替代方案的优势在于它将适用于本地和远程maven存储库。缺点可能是我们正在使用内部API,将来可能会发生变化,并且所有依赖项都映射到“运行时”maven范围。此外,MavenPublication代码段将更加冗长,如果我们想使用其他一些maven范围或应用一些范围映射,将使用更多的内部API。

我用的是Gradle 1.10

 类似资料:
  • 我创建了一个gradle插件(简称testinfra),它在编译时和运行时依赖于其他两个jar。这是我的版本。我的插件的gradle: 我能够将我的插件罐子推向人工制品。但是当我想使用插件时,我必须指定插件的GAV及其依赖项。见下文: 我的要求是避免指定依赖罐的GAV以及测试插件GAV。有没有办法在发布期间配置我的pom.xml(发布任务),这样当我指定插件的GAV时,gradle会识别依赖项并下

  • 我有一个库(Lib1),它依赖于我与Lib1一起从源代码构建的其他几个库(Lib2和Lib3)。所有三个都作为工件发布,工件ID分别为my-artifat-lib1、my-artifat-lib2和my-artifat-lib3。当我通过maven-Publ插件发布工件时,我在pom文件中得到了一个依赖项元素,如下所示: 未指定的版本可以通过在项目级 build.gradle 的 allproje

  • 我有一个Flink会话集群(作业管理器任务管理器),版本1.11.1,配置了log4j控制台。属性包括Kafka appender。此外,在作业管理器和任务管理器中,我都启用了flink-s3-fs-hadoop内置插件。 我已经将kafka客户端jar添加到flink/lib目录,这是容器运行所必需的。但在实例化S3插件(并初始化记录器)时,我仍然会遇到类下加载错误。 原因:org.apache

  • 我试图为其他gradle项目使用的自定义gradle插件构建一个jar。我使用java编写插件。我有一个问题,包括我的jar中的依赖项。如果我使用下面的代码构建jarbuild.gradle 在一个项目中应用插件时,我得到了一个针对guava类的NoClassDefFound异常。如果我在 它表示未找到Id为“my Plugin”的。如何在gradle插件jar中包含依赖项?

  • Maven插件及其在父pom中定义的依赖项,我不希望我的子pom包含该插件依赖项。 例如,如果有1个父级和100个子级,99个使用该插件并希望在一个子级中排除该插件。 我们如何才能实现这一目标?

  • 我正在尝试生成。jar,但是当它是使用Maven publishing生成的时候,它也生成了一个. pom文件。 问题是,我有另一个项目,当它实现这个依赖关系时,它以前只查找.jar,而现在它在所有其他项目中查找.pom,我想做的是,该项目停止使用“发布”任务生成.pom或在实现时停止寻找.pom文件以供其他项目使用。 下面是在 Artifactory 项目 A 中生成.jar的代码,其中项目 B