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

Gradle发布Android库至Sonatype时随机文件报401未授权错误

Android库发布至Sonatype时随机出现401未授权错误

尝试将Android库发布至https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/,但每次任务都会因某一文件的PUT请求返回401未授权错误而失败,且每次失败的文件都不相同。16次尝试中失败的文件包括:

  • caimito-2.0.1-sources.jar.asc
  • caimito-2.0.2.module.asc
  • caimito-2.0.2-sources.jar.asc.md5
  • caimito-2.0.2.module.asc.sha1
  • caimito-2.0.2.pom.asc
  • caimito-2.0.2.module.md5
  • caimito-2.0.2-sources.jar.sha1
  • caimito-2.0.2-sources.jar
  • caimito-2.0.2.aar.asc.md5

曾成功发布过一次,但当时失败的是Sonatype不需要的MD5文件,这显然不是理想状态,希望找出问题根源。以下是构建文件:

主构建文件(build.gradle)

plugins {
    id("com.android.library")
    id("org.jetbrains.kotlin.android")
}

android {
    namespace = "dev.gravitycode.caimito"
    compileSdk = 34

    defaultConfig {
        minSdk = 26
        // targetSdk = 34
        testOptions.targetSdk = 34
        lint.targetSdk = 34

        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            isMinifyEnabled = false
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguard-rules.pro"
            )
        }
    }

    publishing {
        singleVariant("release") {
            withSourcesJar()
            // withJavadocJar()
        }
    }

    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    }

    composeOptions {
        kotlinCompilerExtensionVersion = "1.5.10"
    }

    buildFeatures {
        buildConfig = true
        compose = true
    }

    kotlinOptions {
        jvmTarget = "1.8"
    }
}

dependencies {

    // AndroidX
    implementation("androidx.core:core-ktx:1.12.0")
    implementation("androidx.appcompat:appcompat:1.6.1")

    // Material Design
    implementation("com.google.android.material:material:1.11.0")

    // Google Guava
    implementation("com.google.guava:guava:33.0.0-android")

    // Jetbrains Annotations
    implementation("org.jetbrains:annotations:24.1.0")

    // Data Store
    implementation("androidx.datastore:datastore-preferences:1.0.0")

    // Compose
    implementation("androidx.activity:activity-compose:1.8.2")
    implementation("androidx.lifecycle:lifecycle-runtime-compose:2.7.0")
    implementation(platform("androidx.compose:compose-bom:2024.03.00"))
    implementation("androidx.compose.ui:ui")
    implementation("androidx.compose.ui:ui-graphics")
    implementation("androidx.compose.ui:ui-tooling-preview")
    implementation("androidx.compose.material3:material3")
    debugImplementation("androidx.compose.ui:ui-tooling")

    testImplementation("junit:junit:4.13.2")

    androidTestImplementation("androidx.test.ext:junit:1.1.5")
    androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
}

apply(from = "../publish-package.gradle")

publish-package.gradle

apply plugin: 'maven-publish'
apply plugin: 'signing'

afterEvaluate {
    publishing {
        publications {
            release(MavenPublication) {
                groupId = 'dev.gravitycode.caimito'
                artifactId = 'caimito'
                version = '2.0.2'

                // Specify the components to publish
                from components.release

                pom {
                    name = 'caimito'
                    description = 'A small library of helpful classes for working with Android'
                    url = 'https://github.com/abuicke/caimito'

                    licenses {
                        license {
                            name = 'MIT License'
                            url = 'https://opensource.org/licenses/MIT'
                        }
                    }

                    developers {
                        developer {
                            id = 'adambuicke'
                            name = 'Adam Buicke'
                            email = 'buickea@gmail.com'
                        }
                    }

                    scm {
                        connection = 'scm:git:github.com/abuicke/caimito.git'
                        developerConnection = 'scm:git:ssh://github.com/abuicke/caimito.git'
                        url = 'https://github.com/abuicke/caimito'
                    }
                }
            }
        }

        // Repository configuration
        repositories {
            maven {
                url = uri("https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/")

                credentials {
                    username = project.findProperty("ossrhUsername")
                    password = project.findProperty("ossrhPassword")
                }
            }
        }
    }

    // Signing configuration (if required)
    signing {
        sign publishing.publications.release
    }
}

请问这是Sonatype、Gradle还是我的配置存在问题?


问题排查与解决方案

1. 先排除配置层面的常见问题

  • 凭证验证:确认ossrhUsername和ossrhPassword是正确的Sonatype账号密码,且账号拥有对应groupId的发布权限。可以直接在终端执行简单的curl命令测试凭证有效性:
    curl -u 你的用户名:你的密码 https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/
    
    返回401说明凭证错误;返回403说明账号权限不足;返回200或目录结构则凭证没问题。
  • Gradle版本兼容性:检查当前Gradle版本是否和maven-publish、signing插件存在兼容性问题。建议升级到稳定版Gradle(如8.x系列),同步升级Android Gradle Plugin版本。
  • 签名配置:确认签名密钥配置正确,无密钥过期、路径错误情况。可先注释sign publishing.publications.release关闭签名,测试发布是否稳定完成,排除签名环节干扰。

2. 针对随机401的特殊处理

随机文件失败大概率是并发请求导致的凭证复用问题,或Sonatype负载均衡节点状态不一致,可尝试以下调整:

  • 禁用并行发布:在gradle.properties中添加:
    org.gradle.parallel=false
    
    强制Gradle串行处理文件上传,避免并发引发的凭证失效。
  • 添加HTTP重试机制:在publish-package.gradle的maven仓库配置中增加重试逻辑:
    maven {
        url = uri("https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/")
        credentials {
            username = project.findProperty("ossrhUsername")
            password = project.findProperty("ossrhPassword")
        }
        authentication {
            basic(BasicAuthentication)
        }
        httpClient {
            maxConnections = 1
            retryHandler {
                retryOnServerErrors = true
                numberOfRetries = 3
            }
        }
    }
    
  • 切换Sonatype端点:尝试使用旧端点https://oss.sonatype.org/service/local/staging/deploy/maven2/,排查s01节点的特殊问题。

3. Sonatype端的可能原因

  • 临时节点故障:Sonatype的s01集群个别节点可能存在认证服务异常,可稍后重试或查看Sonatype状态页面确认服务状态。
  • IP限制:若网络IP频繁变动,可能触发Sonatype限流或认证拦截,建议使用固定IP或VPN尝试发布。

总结

优先排查凭证和权限问题,再通过禁用并行、添加重试解决并发导致的随机失败。若以上无效,考虑Sonatype临时故障,或提交工单咨询Sonatype支持。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 02:34:57