I’m facing an issue with multiplatform project dep...
# multiplatform
i
I’m facing an issue with multiplatform project dependencies in my ktor plugins project, and i don’t know if it’s expected behaviour, a limitation or a bug Here’s the deal. I have a task scheduler plugin. It has: • a core module that defines the the plugin itself, configurations, and abstractions, targeting jvm and native • a module for providing locking using redis, targeting jvm and native (the redis client is an expect class that in jvm is actualised by Kreds (kotlin/jvm SDK) and in native is actualised by interop with hiredis (c SDK) • a module for providing locking with jdbc (exposed) targeting jvm only • a module for providing locking with mongodb, targeting jvm only My issue is that when i add the core project as dependency in the jdbc/mongo modules, the abstractions defined there (in commonMain) are not available in jvmMain. they are available in commonMain, but obviously the exposed stuff isnt. If that dependency (core) would have been a published library, the platform specific artifact would be automatically resolved. It seems though that in this case, as it’s a project dependency, that’s not happening. See details in thread -->
@Jacob Ras I’m sorry i’m not familiar with the intention behind the “thread please” reaction
j
@Ido Flax your post is very long, reducing visibility of the other posts here (as does the one above yours). What people usually do is write a short summary in the main post and then post all the lengthy details in the thread (which is where your reply is) 🙂
i
Gotcha
👌 1
Project tree:
Copy code
.
├── build.gradle.kts
├── ktor-server-task-scheduler-core
│   ├── build.gradle.kts
│   └── src
│       ├── commonMain
│       ├── commonTest
│       ├── jvmMain
│       ├── jvmTest
│       ├── nativeMain
│       └── nativeTest
├── ktor-server-task-scheduler-jdbc
│   ├── build
│   │   └── tmp
│   ├── build.gradle.kts
│   └── src
│       ├── commonMain
│       ├── commonTest
│       ├── jvmMain
│       └── jvmTest
├── ktor-server-task-scheduler-mongodb
│   ├── build
│   │   └── tmp
│   ├── build.gradle.kts
│   └── src
│       ├── commonMain
│       ├── commonTest
│       ├── jvmMain
│       ├── jvmTest
│       ├── nativeMain
│       └── nativeTest
└── ktor-server-task-scheduler-redis
    ├── build
    │   └── tmp
    ├── build.gradle.kts
    ├── redis-client
    │   ├── build
    │   ├── build.gradle.kts
    │   └── src
    └── src
        ├── commonMain
        ├── commonTest
        ├── jvmMain
        ├── jvmTest
        ├── nativeMain
        └── nativeTest
Core build tree:
Copy code
├── libs
│   ├── core-jvm-1.2.6-sources.jar
│   ├── core-jvm-1.2.6.jar
│   ├── ktor-server-task-scheduler-core-jvm-1.2.6-sources.jar
│   ├── ktor-server-task-scheduler-core-jvm-1.2.6.jar
│   └── ktor-server-task-scheduler-core-metadata-1.2.6.jar
core build:
Copy code
plugins {
    id("ktor-server-plugin-conventions")
    kotlin("plugin.serialization") version libs.versions.kotlin.asProvider().get()
}

kotlin {
    explicitApi()
    sourceSets {
        commonMain {
            dependencies {
                api(libs.krontab)
            }
        }
    }
}
jdbc build:
Copy code
plugins {
    id("ktor-server-plugin-conventions")
}

kotlin {
    explicitApi()
    targets {
        jvm()
    }
    sourceSets {
        commonMain {
            dependencies {
                api(projects.ktorServerTaskScheduler.core)
                implementation(projects.common)
            }
        }
        jvmMain {
            dependencies {
                implementation(libs.exposed.core)
                implementation(libs.exposed.jdbc)
                implementation(libs.exposed.dao)
                implementation(libs.exposed.kotlin.datetime)
            }
        }
        jvmTest {
            dependencies {
                implementation(libs.kotest.extensions.testcontainers)
                implementation(libs.testcontainers)
                implementation(libs.testcontainers.postgres)
                implementation(libs.kotest.property)
            }
        }
    }
}
In the attached image you can see what isn’t available in jdbc/jvmMain (left) vs jdbc/commonMain (right)
d
Could you please report an issue to YouTrack kotl.in/issue? Also, if I’m not mistaken,
ktor-server-plugin-conventions
is your own convention plugin? If yes, knowing what’s inside of it will be necessary for investigating the issue
i
Here’s the gist of the conventions relevant to this:
Copy code
extensions.findByType(KotlinMultiplatformExtension::class)?.apply {
                explicitApi()
                jvm {
                    jvmToolchain(versionOf("java").toInt())
                    tasks.named("jvmJar", Jar::class).configure {
                        duplicatesStrategy = DuplicatesStrategy.EXCLUDE
                        from(
                            listOf(
                                configurations["jvmCompileClasspath"],
                                configurations["jvmRuntimeClasspath"],
                            ).map { it.map { if (it.isDirectory) it else zipTree(it) } },
                        )
                    }
                }

                this.sourceSets.apply {
                    commonMain {
                        dependencies {
                            implementation(library("kotlinx-datetime"))
                            implementation(library("kotlinx-coroutines-core"))
                            implementation(library("arrow-core"))
                            implementation(library("arrow-fx-coroutines"))
                            implementation(library("kotlin-logging"))
                        }
                    }

                    commonTest {
                        dependencies {
                            implementation(kotlin("test"))
                            implementation(library("kotlinx-coroutines-test"))
                            implementation(library("kotest-framework-engine"))
                            implementation(library("kotest-framework-datatest"))
                            implementation(library("kotest-assertions-core"))
                        }
                    }
                    jvmTest {
                        dependencies {
                            implementation(library("kotest-runner-junit5"))
                            implementation(library("logback-classic"))
                            implementation(library("mockk"))
                        }
                    }
                }
                this.conventionSpecifics()
            }

...

override fun KotlinMultiplatformExtension.conventionSpecifics() {
        // Support mac OS?
        // macosArm64()
        // macosX64()
        linuxX64("native")
    nativeTarget.apply {
        binaries {
            sharedLib {
                this.baseName = "ktor"
            }
        }
        configure()
    }
        sourceSets.apply {
            commonMain {
                with(this.project) {
                    dependencies {
                        implementation(library("ktor-server-core"))
                        implementation(library("ktor-server-config-yaml"))
                        implementation(library("ktor-server-auth"))
                    }
                }
            }
            commonTest {
                with(this.project) {
                    dependencies {
                        implementation(library("ktor-server-test-host"))
                        implementation(library("ktor-server-status-pages"))
                    }
                }
            }
        }
I’ll try and reproduce the issue in a minimal project
Not able to reproduce it, so the issue is with my config, i’ll post my findings here once solved
👍 2
so i tracked down the issue to my conventions plugin applying these plugins:
Copy code
apply("org.gradle.java-library")
apply("java-library-distribution")
When i remove them, it seems to work. I still can’t reproduce this in my minimal reproduction project though… @dsavvinov if you have any insight into why that might be the case, i would be curious to know
d
Doesn’t ring the bell, sorry. Is it possible for you to share non-minimized, or a partially minimized reproducer?
i
@dsavvinov, you can checkout this commit: https://github.com/Flaxoos/extra-ktor-plugins/tree/a244c44c8fa678fe3cd4e60e4ea7d3ea435afeeb In Conventions.kt, uncomment these:
Copy code
open class Conventions : Plugin<Project> {
    open fun KotlinMultiplatformExtension.conventionSpecifics() {}
    override fun apply(project: Project) {
        with(project) {
            with(plugins) {
//                apply("org.gradle.java-library")
//                apply("java-library-distribution")
Or just one of them. Then after building, the projects in
ktor-server
should be broken
d
The specified commit with
apply("org.gradle.java-library")
and
apply("java-library-distribution")
uncommented works for me in: IntelliJ 2032.2.4 (latest stable), build #IU-232.10203.10 Could you please create a YouTrack issue at kotl.in/issue ? We have dedicated Support Engineers working there, they will be able to handle this faster and more reliably than me (as I might not be able to respond quick enough, as now, for example)