Kotlin JaCoCo,无覆盖-> IllegalClassFormatException ...请提供原始的非仪器类

kotlin版本: 1.3.61

Android Gradle插件: 3.5.3

JaCoCo版本:0.8.4.201905082037(默认的Android gradle版本)

项目: https://github.com/goldy1992/Mp3Player/tree/feature/issue-112/migrate-to-kotlin

我有一个多模块gradle项目,其中: 2种口味:完整,自动化 2种构建类型:发布,调试

我正在将所有内容迁移到Kotlin。

模块结构

  • 与[android库]通用(在预期的测试范围内可以正常工作)
  • client-test-support(用于活动的测试实现)
  • 客户端[android库](无覆盖范围)->取决于公用,客户端测试支持
  • 服务测试支持(用于活动的测试实现)
  • 服务[android库](无覆盖范围)->取决于公用,服务测试支持
  • app [android application]没有测试

对于本文的上下文,我仅对单元测试

感兴趣

测试按预期进行,但是由于部分(并非全部)kotlin编译类被识别为“仪器类”,因此未生成覆盖率

错误将在测试即将出现的许多类中打印出来时出现:

    java.lang.instrument.IllegalClassFormatException: Error while instrumenting com/github/goldy1992/mp3player/client/views/viewholders/MediaPlayerTrackViewHolder.
        at org.jacoco.agent.rt.internal_035b120.CoverageTransformer.transform(CoverageTransformer.java:93)
        at sun.instrument.TransformerManager.transform(TransformerManager.java:188)
        at sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:428)
        at java.lang.ClassLoader.defineclass1(Native Method)
        at java.lang.ClassLoader.defineclass(ClassLoader.java:763)
        at java.security.SecureclassLoader.defineclass(SecureclassLoader.java:142)
        at java.net.URLClassLoader.defineclass(URLClassLoader.java:468)
        at java.net.URLClassLoader.access$100(URLClassLoader.java:74)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:369)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:363)
        at java.security.accessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:362)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        at java.lang.Class.getDeclaredFields0(Native Method)
        at java.lang.Class.privateGetDeclaredFields(Class.java:2583)
        at java.lang.Class.getDeclaredFields(Class.java:1916)
        at org.junit.runners.model.TestClass.getsortedDeclaredFields(TestClass.java:77)
        at org.junit.runners.model.TestClass.scanAnnotatedMembers(TestClass.java:70)
        at org.junit.runners.model.TestClass.<init>(TestClass.java:57)
        at org.junit.runners.ParentRunner.createTestClass(ParentRunner.java:88)
        at org.junit.runners.ParentRunner.<init>(ParentRunner.java:83)
        at org.junit.runners.BlockJUnit4ClassRunner.<init>(BlockJUnit4ClassRunner.java:65)
        at org.robolectric.internal.SandboxTestRunner.<init>(SandboxTestRunner.java:71)
        at org.robolectric.RobolectricTestRunner.<init>(RobolectricTestRunner.java:101)
        at org.robolectric.RobolectricTestRunner.<init>(RobolectricTestRunner.java:96)
        at sun.reflect.GeneratedConstructoraccessor5.newInstance(Unknown Source)
        at sun.reflect.DelegatingConstructoraccessorImpl.newInstance(DelegatingConstructoraccessorImpl.java:45)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
        at org.junit.internal.builders.AnnotatedBuilder.buildRunner(AnnotatedBuilder.java:104)
        at org.junit.vintage.engine.discovery.DefensiveAllDefaultPossibilitiesBuilder$DefensiveAnnotatedBuilder.buildRunner(DefensiveAllDefaultPossibilitiesBuilder.java:113)
        at org.junit.internal.builders.AnnotatedBuilder.runnerForClass(AnnotatedBuilder.java:86)
        at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
        at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:26)
        at org.junit.vintage.engine.discovery.DefensiveAllDefaultPossibilitiesBuilder.runnerForClass(DefensiveAllDefaultPossibilitiesBuilder.java:56)
        at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
        at org.junit.vintage.engine.discovery.TestClassRequestResolver.createRunnerTestDescriptor(TestClassRequestResolver.java:55)
        at org.junit.vintage.engine.discovery.VintageDiscoverer.lambda$discover$0(VintageDiscoverer.java:53)
        at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
        at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
        at java.util.Iterator.forEachRemaining(Iterator.java:116)
        at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
        at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
        at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
        at java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:312)
        at java.util.stream.Streams$concatSpliterator.forEachRemaining(Streams.java:742)
        at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
        at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
        at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
        at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
        at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
        at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418)
        at org.junit.vintage.engine.discovery.VintageDiscoverer.discover(VintageDiscoverer.java:55)
        at org.junit.vintage.engine.VintageTestEngine.discover(VintageTestEngine.java:62)
        at org.junit.platform.launcher.core.DefaultLauncher.discoverEngineRoot(DefaultLauncher.java:168)
        at org.junit.platform.launcher.core.DefaultLauncher.discoverRoot(DefaultLauncher.java:155)
        at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:128)
        at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassprocessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassprocessor.java:102)
        at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassprocessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassprocessor.java:82)
        at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassprocessor.stop(JUnitPlatformTestClassprocessor.java:78)
        at org.gradle.api.internal.tasks.testing.SuiteTestClassprocessor.stop(SuiteTestClassprocessor.java:61)
        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.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
        at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
        at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
        at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchinginvocationHandler.invoke(ProxyDispatchAdapter.java:94)
        at com.sun.proxy.$Proxy2.stop(Unknown Source)
        at org.gradle.api.internal.tasks.testing.worker.TestWorker.stop(TestWorker.java:132)
        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.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
        at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
        at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:182)
        at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:164)
        at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:412)
        at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
        at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
        at java.lang.Thread.run(Thread.java:748)
    Caused by: java.io.IOException: Error while instrumenting com/github/goldy1992/mp3player/client/views/viewholders/MediaPlayerTrackViewHolder.
        at org.jacoco.agent.rt.internal_035b120.core.instr.Instrumenter.instrumentError(Instrumenter.java:158)
        at org.jacoco.agent.rt.internal_035b120.core.instr.Instrumenter.instrument(Instrumenter.java:108)
        at org.jacoco.agent.rt.internal_035b120.CoverageTransformer.transform(CoverageTransformer.java:91)
        ... 86 more
    Caused by: java.lang.IllegalStateException: Cannot process instrumented class com/github/goldy1992/mp3player/client/views/viewholders/MediaPlayerTrackViewHolder. Please supply original non-instrumented classes.
        at org.jacoco.agent.rt.internal_035b120.core.internal.instr.InstrSupport.assertNotInstrumented(InstrSupport.java:237)
        at org.jacoco.agent.rt.internal_035b120.core.internal.instr.ClassInstrumenter.visitField(ClassInstrumenter.java:55)
        at org.jacoco.agent.rt.internal_035b120.asm.ClassVisitor.visitField(ClassVisitor.java:287)
        at org.jacoco.agent.rt.internal_035b120.asm.ClassReader.readField(ClassReader.java:906)
        at org.jacoco.agent.rt.internal_035b120.asm.ClassReader.accept(ClassReader.java:683)
        at org.jacoco.agent.rt.internal_035b120.asm.ClassReader.accept(ClassReader.java:400)
        at org.jacoco.agent.rt.internal_035b120.core.instr.Instrumenter.instrument(Instrumenter.java:88)
        at org.jacoco.agent.rt.internal_035b120.core.instr.Instrumenter.instrument(Instrumenter.java:106)
        ... 87 more

