Android库发布Maven Central失败(400错误),请求协助排查
MavenCentral发布Compose Android库失败(400 Bad Request)排查方案
我开发了一款基于Compose的Android库,能正常发布到本地.m2/repository目录并使用,但发布到MavenCentral时失败,报错400 Bad Request。以下是我的build.gradle配置和报错日志,需要找出问题根源并解决。
原配置文件
plugins { id("com.android.library") id("org.jetbrains.kotlin.android") id("signing") id("maven-publish") } // Configure the signing block signing { val signingKey: String? by project val signingPassword: String? by project useInMemoryPgpKeys(signingKey, signingPassword) } android { namespace = "com.gk.image_preview" compileSdk = 34 defaultConfig { minSdk = 24 testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" consumerProguardFiles("consumer-rules.pro") } buildTypes { release { isMinifyEnabled = false proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro" ) } } compileOptions { sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 } kotlinOptions { jvmTarget = "1.8" } buildFeatures { compose = true } composeOptions { kotlinCompilerExtensionVersion = "1.5.1" } // afterEvaluate { // android.libraryVariants.forEach { libraryVariant -> // publishing.publications.create(libraryVariant.name, MavenPublication::class.java) { // from(components.getByName(libraryVariant.name)) // groupId = "io.github.cypher103360" // artifactId = "image-preview" // version = "1.0.0" // } // } // } } afterEvaluate { publishing { publications { create<MavenPublication>("release") { from(components["release"]) groupId = "io.github.cypher103360" artifactId = "image-preview" version = "1.0.0" pom { name = artifactId description = "This is the image preview library." scm { connection = "scm:git@github.com:Cypher103360/MyLibrary.git" url = "https://github.com/Cypher103360/MyLibrary.git" } developers { developer { id = "cypher103360" name = "Gaurav" email = "gk3854631@gmail.com" } } } } } repositories { maven { name = "MyImagePreviewSnapshot" url = uri("https://s01.oss.sonatype.org/content/repositories/snapshots/") credentials { username = project.findProperty("ossrhUsername")?.toString() password = project.findProperty("ossrhPassword")?.toString() } } maven { name = "imagePreview" url = uri("https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/") credentials { username = project.findProperty("ossrhUsername")?.toString() password = project.findProperty("ossrhPassword")?.toString() } } } } } dependencies { implementation("androidx.core:core-ktx:1.12.0") implementation("androidx.appcompat:appcompat:1.6.1") implementation("com.google.android.material:material:1.10.0") testImplementation("junit:junit:4.13.2") androidTestImplementation("androidx.test.ext:junit:1.1.5") androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1") implementation(platform("androidx.compose:compose-bom:2023.08.00")) implementation("androidx.compose.ui:ui") implementation("androidx.compose.ui:ui-graphics") implementation("androidx.compose.ui:ui-tooling-preview") implementation("androidx.compose.material3:material3") }
报错日志
> Configure project :image-preview Kotlin DSL property assignment is an incubating feature. > Task :image-preview:publishReleasePublicationToImagePreviewRepository FAILED FAILURE: Build failed with an exception. * What went wrong: Execution failed for task ':image-preview:publishReleasePublicationToImagePreviewRepository'. > Failed to publish publication 'release' to repository 'imagePreview' > Could not PUT 'https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/io/github/cypher103360/image-preview/1.0.1-SNAPSHOT/maven-metadata.xml'. Received status code 400 from server: Bad Request * Try: > Run with --stacktrace option to get the stack trace. > Run with --info or --debug option to get more log output. > Run with --scan to get full insights. > Get more help at https://help.gradle.org. BUILD FAILED in 4s 26 actionable tasks: 23 executed, 2 from cache, 1 up-to-date
问题根源分析
版本类型与仓库不匹配:报错中版本是
1.0.1-SNAPSHOT,但你试图将快照版本上传到正式staging仓库(service/local/staging/deploy/maven2/),该仓库仅接受不带-SNAPSHOT的正式版本,快照版本必须上传到专门的快照仓库(content/repositories/snapshots/)。签名配置不完整:原配置仅加载了PGP密钥,但未指定对发布产物签名,MavenCentral要求所有构件必须签名才能通过审核。
POM信息缺失必填项:原POM未声明许可证信息,这是MavenCentral强制要求的,即使当前报错未触发,后续仓库验证也会失败。
修复后的完整配置
plugins { id("com.android.library") id("org.jetbrains.kotlin.android") id("signing") id("maven-publish") } android { namespace = "com.gk.image_preview" compileSdk = 34 defaultConfig { minSdk = 24 testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" consumerProguardFiles("consumer-rules.pro") } buildTypes { release { isMinifyEnabled = false proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro" ) } } compileOptions { sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 } kotlinOptions { jvmTarget = "1.8" } buildFeatures { compose = true } composeOptions { kotlinCompilerExtensionVersion = "1.5.1" } } // 签名配置:自动对所有发布产物签名 signing { val signingKey: String? by project val signingPassword: String? by project useInMemoryPgpKeys(signingKey, signingPassword) sign(publishing.publications) } afterEvaluate { publishing { publications { create<MavenPublication>("release") { from(components["release"]) groupId = "io.github.cypher103360" artifactId = "image-preview" // 正式版本去掉-SNAPSHOT,快照版本需上传到对应仓库 version = "1.0.0" pom { name = artifactId description = "This is the image preview library." // 新增必填许可证信息 licenses { license { name = "The Apache License, Version 2.0" url = "http://www.apache.org/licenses/LICENSE-2.0.txt" distribution = "repo" } } scm { connection = "scm:git@github.com:Cypher103360/MyLibrary.git" url = "https://github.com/Cypher103360/MyLibrary.git" } developers { developer { id = "cypher103360" name = "Gaurav" email = "gk3854631@gmail.com" } } } } } repositories { maven { name = "MyImagePreviewSnapshot" url = uri("https://s01.oss.sonatype.org/content/repositories/snapshots/") credentials { username = project.findProperty("ossrhUsername")?.toString() password = project.findProperty("ossrhPassword")?.toString() } } maven { name = "imagePreview" url = uri("https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/") credentials { username = project.findProperty("ossrhUsername")?.toString() password = project.findProperty("ossrhPassword")?.toString() } } } } } dependencies { implementation("androidx.core:core-ktx:1.12.0") implementation("androidx.appcompat:appcompat:1.6.1") implementation("com.google.android.material:material:1.10.0") testImplementation("junit:junit:4.13.2") androidTestImplementation("androidx.test.ext:junit:1.1.5") androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1") implementation(platform("androidx.compose:compose-bom:2023.08.00")) implementation("androidx.compose.ui:ui") implementation("androidx.compose.ui:ui-graphics") implementation("androidx.compose.ui:ui-tooling-preview") implementation("androidx.compose.material3:material3") }
发布操作说明
- 发布正式版本:确保版本号不带
-SNAPSHOT,执行命令:./gradlew publishReleasePublicationToImagePreviewRepository - 发布快照版本:修改版本号为
1.0.1-SNAPSHOT,执行命令:./gradlew publishReleasePublicationToMyImagePreviewSnapshotRepository
额外检查项
- 确认
ossrhUsername和ossrhPassword已在local.properties或系统环境变量中正确配置 - 确认PGP公钥已上传到公共密钥服务器(如keyserver.ubuntu.com),Sonatype需验证签名有效性
- 确认Sonatype平台上的
io.github.cypher103360groupId已通过审核(GitHub账号关联验证)
内容的提问来源于stack exchange,提问作者Cypher
相关产品推荐
相关产品推荐

