You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Gradle+GPG签名时主JAR文件验证失败求助

Maven Central发布时主JAR签名验证失败问题

我正尝试将JAR发布到Maven Central,遵循Sonatype的指引操作,现在测试代码签名功能,使用Gradle构建,遇到了主JAR签名验证失败的问题:javadoc和sources JAR的签名验证通过,但主JAR的签名验证失败。

以下是我的Gradle配置文件:

task javadocJar(type: Jar) {
    classifier = 'javadoc'
    from javadoc
}

task sourcesJar(type: Jar) {
    classifier = 'sources'
    from sourceSets.main.allSource
}


signing {
    sign configurations.archives
}

plugins.withId("com.github.johnrengelman.shadow"){

    //this block requires the java plugin to be applied first.
    plugins.withId("java"){

        shadowJar {
            //We are overriding the default jar to be the shadow jar
            classifier = null
            exclude 'META-INF'
            exclude 'META-INF/*.INF'
            exclude 'META-INF/license/*'
        }

        jar {
            manifest {
                attributes(
                        'Built-By'       : System.properties['user.name'],
                        'Build-Timestamp': new java.text.SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ").format(new Date()),
                        'Created-By'     : "Gradle ${gradle.gradleVersion}",
                        'Build-Jdk'      : "${System.properties['java.version']} (${System.properties['java.vendor']} ${System.properties['java.vm.version']})",
                        'Build-OS'       : "${System.properties['os.name']} ${System.properties['os.arch']} ${System.properties['os.version']}"
                )
            }
        }

        tasks.build.dependsOn tasks.shadowJar
        tasks.shadowJar.mustRunAfter tasks.jar
        tasks.shadowJar.mustRunAfter tasks.javadocJar
        tasks.shadowJar.mustRunAfter tasks.sourcesJar
    }
}

artifacts {
    archives javadocJar, sourcesJar
}

执行gradle clean build后,在build/libs目录生成相关产物,用gpg验证签名的结果如下:

$ gpg --verify build/libs/mask-json-field-transform-0.1-javadoc.jar.asc
gpg: assuming signed data in 'build/libs/mask-json-field-transform-0.1-javadoc.jar'
gpg: Signature made Fri Jan  6 17:17:16 2023 PST
gpg:                using EDDSA key Fxxxx9
gpg: Good signature from "Feroze Daud <xxx@yyy.com>" [ultimate]

$ gpg --verify build/libs/mask-json-field-transform-0.1-sources.jar.asc
gpg: assuming signed data in 'build/libs/mask-json-field-transform-0.1-sources.jar'
gpg: Signature made Fri Jan  6 17:17:16 2023 PST
gpg:                using EDDSA key Fxxxx9
gpg: Good signature from "Feroze Daud <xxx@yyy.com>" [ultimate]

$ gpg --verify build/libs/mask-json-field-transform-0.1.jar.asc
gpg: assuming signed data in 'build/libs/mask-json-field-transform-0.1.jar'
gpg: Signature made Fri Jan  6 17:17:16 2023 PST
gpg:                using EDDSA key Fxxxx9
gpg: BAD signature from "Feroze Daud <xxx@yyy.com>" [ultimate]

问题原因

配置逻辑存在顺序冲突:

  1. sign configurations.archives会对默认jar任务生成的主JAR进行签名
  2. 随后执行的shadowJar任务因为设置了classifier = null,生成的JAR文件名和默认JAR完全一致,直接覆盖了已经签名的主JAR文件
  3. 最终验证时,签名对应的是旧的默认JAR内容,而实际文件是shadowJar生成的新文件,因此签名验证失败

解决方案

方案一:直接签名shadowJar产物(推荐,因为你要将shadowJar作为主产物)

修改签名配置,让signing插件直接签名shadowJar、javadocJar和sourcesJar,同时将shadowJar加入archives artifacts:

signing {
    sign tasks.shadowJar, tasks.javadocJar, tasks.sourcesJar
}

// ... 其他配置保持不变

artifacts {
    archives shadowJar, javadocJar, sourcesJar
}

Gradle会自动处理签名任务和shadowJar的依赖顺序,确保先生成shadowJar再签名。

方案二:避免shadowJar覆盖默认JAR

如果需要保留默认JAR的签名,修改shadowJar的classifier,避免和默认JAR重名:

shadowJar {
    // 给shadowJar设置独立的classifier,避免覆盖默认jar
    classifier = 'shadow'
    exclude 'META-INF'
    exclude 'META-INF/*.INF'
    exclude 'META-INF/license/*'
}

这样默认JAR和shadowJar会以不同文件名共存,签名验证都会正常通过。

内容的提问来源于stack exchange,提问作者feroze

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 03:40:19