skip to Main Content

I have a Kotlin Multiplatform Mobile library that I published to Maven Central. I am also trying to use this library in a non-KMM Android app. When I declare the dependency in the android app I get this error

Execution failed for task ':app:checkDebugAarMetadata'.
> Could not resolve all files for configuration ':app:debugRuntimeClasspath'.
   > Could not resolve io.github.tyczj:tweedle-android:0.3.0.
     Required by:
         project :app
      > No matching variant of io.github.tyczj:tweedle-android:0.3.0 was found. The consumer was configured to find a runtime of a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'debug', attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm' but:
          - Variant 'commonMainMetadataElements-published' capability io.github.tyczj:tweedle-android:0.3.0:
              - Incompatible because this component declares a usage of 'kotlin-api' of a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'common' and the consumer needed a runtime of a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm'
              - Other compatible attribute:
                  - Doesn't say anything about com.android.build.api.attributes.BuildTypeAttr (required 'debug')
          - Variant 'metadataApiElements-published' capability io.github.tyczj:tweedle-android:0.3.0:
              - Incompatible because this component declares a usage of 'kotlin-metadata' of a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'common' and the consumer needed a runtime of a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm'
              - Other compatible attribute:
                  - Doesn't say anything about com.android.build.api.attributes.BuildTypeAttr (required 'debug')
          - Variant 'releaseApiElements-published' capability io.github.tyczj:tweedle-android:0.3.0 declares a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm':
              - Incompatible because this component declares an API of a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'release' and the consumer needed a runtime of a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'debug'
          - Variant 'releaseRuntimeElements-published' capability io.github.tyczj:tweedle-android:0.3.0 declares a runtime of a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm':
              - Incompatible because this component declares a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'release' and the consumer needed a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'debug'

I assume something is wrong with my configuration but I dont really know what that error is telling me, this is my first time creating a KMM library.

Here is my build.gradle.kts

import org.gradle.api.tasks.bundling.Jar

plugins {
    kotlin("multiplatform")
    id("com.android.library")
    id("kotlin-android-extensions")
    id("kotlinx-serialization")
    id("maven-publish")
    id("signing")
}

repositories {
    gradlePluginPortal()
    google()
    mavenCentral()
}

val javadocJar by tasks.registering(Jar::class) {
    archiveClassifier.set("javadoc")
}

group = "io.github.tyczj"
version = "0.3.0"

kotlin {
    android{
        publishLibraryVariants("release")
    }
    ios {
        binaries {
            framework {
                baseName = "tweedle"
            }
        }
    }
    sourceSets {
        val commonMain by getting {
            dependencies {
                implementation("io.ktor:ktor-client-core:1.5.1")
                implementation("io.ktor:ktor-client-json:1.5.1")
                implementation("io.ktor:ktor-client-serialization:1.5.1")
                implementation("io.ktor:ktor-client-logging:1.5.1")
                implementation("ch.qos.logback:logback-classic:1.2.3")
//                implementation("com.squareup.okio:okio:2.10.0")
                implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.2-native-mt"){
                    version {
                        strictly("1.4.2-native-mt")
                    }
                }
            }
        }
        val commonTest by getting {
            dependencies {
                implementation(kotlin("test-common"))
                implementation(kotlin("test-annotations-common"))
            }
        }
        val androidMain by getting {
            dependencies {
                implementation("androidx.core:core-ktx:1.3.2")
                implementation("io.ktor:ktor-client-android:1.5.1")
                implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.2-native-mt")
                implementation("com.github.scribejava:scribejava-apis:8.3.0")
            }
        }
        val androidTest by getting {
            dependencies {
                implementation(kotlin("test-junit"))
                implementation("junit:junit:4.12")
            }
        }
        val iosMain by getting {
            dependencies {
                implementation("io.ktor:ktor-client-ios:1.5.1")
            }
        }
//        val iosTest by getting
    }
}

