How to share kotlin multiplatform targets between submodules? - kotlin

After an eternity I managed to setup a kotlin multi-platform and multi-module project. As there is almost no proper guide or documentation, I have just one more issue I couldn't solve.
Can I share kotlin multiplatform targets between the submodules?
Right now every submodule has a build.gradle.kts containing:
kotlin {
jvm {
compilations.all {
kotlinOptions.jvmTarget = "15"
}
}
js(IR) {
nodejs()
browser {
testTask {
useKarma {
useChromeHeadless()
webpackConfig.cssSupport.enabled = true
}
}
}
}
}
Obviously, I want all modules to compile to the same platforms using the same versions and it would be nice to not copy this snippet for every module.
Not to mention that the test dependencies are identical as well.
sourceSets {
val commonTest by getting {
dependencies {
implementation("io.kotest:kotest-framework-api:$kotestVersion")
implementation("io.kotest:kotest-assertions-core:$kotestVersion")
implementation("io.kotest:kotest-property:$kotestVersion")
}
}
val jvmTest by getting {
dependsOn(commonTest)
dependencies {
implementation("io.kotest:kotest-runner-junit5:$kotestVersion")
}
}
val jsTest by getting {
dependsOn(commonTest)
dependencies {
implementation("io.kotest:kotest-framework-engine:$kotestVersion")
}
}
}

Related

IntelliJ Show an Error on kotlinx.serialization, but compiling works

I have a problem where IntelliJ tells me that the #Serializable annotation cannot be accessed as it's internal to kotlin.io etc. The kotlinx.serialization package also shows as an unresolved reference.
Apparently, this has something to do with using Kotlin 1.7.x as when I downgrade to Kotlin 1.6.10 the issue no longer presents itself. However, Gradle compiles and runs the application without issue even on 1.7.10. Therefore, this seems like ultimately an issue with IntelliJ and/or one of my settings.
This is a Kotlin Multiplatform project. I've tried many things to fix this:
Reloading Gradle Project
Refreshing Gradle Dependencies
Completely refreshing all project indexes via the new Repair IDE tool
Deleting .idea and .gradle folders
Adjusting the project structure versions
Generally messing around with versions and settings
My build.gradle.kts:
plugins {
application
kotlin("multiplatform") version Versions.kotlin
kotlin("plugin.serialization") version Versions.kotlin
}
group = "com.example"
version = "4.0"
repositories {
mavenCentral()
}
kotlin {
jvm {
compilations.all {
kotlinOptions.jvmTarget = "17"
}
withJava()
testRuns["test"].executionTask.configure {
useJUnitPlatform()
}
}
js {
binaries.executable()
browser {
commonWebpackConfig {
cssSupport.enabled = true
}
webpackTask {
outputFileName = "app.js"
}
}
}
sourceSets {
val commonMain by getting {
dependencies {
implementation("io.ktor:ktor-client-core:${Versions.ktor}")
implementation("io.ktor:ktor-client-websockets:${Versions.ktor}")
implementation("io.ktor:ktor-serialization-kotlinx-json:${Versions.ktor}")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:${Versions.serialization}")
}
}
val commonTest by getting {
dependencies {
implementation(kotlin("test-common"))
implementation(kotlin("test-annotations-common"))
}
}
val jvmMain by getting {
dependencies {
implementation("io.ktor:ktor-server-core:${Versions.ktor}")
implementation("io.ktor:ktor-server-auth:${Versions.ktor}")
implementation("io.ktor:ktor-serialization:${Versions.ktor}")
implementation("io.ktor:ktor-server-html-builder:${Versions.ktor}")
implementation("io.ktor:ktor-client-cio:${Versions.ktor}")
implementation("io.ktor:ktor-server-cio:${Versions.ktor}")
implementation("io.ktor:ktor-server-websockets:${Versions.ktor}")
}
}
val jvmTest by getting
val jsMain by getting {
dependencies {
implementation("io.ktor:ktor-client-js:${Versions.ktor}")
implementation("io.ktor:ktor-client-json:${Versions.ktor}")
implementation("io.ktor:ktor-client-auth:${Versions.ktor}")
implementation("io.ktor:ktor-client-websockets:${Versions.ktor}")
implementation("io.ktor:ktor-client-serialization:${Versions.ktor}")
implementation("org.jetbrains.kotlin-wrappers:kotlin-react:${Versions.react}")
implementation("org.jetbrains.kotlin-wrappers:kotlin-react-dom:${Versions.react}")
}
}
val jsTest by getting
}
}
application {
mainClass.set("com.example.app.ServerKt")
}
tasks.named<Copy>("jvmProcessResources") {
val jsBrowserDistribution = tasks.named("jsBrowserDistribution")
from(jsBrowserDistribution)
}
tasks.named<JavaExec>("run") {
dependsOn(tasks.named<Jar>("jvmJar"))
classpath(tasks.named<Jar>("jvmJar"))
}
object Versions {
const val ktor = "2.0.3"
const val kotlin = "1.7.10"
const val coroutines = "1.6.3"
const val serialization = "1.3.3"
const val react = "18.2.0-pre.358-compat"
}
The class that is having issues is:
import kotlinx.serialization.Serializable
#Serializable
data class Customer(val id: Int, val firstName: String, val lastName: String)
I appreciate any help I can get

