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

Jenkins声明式流水线Maven项目NexusArtifactUploader上传失败

问题环境与现象
  • 生产部署版本:Jenkins 2.222.4、Nexus 3.X、NexusArtifactUploader插件
  • 故障表现:Maven项目通过声明式流水线可正常完成构建,执行到制品上传阶段直接失败,仅抛出错误Error: Uploading file filename.jar failed,无额外辅助定位的错误日志
  • 已验证情况:
    • 先后尝试两种NexusArtifactUploader配置写法,均触发相同错误
    • 本地环境使用最新版Jenkins搭配同插件执行相同上传操作可成功
    • 受环境限制,暂时无法升级Jenkins版本,也无法替换使用Sonatype Nexus Platform Plugin
    • 官方说明NexusArtifactUploader并非专门为Maven制品上传场景设计

已尝试的两种配置写法如下:
第一种:

stage('Upload Nexus Artifact') {
 steps {
     script {
         def pom = readMavenPom file: 'pom.xml'
         nexusArtifactUploader artifacts: [[artifactId: "${pom.artifactId}", classifier: '', file: "target/${pom.artifactId}-${pom.version}.${pom.packaging}", type: "${pom.packaging}"]], credentialsId: 'Here_Is_The_Creds', groupId: "${pom.groupId}", nexusUrl: 'nexus.something.com', nexusVersion: 'nexus3', protocol: 'http', repository: 'maven-snapshots', version: "${pom.version}"
     }
 }
}

第二种:

stage('Upload Nexus Artifact') {
steps {
script {
def pom = readMavenPom file: 'pom.xml'

         nexusArtifactUploader(
                 nexusVersion: 'nexus3',
                 protocol: 'http',
                 nexusUrl: 'nexus.something.com',
                 groupId: "${pom.groupId}",
                 version: "${pom.version}",
                 repository: 'maven-snapshots',
                 credentialsId: 'Here_Is_The_Creds',
                 artifacts: [
                     [artifactId: "${pom.artifactId}",
                     file: "target/${pom.artifactId}-${pom.version}.${pom.packaging}",
                     type: "${pom.packaging}"]
                 ]
         )
     }
 }
}
可行解决思路

按排查成本从低到高排序:

  1. 先做基础参数校验,排除低级错误

    • 不要直接用readMavenPom读取的动态值拼接参数,先在上传步骤前加sh 'ls -l target/'打印target目录下的实际产物文件名,和拼接出的文件路径做比对:常见问题包括子模块packaging字段未正确继承为空、SNAPSHOT版本被Maven自动加了时间戳后缀、路径拼接多了或少了字符,老版本插件找不到文件时只会抛通用上传失败错误,不会提示文件不存在。
    • 校验Nexus地址配置:确认nexusUrl是否漏写上下文路径,很多企业部署Nexus会加/nexus前缀,实际访问地址为http://nexus.something.com/nexus,漏写前缀会导致请求打到错误路径,老版本插件不会打印HTTP响应码,直接报通用错误。
    • 临时把所有GAV参数、文件路径硬编码做测试,如果硬编码能上传成功,就是动态参数读取的问题。
  2. 开启插件DEBUG日志拿到具体报错
    老版本NexusArtifactUploader默认日志级别为INFO,会吞掉所有HTTP请求细节(包括401鉴权失败、403无仓库写权限、400版本策略不匹配、连接超时等)。进入Jenkins系统管理-系统日志,新增日志记录器,添加日志路径org.jenkinsci.plugins.nexusartifactuploader,日志级别设置为ALL,重跑流水线即可看到完整的请求响应信息,直接定位根因。

  3. 适配插件版本解决兼容性问题
    本地最新版Jenkins运行正常、生产老版本Jenkins运行失败,大概率是生产环境安装的NexusArtifactUploader版本过高,和2.222.4版本的Jenkins核心存在API兼容问题。查询插件的版本发布时间,选择和Jenkins 2.222.4(2020年中发布)发布时间匹配的历史版本,手动下载hpi安装包上传到生产Jenkins安装,不要使用最新版插件。

  4. 绕过插件直接上传,彻底规避兼容问题
    不需要死磕第三方插件,直接用原生能力实现上传,稳定性更高:

    • 方案一:使用Maven原生deploy命令,通过Config File Provider插件托管Maven的settings.xml配置,在settings.xml中配置Nexus仓库地址与对应凭证,流水线中直接执行mvn deploy完成上传,该方式为Maven原生能力,和Jenkins版本无绑定关系。
    • 方案二:通过curl调用Nexus原生API上传,完全不依赖任何Nexus相关Jenkins插件,示例流水线代码如下:
    stage('Upload Nexus Artifact') {
      steps {
        script {
          def pom = readMavenPom file: 'pom.xml'
          def uploadPath = "${pom.groupId.replace('.', '/')}/${pom.artifactId}/${pom.version}/${pom.artifactId}-${pom.version}.${pom.packaging}"
          def localFile = "target/${pom.artifactId}-${pom.version}.${pom.packaging}"
          
          if (!fileExists(localFile)) {
            error("待上传文件不存在,路径:${localFile}")
          }
          
          withCredentials([usernamePassword(credentialsId: 'Here_Is_The_Creds', usernameVariable: 'NEXUS_USER', passwordVariable: 'NEXUS_PASS')]) {
            sh """
              curl -f -u ${NEXUS_USER}:${NEXUS_PASS} \
                --upload-file ${localFile} \
                "http://nexus.something.com/repository/maven-snapshots/${uploadPath}"
            """
          }
        }
      }
    }
    

    该方式所有请求错误都会直接打印在流水线控制台,不会出现日志被吞的问题,只要Jenkins节点有curl命令即可使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 18:22:47