要尝试找出问题的根源,我只是在运行客户端单元测试

客户端 build.gradle

apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
apply plugin: 'de.mannodermaus.android-junit5'
apply plugin: 'jacoco'

android {

    compileSdkVersion TARGET_SDK_VERION
    buildToolsVersion BUILD_TOOLS_VERSION

    defaultConfig {
        minSdkVersion MIN_SDK_VERSION
        targetSdkVersion TARGET_SDK_VERION
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        consumerproguardfiles 'consumer-rules.pro'
        vectorDrawables.useSupportlibrary = true
    }

    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'),'proguard-rules.pro'
        }
        debug {
            debuggable true
            minifyEnabled false
            testCoverageEnabled = true
        }
    }
    flavorDimensions 'default'
    productflavors {
        full {
            dimension = 'default'
        }
        automation {
            dimension = 'default'
        }
    }

    compileOptions {
        incremental = false
        sourceCompatibility JavaVersion.VERSION_1_8
        targetcompatibility JavaVersion.VERSION_1_8
    }

    kotlinOptions { jvmTarget = "1.8" }


    testOptions {
        execution 'ANDROID_TEST_ORCHESTRATOR'
        animationsDisabled true

        unitTests {
            includeAndroidResources = true
            returnDefaultvalues = true
        }

        unitTests.all {
            testLogging {
                events "passed","skipped","failed","standardOut","standardError"
                outputs.upToDateWhen {false}
                showStandardStreams = true
            }
        }
    }

    sourceSets {
        main.java.srcDirs += 'src/main/java'
        test.java.srcDirs += 'src/test/java'
        androidTest.java.srcDirs += 'src/androidTest/java'
    }
}

dependencies {
 implementation project(path: ':commons')
 testApi project(":client:testsupport")

 /* MORE DEPENDENCIES NOT RELEVANT TO ISSUE */
}

可能值得注意的是,我正在使用 Dagger 2.25.2

执行数据目录:$ {projectRootDir} /client/build/jacoco/testFullDebugUnitTest.exec

源目录:$ {projectRootDir} / client / src / main / java

类目录:$ {projectRootDir} / client / build / intermediates / javac / fullDebug / classes / ,$ {projectRootDir} / client / build / tmp / kotlin-classes / fullDebug /

更新1: 通过建立新分支并将客户端模块中的所有类和测试类重命名为CLASS_NAME.kt.old,我可以确认IllegalClassFormatException和no coverage之间似乎没有任何联系。因此,我将进行更新问题如下

更新2: 在对更新1进行进一步试验之后,似乎不存在异常,并且在不依赖子(测试)模块的情况下(即从gradle文件中删除行testApi project(":client:testsupport")),按预期计算了覆盖率。问题是我需要这个testsupport模块才能执行我的活动测试(由于更新1 ^^,它们当前位于.old文件中,因此当前未运行)。

问题已根据审核2更新 我如何配置JaCoCo以支持this pull request中的robolectric团队建议的android类的子模块测试实现。

如果需要更多信息,将更新帖子

weiyi961013 回答:Kotlin JaCoCo,无覆盖-> IllegalClassFormatException ...请提供原始的非仪器类

我刚刚遇到了同样的错误。

经过一番调查,似乎是Android Gradle Plugin中的一个错误,只有在使用com.android.library时才会发生。

我已经在此处报告了它以及更多详细信息:https://issuetracker.google.com/issues/178015739

虽然它不是由 Android 团队修复,但解决方法是配置

jacoco {
    toolVersion = "0.7.9"
}

在 build.gradle

它不会阻止错误被记录下来,而是可以正确收集覆盖率数据。

本文链接:https://www.f2er.com/2904731.html

大家都在问