android {
    compileSdkVersion(30)
    sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml")
    defaultConfig {
        minSdkVersion(26)
        targetSdkVersion(30)
        versionCode = 1
        versionName = "1.0"
    }
    buildTypes {
        getByName("release") {
            isMinifyEnabled = false
        }
    }

    packagingOptions {
        excludes.add("META-INF/*.kotlin_module")
    }
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    }
    tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>().all {
        kotlinOptions {
            jvmTarget = "1.8"
        }
    }
}

afterEvaluate {
    publishing {
        repositories {
            maven {
                name = "sonatype"
                url = uri("https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/")
                credentials {
                    username = rootProject.ext["ossrhUsername"]?.toString()
                    password = rootProject.ext["ossrhPassword"]?.toString()
                }
            }
        }

        publications.withType<MavenPublication> {

            artifact(javadocJar.get())

            pom{
                name.set("Tweedle")
                description.set("Tweedle is an Android library built around the Twitter v2 API built fully in Kotlin using Kotlin Coroutines")
                url.set("https://github.com/tyczj/Tweedle")
                licenses {
                    license {
                        name.set("MIT")
                        url.set("https://opensource.org/licenses/MIT")
                    }
                }
                developers {
                    developer {
                        id.set("tyczj")
                        name.set("Jeff Tycz")
                        email.set("[email protected]")
                    }
                }
                scm {
                    url.set("https://github.com/tyczj/Tweedle")
                }
            }
        }
    }
}

val packForXcode by tasks.creating(Sync::class) {
    group = "build"
    val mode = System.getenv("CONFIGURATION") ?: "DEBUG"
    val sdkName = System.getenv("SDK_NAME") ?: "iphonesimulator"
    val targetName = "ios" + if (sdkName.startsWith("iphoneos")) "Arm64" else "X64"
    val framework =
        kotlin.targets.getByName<org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget>(
            targetName
        ).binaries.getFramework(mode)
    inputs.property("mode", mode)
    dependsOn(framework.linkTask)
    val targetDir = File(buildDir, "xcode-frameworks")
    from({ framework.outputDirectory })
    into(targetDir)
}
tasks.getByName("build").dependsOn(packForXcode)

ext["signing.keyId"] = rootProject.ext["signing.keyId"]?.toString()
ext["signing.password"] = rootProject.ext["signing.password"]?.toString()
ext["signing.secretKeyRingFile"] = rootProject.ext["signing.secretKeyRingFile"]?.toString()

signing {
    sign(publishing.publications)
}

What do I need to do to be able to use the android dependency (io.github.tyczj:tweedle-android) in a non-KMM android app?

Update

I tried adding "debug" to android library variants

android{
    publishLibraryVariants("release", "debug")
}

as well as adding fallbacks

buildTypes {
    getByName("release") {
        isMinifyEnabled = false
    }
    val staging by creating{
        setMatchingFallbacks(listOf("release", "debug"))
    }
}

and that didnt do anything

If I create a new KMM project and just try to add the dependency I get somewhat of a different error saying

Failed building KotlinMPPGradleModel
org.gradle.internal.resolve.ArtifactNotFoundException: Could not find tweedle-android-0.3.1-samplessources.jar (io.github.tyczj:tweedle-android:0.3.1).

2

Answers


  1. I guess you publish library as aar. In this case you should explicitly add @aar to gradle dependency

    implementation 'io.github.tyczj:tweedle-android:0.3.0@aar'
    
    Login or Signup to reply.
  2. The error message referencing "samplessources" comes up when you include a dependency that’s not built for the correct platforms. There’s some discussion in this youtrack issue, as well as this other issue around emitting a better error message in this case.

    In your case, it’s presumably being triggered by implementation("ch.qos.logback:logback-classic:1.2.3") in your common dependencies. This is a JVM library, but you have an iOS target so it won’t work in your common dependencies. Move it to your Android dependencies instead.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search