https://kotlinlang.org logo
#multiplatform
Title
# multiplatform
s

Sean Keane

03/06/2020, 11:32 AM
Hi everyone! So I have built a simple network request, but when I use the AAR output from the android build, it doesnt seem to contain the libraries that are needed and causes the application that im using the multiplatform lib in to crash. Here is my build.gradle.kts file. Can anybody see anything out of the ordinary?
Copy code
import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig.*

group = "org.example"
version = "1.0-SNAPSHOT"

plugins {
    id("com.android.library")
    id("org.jetbrains.kotlin.multiplatform")
    id("org.jetbrains.kotlin.native.cocoapods")
}

kotlin {
    /* Targets configuration omitted. 
    *  To find out how to configure the targets, please follow the link:
    *  <https://kotlinlang.org/docs/reference/building-mpp-with-gradle.html#setting-up-targets> */

    js() {
        browser {
            dceTask {
                keep("ktor-ktor-io.\$\$importsForInline\$\$.<http://ktor-ktor-io.io.ktor.utils.io|ktor-ktor-io.io.ktor.utils.io>")
                keep("multiplatform-lib")
            }
            webpackTask {
                mode = Mode.PRODUCTION
                sourceMaps = false
            }
        }
    }

    android()

    sourceSets {

        val commonMain by getting {
            dependencies {
                implementation(kotlin("stdlib-common"))
                implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core-common:${Versions.coroutinesCore}")
                implementation("org.jetbrains.kotlinx:kotlinx-serialization-runtime-common:${Versions.serializationCommon}")
                implementation("io.ktor:ktor-client-core:${Versions.ktor}")
                implementation("io.ktor:ktor-client-json:${Versions.ktor}")
                implementation("io.ktor:ktor-client-serialization:${Versions.ktor}")
            }
        }

        val commonTest by getting {
            dependencies {
                implementation(kotlin("test-common"))
                implementation(kotlin("test-annotations-common"))
            }
        }

        val jsMain by getting {
            dependencies {
                implementation(kotlin("stdlib-js"))
                implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core-js:${Versions.coroutinesCore}")
                implementation("org.jetbrains.kotlinx:kotlinx-serialization-runtime-js:${Versions.serializationCommon}")
                implementation("io.ktor:ktor-client-js:${Versions.ktor}")
                implementation("io.ktor:ktor-client-json-js:${Versions.ktor}")
                implementation("io.ktor:ktor-client-serialization-js:${Versions.ktor}")
                api(npm("text-encoding"))
                api(npm("bufferutil"))
                api(npm("utf-8-validate"))
                api(npm("abort-controller"))
                api(npm("fs"))
            }
        }

        val jsTest by getting {

        }
    }
}

android {
    compileSdkVersion(App.compileSdk)

    sourceSets {
        getByName("main") {
            manifest.srcFile("src/androidMain/AndroidManifest.xml")
        }
    }

    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    }

    packagingOptions {
        exclude("META-INF/*")
    }

}

dependencies {
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:${Versions.coroutinesCore}")
    implementation("org.jetbrains.kotlinx:kotlinx-serialization-runtime:${Versions.serializationCommon}")
    implementation("io.ktor:ktor-client-android:${Versions.ktor}")
    implementation("io.ktor:ktor-client-json-jvm:${Versions.ktor}")
    implementation("io.ktor:ktor-client-serialization-jvm:${Versions.ktor}")
    implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
}

tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>().all {
    kotlinOptions.freeCompilerArgs += "-Xopt-in=kotlin.RequiresOptIn"
    kotlinOptions.jvmTarget = "1.8"
}
k

Kris Wong

03/06/2020, 1:55 PM
are your library dependencies included in your app artifact as well?
s

Sean Keane

03/06/2020, 1:56 PM
No, I'm just importing this lib to another standalone project but its not including the libs like KTOR bundled
k

Kris Wong

03/06/2020, 2:00 PM
well, that's the problem
when you saying importing, I assume you mean your dropping the artifact into the source tree?
s

Sean Keane

03/06/2020, 2:01 PM
Exactly. just copying the aar into libs in the other project
k

Kris Wong

03/06/2020, 2:01 PM
java/android artifacts are not "fat". they do not include the dependencies. maven solves this problem.
s

Sean Keane

03/06/2020, 2:01 PM
I need to figure out how to bundle it or how to get the client to fetch the resources without needing to modify their gradle system
I was expecting a pom or gradle file to be included with dependacies. But there is nothing generated.
k

Kris Wong

03/06/2020, 2:02 PM
you can make them fat, via the magic of gradle, but it's not straightforward
s

Sean Keane

