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}"] ] ) } } }
可行解决思路
按排查成本从低到高排序:
先做基础参数校验,排除低级错误
- 不要直接用
readMavenPom读取的动态值拼接参数,先在上传步骤前加sh 'ls -l target/'打印target目录下的实际产物文件名,和拼接出的文件路径做比对:常见问题包括子模块packaging字段未正确继承为空、SNAPSHOT版本被Maven自动加了时间戳后缀、路径拼接多了或少了字符,老版本插件找不到文件时只会抛通用上传失败错误,不会提示文件不存在。 - 校验Nexus地址配置:确认
nexusUrl是否漏写上下文路径,很多企业部署Nexus会加/nexus前缀,实际访问地址为http://nexus.something.com/nexus,漏写前缀会导致请求打到错误路径,老版本插件不会打印HTTP响应码,直接报通用错误。 - 临时把所有GAV参数、文件路径硬编码做测试,如果硬编码能上传成功,就是动态参数读取的问题。
- 不要直接用
开启插件DEBUG日志拿到具体报错
老版本NexusArtifactUploader默认日志级别为INFO,会吞掉所有HTTP请求细节(包括401鉴权失败、403无仓库写权限、400版本策略不匹配、连接超时等)。进入Jenkins系统管理-系统日志,新增日志记录器,添加日志路径org.jenkinsci.plugins.nexusartifactuploader,日志级别设置为ALL,重跑流水线即可看到完整的请求响应信息,直接定位根因。适配插件版本解决兼容性问题
本地最新版Jenkins运行正常、生产老版本Jenkins运行失败,大概率是生产环境安装的NexusArtifactUploader版本过高,和2.222.4版本的Jenkins核心存在API兼容问题。查询插件的版本发布时间,选择和Jenkins 2.222.4(2020年中发布)发布时间匹配的历史版本,手动下载hpi安装包上传到生产Jenkins安装,不要使用最新版插件。绕过插件直接上传,彻底规避兼容问题
不需要死磕第三方插件,直接用原生能力实现上传,稳定性更高:- 方案一:使用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命令即可使用。
- 方案一:使用Maven原生deploy命令,通过Config File Provider插件托管Maven的settings.xml配置,在settings.xml中配置Nexus仓库地址与对应凭证,流水线中直接执行
内容的提问来源于stack exchange,提问作者Swapnil Shrishrimal
相关产品推荐
相关产品推荐

