Search code examples
kotlinkotlin-multiplatformkotlin-native

Kotlin Multiplatform. Cannot access class SqlDriver.Schema. Check your module classpath for missing or conflicting dependencies


I am trying to build a KMP library targeting iOS, Android, JS(Browser), Mac, Windows and Linux. For now I am only using Ktor and SQLDelight as a dependency. But getting the following issue in nativeMain's actual implementation while creating driver for SQLDelight

SQLDelight Native driver

While the same code doesn't give any issue for iOS main which is also using the same NativeSqliteDriver (I need them separately since Ktor client for iOS and desktop platforms are separate). Following is my build.gradle.kts

plugins {
    kotlin("multiplatform") version "1.5.31"
    id("maven-publish")
    id("com.android.library")
    kotlin("plugin.serialization") version "1.5.31"
    id("com.squareup.sqldelight") version "1.5.3"
}

group = "me.group"
version = "1.0-SNAPSHOT"

val xcFrameworkName = "AddressLib"

repositories {
    google()
    mavenCentral()
}

kotlin {
    jvm {
        compilations.all {
            kotlinOptions.jvmTarget = "1.8"
        }
        testRuns["test"].executionTask.configure {
            useJUnit()
        }
    }
    js(LEGACY) {
        browser {
            commonWebpackConfig {
                cssSupport.enabled = true
            }
        }
    }

    val xcFramework = XCFramework(xcFrameworkName)

    val hostOs = System.getProperty("os.name")
    val isMingwX64 = hostOs.startsWith("Windows")
    when {
        hostOs == "Mac OS X" -> macosX64("native") {
            binaries.framework(xcFrameworkName) {
                xcFramework.add(this)
            }
        }
        hostOs == "Linux" -> linuxX64("native")
        isMingwX64 -> mingwX64("native")
        else -> throw GradleException("Host OS is not supported in Kotlin/Native.")
    }

    android()

    ios {
        binaries.framework(xcFrameworkName) {
            xcFramework.add(this)
        }
    }

    val coroutinesVersion = "1.5.2-native-mt"
    val serializationVersion = "1.3.1"
    val ktorVersion = "1.6.5"
    val sqlDelightVersion = "1.5.3"
    val napierVersion = "2.2.0"
    val koinVersion = "3.1.4"

    sourceSets {
        val commonMain by getting {
            dependencies {
                implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesVersion")
                implementation("org.jetbrains.kotlinx:kotlinx-serialization-core:$serializationVersion")

                implementation("io.ktor:ktor-client-core:$ktorVersion")
                implementation("io.ktor:ktor-client-serialization:$ktorVersion")
                implementation("io.ktor:ktor-client-logging:$ktorVersion")

                implementation("com.squareup.sqldelight:runtime:$sqlDelightVersion")
                implementation("io.insert-koin:koin-core:$koinVersion")

                implementation("io.github.aakira:napier:$napierVersion")
            }
        }
        val commonTest by getting
        val jvmMain by getting {
            dependencies {
                implementation("io.ktor:ktor-client-java:$ktorVersion")
                implementation("com.squareup.sqldelight:sqlite-driver:$sqlDelightVersion")
            }
        }
        val jvmTest by getting
        val jsMain by getting {
            dependencies {
                implementation("io.ktor:ktor-client-js:$ktorVersion")
                implementation("com.squareup.sqldelight:sqljs-driver:$sqlDelightVersion")
            }
        }
        val jsTest by getting
        val nativeMain by getting {
            dependencies {
                implementation("io.ktor:ktor-client-curl:$ktorVersion")
                implementation("com.squareup.sqldelight:native-driver:$sqlDelightVersion")
            }
        }
        val nativeTest by getting
        val androidMain by getting {
            dependencies {
                implementation("io.ktor:ktor-client-android:$ktorVersion")
                implementation("com.squareup.sqldelight:android-driver:$sqlDelightVersion")
            }
        }
        val androidTest by getting {
            dependencies {
                implementation(kotlin("test-junit"))
                implementation("junit:junit:4.13.2")
            }
        }
        val iosMain by getting {
            dependencies {
                implementation("io.ktor:ktor-client-ios:$ktorVersion")
                implementation("com.squareup.sqldelight:native-driver:$sqlDelightVersion")
            }
        }
        val iosTest by getting
    }

    sqldelight {
        database("AddressDatabase") {
            packageName = "com.library.address.database"
        }
    }
}

android {
    compileSdkVersion(31)
    sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml")
    defaultConfig {
        minSdkVersion(24)
        targetSdkVersion(31)
    }
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    }
}

publishing {
    repositories {
        maven {
            credentials {
                username = "<username>"
                password = "<pwd>"
            }
            url = URI("https://mymavenrepo.com")
        }
    }
}

Solution

  • So it seems the issue was somewhat due to same dependency being added to the build gradle twice and it's corresponding code being added twice as well. To solve the same I had to make a separate source set like the following

    val sqlDriverNativeMain by creating {
        dependsOn(commonMain)
        dependencies {
            implementation("com.squareup.sqldelight:native-driver:$sqlDelightVersion")
        }
    }
    val iosMain by getting {
        dependsOn(sqlDriverNativeMain)
        dependencies {
            implementation("io.ktor:ktor-client-ios:$ktorVersion")
        }
    }
    val nativeMain by getting {
       dependsOn(sqlDriverNativeMain)
       dependencies {
           implementation("io.ktor:ktor-client-curl:$ktorVersion")
        }
    }
    

    and after that move the driver creation code inside the sourceSet directory named sqlDriverNativeMain. This resolved the issue.