如何在Gradle中将打包方式设置为pom而不是默认的jar?

3
我有一个生成物料清单(BOM)的项目。当我执行 gradle build 命令时,它会生成一个空 jar 包,里面只包含一个 META-INF 文件夹。
但是我能够正确地将 pom(BOM)发布到 Nexus,并上传空 jar 包。
根据 maven 插件文档 https://docs.gradle.org/current/userguide/maven_plugin.html,我们应该能够设置打包方式:

packaging archiveTask.extension

其中,uploadTask 和 archiveTask 分别指用于上传和生成归档文件的任务

那么,如何将打包方式设置为 pom?
下面是 Gradle 上传的 pom 示例:
<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.ttt.a</groupId>
  <artifactId>my-bom</artifactId>
  <version>Something-SNAPSHOT</version>

用maven上传时,会出现以下额外内容:
  <packaging>pom</packaging>

更新:

完整的build.gradle配置:

buildscript {
    repositories {
        maven {
            url "http://myrepo"
        }
    }
    dependencies {
        classpath "io.spring.gradle:dependency-management-plugin:1.0.4.RELEASE"
        classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.5"
        classpath 'org.asciidoctor:asciidoctor-gradle-plugin:1.5.7'
    } }

apply plugin: 'java' apply plugin: 'maven' apply plugin: "io.spring.dependency-management" apply plugin: "jacoco" apply plugin: 'org.asciidoctor.convert' apply plugin: 'org.sonarqube'

group = project.properties['groupId'] version = project.properties['version'].toString()

description = """Bill of Materials"""

sourceCompatibility = 1.8 targetCompatibility = 1.8

ext {
    xxx = '1.0.0'
    yyy = '1.2.0'
    ... }

repositories {
    maven {
        url "http://myrepo"
    } }

dependencyManagement {
    dependencies {
        dependency "com.myorg:xxx:${xxx}"
        dependency "com.myorg:yyy:${yyy}"
        ...
    } }

uploadArchives {
    repositories {
        mavenDeployer {
            snapshotRepository(url: 'http://myrepo') {
                authentication(userName: "$System.env.NEXUS_USER", password: "$System.env.NEXUS_PASSWORD")
            }
        }
    } }

asciidoctor {
    sourceDir = file('src/docs/asciidoc/')
    sources {
        include '*.adoc'
    }
    outputDir = file("build/docs/${version}") }

task generateDummyBom {
    doLast {
        project.buildDir.mkdirs()
        new File("$project.buildDir/dummy.pom").write("<project></project>\n")
    }
    ext.bomFile = file("$project.buildDir/dummy.pom") }

artifacts {
    archives(generateDummyBom.bomFile) {
        builtBy generateDummyBom
    } }

jar.enabled = false

你尝试过手动设置packaging属性吗?例如,设置为pom - ToYonos
是的,我尝试过了,但它没有起作用 :( - codependent
请问您能否在您的帖子中添加相关的 build.gradle 文件部分呢? - ToYonos
2个回答

0

我发现Maven插件似乎忽略了packaging属性。经过一些实验,我发现它将packaging属性设置为您的构件中文件的扩展名。因此,将packaging属性设置为pom的方法是创建一个带有.pom扩展名的虚拟构件。

// The real file that we want to publish is the pom generated implicitly by the
// maven publishing plugin.
//
// We need to generate at least one file that we can call an archive so that the
// maven plugin will actually publish anything at all. Luckily, if the file
// that we call an archive is a .pom file, it's magically discarded, and we are
// only left with the implicitly-generated .pom file.
//
// We need the extension of the file to be `.pom` so that the maven plugin will
// set the pom packaging to `pom` (i.e. `<packaging>pom</packaging>`). Otherwise,
// packaging would be set to `xml` if our only file had an `.xml` extension.
task generateDummyBom {
  doLast {
    // Since we don't depend on anything else, we have to create the build dir
    // ourselves.
    project.buildDir.mkdirs()
    // The file actually has to have xml in it, or Sonatype will reject it
    new File("$project.buildDir/${project.artifactId}.pom").write("<project></project>\n")
  }
  ext.bomFile = file("$project.buildDir/${project.artifactId}.pom")
}

artifacts {
  archives(generateDummyBom.bomFile) {
    builtBy generateDummyBom
  }
}

jar.enabled = false

更新:如果您应用了Java插件,则需要从您的存档中删除jar归档文件。

// Remove the default jar archive which is added by the 'java' plugin.
configurations.archives.artifacts.with { archives ->
  def artifacts = []
  archives.each {
    if (it.file =~ 'jar') {
      // We can't just call `archives.remove(it)` here because it triggers
      // a `ConcurrentModificationException`, so we add matching artifacts
      // to another list, then remove those elements outside of this iteration.
      artifacts.add(it)
    }
  }
  artifacts.each {
    archives.remove(it)
  }
}

第二次更新:将上面的“dummy.pom”替换为“${project.artifactId}”。


嗨,Garret,我刚刚测试了你的解决方案,但它不起作用。我看到现在没有jar文件了,而是有一个新的dummy.pom文件,到目前为止还不错。问题是,./gradlew -DNEXUS_PASSWORD=$NEXUS_PASSWORD -DNEXUS_USER=$NEXUS_USER clean build upload --no-daemon 最终出现了这个错误:Execution failed for task ':uploadArchives'. Could not publish configuration 'archives' Cannot publish artifact 'myreleasetrain.jar (com.myorg:myreleasetrain:Callao-SR5-SNAPSHOT)' (/home/myreleasetrain/build/libs/myreleasetrain-Autumn-GA-SNAPSHOT.jar) as it does not exist. - codependent
我添加了一个更新,说明如何删除使用Java插件时默认添加的jar构件。 - Garrett Jones
通过您的更新,pom成功上传了...几乎成功了。但是我在Nexus中看到的是一个名为dummy的artifactId的pom。将“dummy.pom”替换为${project.artifactId}.pom就会像魅力一样工作。 - codependent
我用${project.artifactId}更新了我的答案。谢谢! - Garrett Jones
我发现${project.artifactId}未定义,尝试将其替换为${project.name}-${project.version},虽然消除了该错误,但现在出现了一个关于无法找到jar的错误,这对我来说似乎很愚蠢,因为我认为这个解决方案的整个重点是停止寻找jar。 :( - Hakanai

0

我无法让Garrett的解决方案起作用,但我通过以下方式取得了成功:

dependencies {
    // ...Omitted...
}

tasks.named('generatePomFileForMavenJavaPublication') {
    pom.with {
        description = 'Parent BOM'
        withXml {
            // ...Omitted...
        }
    }
}

// Removing all jar artifacts from the mavenJava publication
// appears to automagically cause packaging to be set to 'pom'!
publishing.publications.named('mavenJava') {
    artifacts.removeIf { artifact ->
        artifact.extension == 'jar'
    }
}

1
pom.packaging = "pom" }``` - Roy Clarkson

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