NoSuchFieldError: Companion при использовании MockWebServer только в модуле kotlin - PullRequest
1 голос
/ 21 февраля 2020

У меня есть модульный проект, где слой API разделен на собственный модуль. Поскольку это не зависит от Android SDK, я сделал его только для kotlin модуля. Это плагин kotlin jvm, как показано ниже в файле сборки. Это приводит к ошибке java .lang.NoSuchFieldError: Companion, когда я пытаюсь использовать MockWebServer (только это, все остальное работает нормально).

Используя kotlin dsl в файле сборки, файл build.gradle.kts выглядит следующим образом:

plugins {
    kotlin("jvm")
    kotlin("kapt")
}


dependencies {
    implementation(kotlin("stdlib"))
    implementation("com.squareup.retrofit2:retrofit:2.7.0")
    implementation("com.squareup.retrofit2:converter-moshi:2.7.0")
    implementation("com.squareup.moshi:moshi-kotlin:1.9.2")
    implementation("com.squareup.okhttp3:logging-interceptor:4.4.0")
    testImplementation("com.squareup.okhttp3:mockwebserver:4.4.0")
    testImplementation("junit:junit:4.13")
    kapt("com.squareup.moshi:moshi-kotlin-codegen:2.7.0")
    // There are various other libraries, but I'm including the only ones I feel are relevant 
    // in case my problem is to do with conflicting versions of libraries
}

А вот фрагмент моего модульного теста. Строка, где я создаю экземпляр MockWebServer (), завершается с ошибкой NoSuchFieldError: Companion:

class LoginServiceTest {


private val mockWebServer: MockWebServer = MockWebServer()

И трассировка стека:

java.lang.NoSuchFieldError: Companion

    at okhttp3.internal.Util.<clinit>(Util.kt:69)
    at okhttp3.mockwebserver.MockWebServer.<init>(MockWebServer.kt:101)
    at com.mobilleo.data.webapi.service.core.user.LoginServiceTest.<init>(LoginServiceTest.kt:29)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at org.junit.runners.BlockJUnit4ClassRunner.createTest(BlockJUnit4ClassRunner.java:250)
    at org.junit.runners.BlockJUnit4ClassRunner.createTest(BlockJUnit4ClassRunner.java:260)
    at org.junit.runners.BlockJUnit4ClassRunner$2.runReflectiveCall(BlockJUnit4ClassRunner.java:309)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:306)
    at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
    at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
    at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
    at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)


Process finished with exit code 255

После различных экспериментов я обнаружил следующее:

  • Откат библиотек okhttp3 до версии 3.xx устраняет эту ошибку, но затем я теряю много необходимых функций okhttp3, которые мне нужны, для перехватчиков, аутентификаторов и т. Д. c. et c.
  • Я полагаю, что при модернизации используется okhttp3 3.14, однако до того, как я попытался использовать MockWebServer, у меня не было проблем с перехватчиком журналирования okttp3: 4.4.0
  • . переключите модуль на модуль kotlin android, он работает как положено. Итак, изменив файл сборки следующим образом:

Рабочий build.gradle.kts:

plugins {
    id("com.android.library")
    kotlin("android")
    kotlin("kapt")
 }

android {

    compileSdkVersion(29)
    // etc. etc. Android config, that all seems a bit pointless just to get MockWebServer working

Мой инстинкт подсказывает мне, что между компиляциями kotlin android есть некоторая разница Kotlin, с объектами Companion или методами stati c et c., по сравнению с использованием только компилятора kotlin jvm, но я признаюсь, что не знал достаточно о том, что происходит «под капотом» со всем этим ,

Как заставить MockWebServer работать в модуле kotlin only с использованием плагина kotlin ("jvm")?

...