У меня есть модульный проект, где слой 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")?