What happened?
On Android, depending on the A2A Java client fails AGP's checkDuplicateClasses because a2a-java-sdk-common and a2a-java-sdk-spec both ship a byte-identical org/a2aproject/sdk/util/package-info.class.
How to reproduce
A minimal Android project (verified with Android Gradle Plugin 9.2.1, Gradle 9.6.1):
settings.gradle.kts
pluginManagement {
repositories { google(); mavenCentral(); gradlePluginPortal() }
}
dependencyResolutionManagement {
repositories { google(); mavenCentral() }
}
include(":app")
build.gradle.kts
plugins { id("com.android.application") version "9.2.1" apply false }
gradle.properties
app/build.gradle.kts
plugins { id("com.android.application") }
android {
namespace = "com.example.a2arepro"
compileSdk = 34
defaultConfig { minSdk = 26 }
}
dependencies {
implementation("org.a2aproject.sdk:a2a-java-sdk-client:1.0.0.Final")
}
app/src/main/AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android" />
Then run:
./gradlew :app:checkDebugDuplicateClasses
The build fails with the duplicate class shown below. (checkDuplicateClasses is a standard AGP task that also runs during any normal build, e.g. :app:assembleDebug.) Reproduced on both 1.0.0.Final and 1.1.0.Final.
Cause
org.a2aproject.sdk.util is a split package — real classes live in both modules (common: Assert, HttpHeaderUtils, NotNull; spec: Utils, ErrorDetail, PageToken) — and each ships its own package-info.java (@NullMarked), so both jars contain a duplicate package-info.class. It's unavoidable for consumers: spec depends on common, and the client/http-client/transports all depend on spec, so both jars are always on the Android classpath.
Expected
An Android app should be able to depend on the A2A Java client without a duplicate-class build failure.
Relevant log output
> Task :app:checkDebugDuplicateClasses FAILED
> A failure occurred while executing com.android.build.gradle.internal.tasks.CheckDuplicatesRunnable
> Duplicate class org.a2aproject.sdk.util.package-info found in modules a2a-java-sdk-common-1.0.0.Final.jar -> a2a-java-sdk-common-1.0.0.Final (org.a2aproject.sdk:a2a-java-sdk-common:1.0.0.Final) and a2a-java-sdk-spec-1.0.0.Final.jar -> a2a-java-sdk-spec-1.0.0.Final (org.a2aproject.sdk:a2a-java-sdk-spec:1.0.0.Final)
Code of Conduct
What happened?
On Android, depending on the A2A Java client fails AGP's
checkDuplicateClassesbecausea2a-java-sdk-commonanda2a-java-sdk-specboth ship a byte-identicalorg/a2aproject/sdk/util/package-info.class.How to reproduce
A minimal Android project (verified with Android Gradle Plugin 9.2.1, Gradle 9.6.1):
settings.gradle.ktspluginManagement { repositories { google(); mavenCentral(); gradlePluginPortal() } } dependencyResolutionManagement { repositories { google(); mavenCentral() } } include(":app")build.gradle.ktsplugins { id("com.android.application") version "9.2.1" apply false }gradle.propertiesandroid.useAndroidX=trueapp/build.gradle.ktsplugins { id("com.android.application") } android { namespace = "com.example.a2arepro" compileSdk = 34 defaultConfig { minSdk = 26 } } dependencies { implementation("org.a2aproject.sdk:a2a-java-sdk-client:1.0.0.Final") }app/src/main/AndroidManifest.xmlThen run:
The build fails with the duplicate class shown below. (
checkDuplicateClassesis a standard AGP task that also runs during any normal build, e.g.:app:assembleDebug.) Reproduced on both 1.0.0.Final and 1.1.0.Final.Cause
org.a2aproject.sdk.utilis a split package — real classes live in both modules (common: Assert, HttpHeaderUtils, NotNull;spec: Utils, ErrorDetail, PageToken) — and each ships its ownpackage-info.java(@NullMarked), so both jars contain a duplicatepackage-info.class. It's unavoidable for consumers:specdepends oncommon, and the client/http-client/transports all depend onspec, so both jars are always on the Android classpath.Expected
An Android app should be able to depend on the A2A Java client without a duplicate-class build failure.
Relevant log output
Code of Conduct