03/06/2020, 2:03 PM
I have made fat jars before. Just thought there was an easier way of using the output from kotlin mpp in another project
k

Kris Wong

03/06/2020, 2:03 PM
for java we have the shadow jar plugin. for android we don't have an equivalent that supports KMP.
there is. use maven.
s

Sean Keane

03/06/2020, 2:03 PM
I have the maven plugin
But its not generating the jar with the dependants
Im inspecting the bundle and they are'nt there
k

Kris Wong

03/06/2020, 2:04 PM
the pom should specify the dependencies
s

Sean Keane

03/06/2020, 2:05 PM
There is no pom created in the AAR file
k

Kris Wong

03/06/2020, 2:05 PM
that's not where poms go 🙂
they're adjacent to the artifact in the artifact repo
s

Sean Keane

03/06/2020, 2:07 PM
You mean in maven or in the KMP project? Do I need to create a custom pom? I thought the dependacies could be mapped with gradle.
k

Kris Wong

03/06/2020, 2:07 PM
in maven
they are mapped by the maven publish plugin
s

Sean Keane

03/06/2020, 2:07 PM
Ok, so where can I find the maven output?
k

Kris Wong

03/06/2020, 2:08 PM
check your gradle publishing tasks
s

Sean Keane

03/06/2020, 2:08 PM
I have that done already and it creates a publication build folder with different maven variants
k

Kris Wong

03/06/2020, 2:08 PM
you can use local maven to experiment
s

Sean Keane

03/06/2020, 2:08 PM
Im using
publishToMavenLocal
currently
k

Kris Wong

03/06/2020, 2:08 PM
publishToMavenLocal
and then you need
mavenLocal()
in the consumer repos
s

Sean Keane

03/06/2020, 2:09 PM
Used this workflow before. I build a standalone Android SDK
k

Kris Wong

03/06/2020, 2:09 PM
👍
s

Sean Keane

03/06/2020, 2:09 PM
But this is a little more confusing with KMP
Thank you for the advice
k

Kris Wong

03/06/2020, 2:09 PM
there's more going on, but it all boils down to the same concepts
s

Sean Keane

03/06/2020, 2:17 PM
So im still in the same issue but with more info. It seems to be generating the Jar for JS and not for Android which is odd
s

Sean Keane

03/06/2020, 2:34 PM
I think this has it sorted.
Copy code
publishLibraryVariants("release", "debug")
Thank you very much for the help
🍻 1
Getting a weird network request issue now with serialisation.
Copy code
java.lang.NoSuchFieldError: No field Companion of type Lkotlinx/serialization/json/Json$Companion; in class Lkotlinx/serialization/json/Json;
I've tried cleaning and reimporting everything to no avail.
k

Kris Wong

03/06/2020, 5:02 PM
what version of kotlin are you using?
s

Sean Keane

03/06/2020, 5:03 PM
1.3.70
k

Kris Wong

03/06/2020, 5:04 PM
are all your dependencies using the same version?
s

Sean Keane

03/06/2020, 5:07 PM
Copy code
object Versions {
    const val gradle = "3.6.0"
    const val kotlin = "1.3.70"
    const val ktor = "1.3.1"
    const val coroutinesCore = "1.3.4"
    const val serializationCommon = "0.20.0"
    const val cocoapodVersion = "1.8.0"
    const val lifecycleVersion = "2.2.0-rc03"
    const val multiplatformSettingsVersion = "0.5"

    /* TEST */
    const val junit = "4.12"
}
k

Kris Wong

03/06/2020, 5:14 PM
that doesn't really answer the question, but i would recommend going with 1.3.61 for the time being
s

Sean Keane

03/06/2020, 5:26 PM
These are what im running. I need to stick with 1.3.70 because of JS library creation. Every dependency is listed there with the version, they are all linked to use the same version
k

Kris Wong

03/06/2020, 5:27 PM
alright, my point is that new Kotlin versions are not always backwards compatible, so if your dependencies are not on the same version it can cause these kinds of issues
we have seen specifically issues with nested classes/companion objects
s

Sean Keane

03/06/2020, 5:28 PM
I have adapted everything on this project to use the updated Kotlin version. Let me confirm with the Android project
Copy code
buildscript {
    ext.kotlin_version = '1.3.70'
    repositories {
        google()
        jcenter()
        mavenLocal()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.6.1'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}
The app uses 1.3.70 also
k

Kris Wong

03/06/2020, 5:31 PM
dunno, seems to be the right version of kotlinx.serialization, and that's where the issue is coming from
s

Sean Keane

03/06/2020, 5:32 PM
Exactly why I'm a little lost.
2 Views