Kotlin Multiplattform Project Dependencies

What do I do wrong, I just want to add dependencies to my multiplattform project (at the moment just windows):
I just added some example repository and dependencies.
plugins {
kotlin("multiplatform") version "1.5.0"
kotlin("plugin.serialization") version "1.5.0"
}
kotlin {
allprojects {
repositories {
mavenCentral()
google()
jcenter()
maven { setUrl("https://jitpack.io") }
}
}
sourceSets {
commonMain {
dependencies {
implementation("com.squareup.okhttp3:okhttp:4.9.1")
implementation("io.ktor:ktor-server-netty:1.5.4")
implementation("io.ktor:ktor-server-core:1.5.4")
}
}
}
}
kotlin {
mingwX64("native") {
binaries {
executable()
}
}
}
tasks.withType<Wrapper> {
gradleVersion = "7.0.1"
distributionType = Wrapper.DistributionType.ALL
}
Outcome:
Output
I would guess none of those dependencies are actually available for windows. You'll need windows compatible ktor dependencies (and I'd stick to Kotlin 1.4.32 vs 1.5 because of kotlinx.coroutines, for now).
Ktor config for windows is probably like this, but I've never done this for Windows.
sourceSets {
commonMain {
dependencies {
implementation "io.ktor:ktor-client-core:$ktor_version"
}
}
mingwX64Main {
dependencies {
implementation "io.ktor:ktor-client-curl:$ktor_version"
}
}
}

Can I use Spock test in Koltin Multiplatform project? If so how to set in gradle.build.kts?

I try to use Spock test framework in my Kotlin multiplatform project, but with fail, the gradle script:
plugins {
val kotlinVersion = "1.4.30"
kotlin("multiplatform") version kotlinVersion
application
kotlin("plugin.serialization") version kotlinVersion
groovy // for spock
}
repositories {
// ...
maven("https://jitpack.io") // for spock
}
kotlin {
jvm {withJava()}
js {/*...*/}
sourceSets {
val commonMain by getting {
dependencies {/*...*/}
}
val commonTest by getting {
dependencies {
implementation(kotlin("test-common"))
implementation(kotlin("test-annotations-common"))
}
}
val jvmMain by getting {
dependencies {/*...*/}
}
val jvmTest by getting {
dependencies {
dependsOn(commonTest)
implementation(kotlin("test"))
implementation(kotlin("test-junit"))
// implementation(kotlin("test-junit5"))
// for spock
implementation("org.spockframework.spock:spock-core:spock-1.3")
implementation("org.codehaus.groovy:groovy-all:3.0.7")
}
}
val jsMain by getting {
dependencies {/*...*/}
}
}
}
I tried the spock-1.3 and spock-2.0-M4 with groovy-2.5 and Junit5, all failed with dependencies problems, even thought the test can run, it tells: Test events were not received, and more important:
I cannot create groovy source fold for test only.(The directory appreas like normal folder, not source or test folder)
How to configure the dependencies or gradle.build.kts file? Any help is highly appreciated!
I can now make Spock work with existed Ktor project with the code below added to my gradle.build.kts :
plugins {
groovy
}
repositories {
maven("https://jitpack.io")
}
dependencies {
testImplementation("org.codehaus.groovy:groovy-all:2.4.15")
testImplementation("org.spockframework.spock:spock-core:spock-1.3")
}
sourceSets {
main {
withConvention(GroovySourceSet::class) {
groovy {
setSrcDirs(listOf("src"))
}
}
}
test {
withConvention(GroovySourceSet::class) {
groovy {
setSrcDirs(listOf("test"))
}
}
}
}
tasks.test {
useJUnitPlatform()
testLogging {
events("passed", "skipped", "failed")
}
}
However, I cannot figure out the Koltin Multiplatform project with Spock test, I will post the script when I make it.

Intellij autocomplete failing on multiplatform library dependencies

