NoClassDefFoundError en la class Kotlin en la testing JUnit en time de ejecución

Mi class Kotlin comstack y ejecuta en un emulador sin problemas. Pero cuando lo pruebo, Android Studio dice que la class no se encuentra.

Aquí está la class Kotlin y un ejemplo de su uso:

// Product.kt data class Product( val id: Int, val name: String, val manufacturer: String) // MainActivity.java public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Product product = new Product(0, "foo", "bar"); TextView textView = findViewById(R.id.textView); textView.setText(product.getName()); } } 

enter image description here

Sin embargo, cuando escribo una testing JUnit para la class Kotlin:

 // ProductTest.java public class ProductTest { @Test public void getName() throws Exception { Product p = new Product(0, "foo", "bar"); assertThat(p.getName(), equalTo("foo")); } } 

Android Studio comstack el código, pero se niega a ejecutar la testing:

 java.lang.NoClassDefFoundError: com/example/Product at com.example.ProductTest.getName(ProductTest.java:15) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) 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:51) at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242) at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.intellij.rt.execution.application.AppMainV2.main(AppMainV2.java:131) Caused by: java.lang.ClassNotFoundException: com.example.Product at java.net.URLClassLoader.findClass(URLClassLoader.java:381) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331) at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ... 28 more 

Aquí viene la sección de dependencies en build.gradle nivel de build.gradle :

 dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version" testCompile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version" testCompile "org.jetbrains.kotlin:kotlin-test:$kotlin_version" testCompile "org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version" testCompile 'junit:junit:4.12' } 

¿Qué hice mal?

Esto actualmente no funciona con las últimas herramientas. Hay un problema abierto para esto en el rastreador Jetbrains.

La solución es crear una nueva tarea en el file build.gradle del module.

 android { task copyTestClasses(type: Copy) { from "build/tmp/kotlin-classes/debugUnitTest" into "build/intermediates/classes/debug" } 

A continuación, agregue esa tarea a la sección "Antes de iniciar" de la configuration de ejecución de testing.

enter image description here

Este es un problema abierto, creo que se solucionará pronto:

https://youtrack.jetbrains.com/issue/KT-17951

https://issuetracker.google.com/issues/38454212

Mientras tanto, puede usar la siguiente solución alternativa:

 task copyTestClasses(type: Copy) { from "build/tmp/kotlin-classes/debugUnitTest" into "build/intermediates/classes/debug" } task copySdkClasses(type: Copy) { from "build/tmp/kotlin-classes/debug" into "build/intermediates/classes/debug" } 

Agrégalo a tu file Gradle (después de la sección de Android {…})

Después de eso, abra la configuration de las testings y agregue el nuevo paso "antes del lanzamiento" que ejecutará esas tareas:

enter image description here

enter image description here

enter image description here

Alguien confirmó que este error se ha solucionado en Android Studio 3 Canary 3: https://issuetracker.google.com/issues/38454212

  • Cómo escribir Short / Int en buffer de 1 byte
  • RxJava2 + Retrofit pantalla negra en request de datos
  • Deserializador de logging para una list envuelta de tipo
  • El operador de Kotlin Reflection obtiene la implementación
  • ¿Por qué solo se pueden delegar interfaces en kotlin?
  • Referencia no resuelta dentro del oyente Kotlin anónimo
  • Enumeraciones efectivas en Kotlin con búsqueda inversa
  • Cómo acceder al valor de campo en el método de propiedad get ()
  • onCreate en la actividad padre abstracta no llamada en kotlin
  • Desactivar cheque para usar el package 'kotlin' en Gradle
  • onActivityResult no se llama cuando se llama a la actividad de java desde kotlin para get resultados