Ktor: 1.3.0: encodeToByteArray is not a function

Created on 13 Sep 2019  Â·  16Comments  Â·  Source: ktorio/ktor

1.3.0-beta-1: encodeToByteArray is not a function at Object.eval (ktor-ktor-http-cio.js?:formatted:1314)

Ktor version: 1.3.0-beta-1
Run using: Browser

bug

All 16 comments

This still persist on ktor client 1.3.0

@bashor

To try and narrow down this, it appears to be a method in this package
$module$ktor_ktor_io.io.ktor.utils.io.charsets.encodeToByteArray_fj4osb$;

I was able to track the source of the problem directly to this function Charsets.UTF_8.newEncoder().encodeToByteArray("test encoding"), from the lib ktor-io, in the file https://github.com/ktorio/ktor/blob/master/ktor-io/js/src/io/ktor/utils/io/charsets/CharsetJS.kt Somehow, it's compiled JS suggests that there is no function encodeToByteArray

@andylamax please try next workaround in your project (in build.gradle.kts) and let us know about any result:

...
browser {
            dceTask {
                dceOptions {
                    keep("ktor-ktor-io.\$\$importsForInline\$\$.ktor-ktor-io.io.ktor.utils.io")
                }
            }
        }
...
js() {
        browser {
            dceTask {
                dceOptions {
                    keep("ktor-ktor-io.\$\$importsForInline\$\$.ktor-ktor-io.io.ktor.utils.io")
                }
            }
        }
//        nodejs()
        compilations.all {
            tasks[compileKotlinTaskName].kotlinOptions {
                kotlinOptions.metaInfo = true
                kotlinOptions.outputFile = "$project.buildDir.path/js/${project.name}.js"
                kotlinOptions.sourceMap = true
                kotlinOptions.moduleKind = 'commonjs'
                kotlinOptions.main = "call"
            }
        }
    }

Results in Could not find method dceTask() . . .
N.B: I am not using Gradle-Kotlin DSL

Which version of the kotlin plugin do you use?
Could you please share your project or build.gradle?

If you are using plugin prior 1.3.70 and applying it manually try to add on the top level of the file something like:

tasks {
    runDceKotlin {
        keep("ktor-ktor-io.\$\$importsForInline\$\$.ktor-ktor-io.io.ktor.utils.io")
    }
}

Sure, I am using kotlin-gradle-plugin 1.3.61, using gradle: 5.4.0

buildscript {
   ext {
            kotlin_version = "1.3.61"
            ktor_version = "1.3.0"
            serialization_version = "0.14.0"
            android_tools_version = "3.5.0"
    }
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath("com.android.tools.build:gradle:$android_tools_version")
        classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version")
        classpath("org.jetbrains.kotlin:kotlin-serialization:$kotlin_version")
    }
}

plugins {
    id("kotlin-multiplatform") version("1.3.61")
}

group 'tz.co.asoft'
version '0.0.0'

apply plugin: 'com.android.library'
apply plugin: 'maven-publish'
apply plugin: 'kotlinx-serialization'

android {
    compileSdkVersion(28)
    defaultConfig {
        minSdkVersion(21)
        targetSdkVersion(28)
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }

    sourceSets {
        main {
            java.srcDirs += 'src/androidMain/kotlin'
            manifest.srcFile "src/androidMain/AndroidManifest.xml"
            res.srcDirs += "src/androidMain/resources"
        }
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }

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

repositories {
    google()
    jcenter()
    mavenCentral()
    maven { url "https://kotlin.bintray.com/kotlinx" }
    maven { url 'https://dl.bintray.com/kotlin/kotlin-js-wrappers' }
    maven { url 'https://dl.bintray.com/kotlinx/kotlinx' }
    maven { url "https://kotlin.bintray.com/kotlinx" }
    maven { url "https://jitpack.io" }
}

kotlin {
    android() {
        compilations.all {
            tasks[compileKotlinTaskName].kotlinOptions {
                jvmTarget = "1.8"
            }
        }
    }

    js() {
        browser {
            dceTask {
                dceOptions {
                    keep("ktor-ktor-io.\$\$importsForInline\$\$.ktor-ktor-io.io.ktor.utils.io")
                }
            }
        }
//        nodejs()
        compilations.all {
            tasks[compileKotlinTaskName].kotlinOptions {
                kotlinOptions.metaInfo = true
                kotlinOptions.outputFile = "$project.buildDir.path/js/${project.name}.js"
                kotlinOptions.sourceMap = true
                kotlinOptions.moduleKind = 'commonjs'
                kotlinOptions.main = "call"
            }
        }
    }

    sourceSets {
        commonMain {
            dependencies {
                api kotlin('stdlib-common')
                api "org.jetbrains.kotlinx:kotlinx-serialization-runtime-common:$serialization_version"
                 api "io.ktor:ktor-client-core:$ktor_version"
            }
        }

        jsMain {
            dependencies {
                api kotlin('stdlib-js')
                api "org.jetbrains.kotlinx:kotlinx-serialization-runtime-js:$serialization_version"
                api "io.ktor:ktor-client-core-js:$ktor_version"
            }
        }

        jsTest {
            dependsOn jsMain
            dependencies {
                implementation kotlin('test-js')
            }
        }

        androidMain {
            dependencies {
                api kotlin('stdlib-jdk8')
                api "org.jetbrains.kotlinx:kotlinx-serialization-runtime:$serialization_version"
                api "io.ktor:ktor-client-android:$ktor_version"
            }
        }
    }
}

How do you run your code? Do you apply somehow DCE on generated code?

Yes. For Now, I am using the kotlinFrontend plugin. (version 0.0.45) I am using this as a library in my main project. and yes, it does have a task called runKotlinDceJs

So, please try to add keep("ktor-ktor-io.\$\$importsForInline\$\$.ktor-ktor-io.io.ktor.utils.io") there.

Adding keep to the DCE task, solves the current ploblem but also, it creates a new one.

ERROR in ./ktor-ktor-client-core.js
Module not found: Error: Can't resolve 'abort-controller' in '/media/andylamax/63C23C360914D355/Projects/agro/agro-meru/agro-meru-web/build/kotlin-js-min/js/main'
 @ ./ktor-ktor-client-core.js 8529:23-50
 @ ./agro-meru-web.js
 @ multi webpack-dev-server/client?http://0.0.0.0:8088/ webpack/hot/dev-server ./agro-meru-web
ℹ 「wdm」: Failed to compile.
ℹ 「wdm」: Compiling...
✖ 「wdm」: 

Looks like you need to add npm dependency on abort-controller.

Thanks @bashor the after adding npm dependency on abort-controller, everything worked

The related issue in the toolchain: KT-36484

Was this page helpful?
0 / 5 - 0 ratings