I've created a multiplatform library that I consume in a different multiplatform project. After including the dependency I am able to use the libraries in commonMain without issue and all targets build without errors. However, intellij autocomplete does not know about my new types. I have invalidated caches and restarted the application many times, but it just cannot find this type. Anybody encountered this?
just in case, here is my build.gradle.kts:
import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpack
buildscript {
repositories {
jcenter()
}
}
plugins {
kotlin("multiplatform") version "1.3.61"
}
repositories {
jcenter()
maven( "https://dl.bintray.com/kotlin/ktor" )
mavenCentral()
mavenLocal()
}
val ktor_version = "1.1.3"
val logback_version = "1.2.3"
kotlin {
js {
browser { }
}
jvm {
compilations.named("main") {
tasks.getByName<Copy>(processResourcesTaskName) {
dependsOn("jsBrowserWebpack")
tasks.named<KotlinWebpack>("jsBrowserWebpack") {
from(entry.name, destinationDirectory)
}
}
}
}
sourceSets {
val commonMain by getting {
dependencies {
implementation(kotlin("stdlib-common"))
api("github.fatalcatharsis:constraint:1.0-SNAPSHOT")
}
}
val commonTest by getting {
dependencies {
implementation(kotlin("test-common"))
implementation(kotlin("test-annotations-common"))
}
}
val jvmMain by getting {
dependencies {
implementation( kotlin("stdlib-jdk8"))
implementation( "io.ktor:ktor-server-netty:$ktor_version")
implementation( "io.ktor:ktor-html-builder:$ktor_version")
implementation( "ch.qos.logback:logback-classic:$logback_version")
}
}
val jvmTest by getting {
dependencies {
implementation(kotlin("test"))
implementation(kotlin("test-testng"))
}
}
val jsMain by getting {
dependencies {
implementation( kotlin("stdlib-js"))
}
}
val jsTest by getting {
dependencies {
implementation( kotlin("test-js"))
}
}
}
}
tasks.register<JavaExec>("run") {
dependsOn("jvmJar")
group = "application"
main = "sample.SampleJvmKt"
val t = tasks.named<Jar>("jvmJar")
classpath(configurations.named("jvmRuntimeClasspath"), t.get() )
}

Cannot update kotlin to v1.3.50 for multiplatform project

I'm using kotlin 1.3.41 for my multiplatform project (included ios, jvm, js) and everything is ok. Now I'm trying to update to the latest version 1.3.50 but get this error:
Could not determine the dependencies of task ':kotlinNpmInstall'.
> org.jetbrains.kotlin.gradle.targets.js.npm.KotlinNpmResolutionManager$ResolutionState$Installed cannot be cast to org.jetbrains.kotlin.gradle.targets.js.npm.KotlinNpmResolutionManager$ResolutionState$Configuring
I have tried to search everywhere (github, kotlin issue tracker) but got nothing. Does anyone know what causes this error? Thanks.
Part of my configuration:
Root project configuration
buildscript {
apply from: "buildsystem/dependencies.gradle"
repositories {
google()
jcenter()
mavenCentral()
maven { url "https://dl.bintray.com/kotlin/kotlinx/" }
maven { url "https://plugins.gradle.org/m2/" }
}
dependencies {
classpath deps.gradlePlugins.android
classpath deps.gradlePlugins.androidNavigation
classpath deps.gradlePlugins.node
classpath deps.gradlePlugins.kotlin
classpath deps.gradlePlugins.kotlinSerialization
classpath deps.gradlePlugins.kotlinAtomicfun
classpath deps.gradlePlugins.dokka
}
}
Multiplatform module configuration
apply plugin: 'org.jetbrains.kotlin.multiplatform'
apply plugin: 'kotlinx-serialization'
kotlin {
targets {
jvm("jvm")
js("js") {
nodejs {}
}
iosArm64("ios64")
iosX64("iosSim")
configure([ios64, iosSim]) {
binaries.framework {
baseName = "LIB"
}
}
}
sourceSets {
def commonDependencies = rootProject.ext.deps.common
commonMain {
dependencies {
implementation commonDependencies.kotlin
implementation commonDependencies.kotlinCoroutines
}
}
commonTest {
dependencies {
implementation commonDependencies.kotlinTest
implementation commonDependencies.kotlinTestAnnotations
implementation commonDependencies.mockk
}
}
def jvmDependencies = rootProject.ext.deps.jvm
jvmMain {
dependencies {
implementation jvmDependencies.kotlin
implementation jvmDependencies.kotlinCoroutines
}
}
jvmTest {
dependencies {
implementation jvmDependencies.kotlinTest
implementation jvmDependencies.kotlinTestJunit
implementation jvmDependencies.kotlinCoroutinesTest
implementation jvmDependencies.mockk
}
}
def jsDependencies = rootProject.ext.deps.js
jsMain {
dependencies {
implementation jsDependencies.kotlin
implementation jsDependencies.kotlinCoroutines
// npm
implementation npm("uuid", "^3.3.2")
}
}
jsTest {
dependsOn jsMain
dependsOn commonMain
dependencies {
implementation jsDependencies.kotlinTest
}
}
def iosDependencies = rootProject.ext.deps.ios
iosMain {
dependencies {
implementation iosDependencies.kotlinCoroutines
}
}
ios64Main {
dependsOn iosMain
}
iosSimMain {
dependsOn iosMain
}
}
}
// other configuration
I can confirm that the issue is in Android Studio.
When I run the official KotlinJS react app tutorial on IntelliJ, the app works. But on AS, I get the above error when executing any Gradle task dependent on npm.
Until the issue is resolved, I recommend using the Community version of IntelliJ. You can download it here