Detox - DetoxManager не может найти kotlin / jvm / functions / Function1 во время выполнения - PullRequest
1 голос
/ 06 апреля 2020

Чтобы воспроизвести проблему, с которой я столкнулся, я использовал react-native пример проекта demo-реакции-native из `Detox.

После установки пакетов с yarn я выполнил две команды для запуска теста:

1) cd android && ./gradlew assembleRelease assembleAndroidTest -DtestBuildType=release && cd ..

2) npx detox test -l error --configuration android.emu.release

Пока все работает как положено, но как только я добавляю зависимость Kotlin стандартная библиотека в файле android/app/build.gradle, как этот

dependencies {
  ...
  androidTestImplementation('com.wix:detox:+')
  implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.71" // <-- line added
}

и снова выполнить 2 шага, я получаю следующую ошибку

04-05 20:21:06.709 16552 16615 E AndroidRuntime: FATAL EXCEPTION: com.wix.detox.manager
04-05 20:21:06.709 16552 16615 E AndroidRuntime: Process: com.test.app, PID: 16552
04-05 20:21:06.709 16552 16615 E AndroidRuntime: java.lang.NoClassDefFoundError: Failed resolution of: Lkotlin/jvm/functions/Function1;
04-05 20:21:06.709 16552 16615 E AndroidRuntime:    at com.wix.detox.Detox$1.run(Detox.java:134)
04-05 20:21:06.709 16552 16615 E AndroidRuntime:    at java.lang.Thread.run(Thread.java:764)
04-05 20:21:06.709 16552 16615 E AndroidRuntime: Caused by: java.lang.ClassNotFoundException: Didn't find class "kotlin.jvm.functions.Function1" on path: DexPathList[[zip file "/system/framework/android.test.runner.jar", zip file "/system/framework/android.test.mock.jar", zip file "/data/app/com.test.app.test-xbA2GW9WwS_BxzRNPa2waQ==/base.apk", zip file "/data/app/com.test.app-g_-tD026mxddTh82TmdYGg==/base.apk"],nativeLibraryDirectories=[/data/app/com.test.app.test-xbA2GW9WwS_BxzRNPa2waQ==/lib/x86, /data/app/com.test.app-g_-tD026mxddTh82TmdYGg==/lib/x86, /data/app/com.test.app.test-xbA2GW9WwS_BxzRNPa2waQ==/base.apk!/lib/x86, /data/app/com.test.app-g_-tD026mxddTh82TmdYGg==/base.apk!/lib/x86, /system/lib]]
04-05 20:21:06.709 16552 16615 E AndroidRuntime:    at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:134)
04-05 20:21:06.709 16552 16615 E AndroidRuntime:    at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
04-05 20:21:06.709 16552 16615 E AndroidRuntime:    at java.lang.ClassLoader.loadClass(ClassLoader.java:312)

Я пытался загрузить * Плагин 1022 * в файле android/build.gradle, как описано здесь , но это не помогает.

Что еще я могу сделать, чтобы org.jetbrains.kotlin.jvm работал в этом проекте?

Заранее спасибо.

Редактировать 1

Я добавил kotlin.jvm.functions.Function1 к MainApplication.java, чтобы проверить, действительно ли Kotlin JVM доступен проекту, добавив следующий код

...
import kotlin.jvm.functions.Function0;
import kotlin.jvm.functions.Function1;

public class MainApplication extends Application implements ReactApplication {
    private Function1<Throwable, String> errorParseFn = new Function1<Throwable, String>() {
        @Override
        public String invoke(Throwable t) {
            return Log.getStackTraceString(t);
        }
    };

    ...

    @Override
    public void onCreate() {
        super.onCreate();
        SoLoader.init(this, /* native exopackage */ false);
        Log.d("@@@@@@", "onCreate");
        Log.d("@@@@@@", errorParseFn.invoke(new Exception("Test Exception message")));
    }
}

после того, как я еще раз набрал npx detox test -l error --configuration android.emu.release, я увидел журналы в консоли.

04-06 21:24:06.715 23836 23836 D @@@@@@  : onCreate
04-06 21:24:06.716 23836 23836 D @@@@@@  : java.lang.Exception: Test Exception message 

Это означает, что само приложение имеет доступ к kotlin.jvm, что означает правильную настройку gradle.

Кто-нибудь знает, как DetoxManager.java может получить доступ к Kotlin JVM при время выполнения ?

Ответы [ 2 ]

2 голосов
/ 22 апреля 2020

Мне удалось смягчить те же ошибки, добавив следующую конфигурацию в файл proguard.

-dontobfuscate



-keep class kotlin.** { *; }

-keep class kotlin.Metadata { *; }

-dontwarn kotlin.**
2 голосов
/ 21 апреля 2020

Наконец-то у меня есть время опубликовать решение.

После изучения значения журнала

Note: kotlin.jvm.internal.Reflection: can't find dynamically referenced class kotlin.reflect.jvm.internal.ReflectionFactoryImpl
Note: kotlin.coroutines.jvm.internal.DebugMetadataKt accesses a declared field 'label' dynamically
...
Note: there were 1 references to unknown classes.
      You should check your configuration for typos.
      (http://proguard.sourceforge.net/manual/troubleshooting.html#unknownclass)

я обнаружил, что Proguard удаляет Kotlin зависимостей.

Чтобы доказать гипотезу, я закомментировал строки, касающиеся proguard в app/build.gradle из демо-реакции-нативного

buildTypes {
  release {
    // minifyEnabled true
    // proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    // proguardFile "${rootProject.projectDir}/../node_modules/detox/android/detox/proguard-rules-app.pro"

    signingConfig signingConfigs.release
  }
}

, и это сработало, как и ожидалось.

Это означало, что я должен был создать свой собственный buildType только для теста E2E и включить proguard только для релизной сборки

...
signingConfigs {
  e2e_release {
    storeFile file("keystore.e2e.jks")
    storePassword "987654321"
    keyAlias "e2e_key"
    keyPassword "987654321"
  }
  release {
    storeFile file("keystore.jks")
    storePassword "12345678"
    keyAlias "key0"
    keyPassword "12345678"
  }
buildTypes {
  e2eRelease {
    initWith release
    matchingFallbacks = ['release']
    signingConfig signingConfigs.e2e_release
  }
  release{}
  if(gradle.startParameter.taskNames.contains("assembleRelease")) {
    minifyEnabled true
    proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    proguardFile "${rootProject.projectDir}/../node_modules/detox/android/detox/proguard-rules-app.pro"
    signingConfig signingConfigs.release
  }
}

Осталось только настроить путь и команду сборки в файле package.json следующим образом:

"android.emu.e2e": {
  "binaryPath": "android/app/build/outputs/apk/e2eRelease/app-e2eRelease.apk",
  "build": "cd android && RN_SRC_EXT=e2e.js ./gradlew app:assembleE2ERelease  app:assembleE2EReleaseAndroidTest -DtestBuildType=e2eRelease -x bundleE2eReleaseJsAndAssets && cd ..",
  "type": "android.emulator",
  "device": {
    "avdName": "Nexus_6P_API_28"
  }
}

Обратите внимание, что папку outputs/apk/e2eRelease необходимо создать вручную перед запуском ./gradlew assembleE2ERelease assembleE2EReleaseAndroidTest -DtestBuildType=e2eRelease

Это работает очень хорошо, но дайте мне знать, если есть лучшее решение.

Ура

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...