Kotlin / kotlinx-kover

Apache License 2.0
1.28k stars 48 forks source link

Exception in thread "main" java.lang.NullPointerException #228

Closed henriquesandri closed 1 year ago

henriquesandri commented 1 year ago

When I run some task to generate xml report, I have this error:

Exception in thread "main" java.lang.NullPointerException
    at com.intellij.rt.coverage.report.XMLCoverageReport.writeLine(XMLCoverageReport.java:221)
    at com.intellij.rt.coverage.report.XMLCoverageReport.writeFile(XMLCoverageReport.java:141)
    at com.intellij.rt.coverage.report.XMLCoverageReport.writePackage(XMLCoverageReport.java:123)
    at com.intellij.rt.coverage.report.XMLCoverageReport.writeProject(XMLCoverageReport.java:93)
    at com.intellij.rt.coverage.report.XMLCoverageReport.write(XMLCoverageReport.java:58)
    at com.intellij.rt.coverage.report.Reporter.createXMLReport(Reporter.java:42)
    at com.intellij.rt.coverage.report.Main.main(Main.java:38)

I've already tried koverXmlReport, koverMergedXmlReport and koverMergedReport. Html's report is working fine.

Unfortunately my project isnt open source, so I can't share the code.

Thanks for the help.

k3marek commented 1 year ago

In my case it was caused by an already compiled different build configuration with implementation of the same class for a different build version or build configuration (debug/release). You may check it easily by opening the generated and broken xml file and looking for the last class that was examined - that is the cause.

I know It should work properly for every possible configuration, because all those classes should be unit tested and the coverage should check it, but as a quick solution you may try to setup only single debug configuration for all tests and exclude all different ones.

I use such config, which is shared across android, java modules

ext.setupCoverage = {
        kover {
            ...
            instrumentation {
                //perform only on api24 debug build configuration
                //exclude api21, release
                excludeTasks.addAll(
                        "testReleaseUnitTest",
                        "testApi21DebugUnitTest",
                        "testApi21ReleaseUnitTest",                        
                        "testApi24ReleaseUnitTest")
            }
        }
    }

Note - if you run any task before the koverReport that will compile a different build configuration, then even if you have proper kover instrumentation rules, the report will fail.

Note 2 - from my observation, this error is not reproducible on every machine - on one mac it was working properly, on ubuntus or different macs it was failing every time, despite of java -v or other factors. Finally, only proper instrumentation rules and build task order solved my problems...

And finally, I want to kindly ask authors to take a look on this issue.

henriquesandri commented 1 year ago

Hi everyone,

@k3marek, thanks for your answer, after I added a few files into excludes, my xmlReport task is working. I also believe this issue could be solved to improve the Kover, so I also want to kindly ask authors to take a look on this issue.

I would like to thank you in advance for assistance and say that I am available for questions if necessary.

shanshin commented 1 year ago

Hi, @k3marek, thanks for the research, it will help with solving the problem! @henriquesandri, of course, first of all it should be solved by introducing filters for build types. However, the NPE error message does not help users in understand the causes of the error, so the agent also needs to be fixed - a small producer would help with this.

shanshin commented 1 year ago

Relates #18

henriquesandri commented 1 year ago

@shanshin ,

Sorry for my beginner question, but can I debug the problematic task if I clone the Kover project? If yes, there are any documentation which explain it?

I'd like to obtain more information and maybe propose some solution.

shanshin commented 1 year ago

@henriquesandri , there is no such possibility now.

The error does not occur in the plugin itself, but in an external toolchain to it (IntelliJ Coverage Engine). Connect from debugger to the task koverXmlReport possible only with a small modification of the plugin itself (adding a debugging agent to plugin).

As far as I understand, in your case, NPE is thrown out when there are several classes with the same name in the project, located in different files (in different build types)

tjerkw commented 1 year ago

Same problem for mu multiplatform module

Tried to exclude tasks but didnt work:

kover {
    instrumentation {
        excludeTasks += setOf("jsTest", "iosTest") 
    }
}

> Task :shared:koverXmlReport FAILED
Exception in thread "main" java.lang.NullPointerException
        at com.intellij.rt.coverage.report.XMLCoverageReport.writeLine(XMLCoverageReport.java:221)
        at com.intellij.rt.coverage.report.XMLCoverageReport.writeFile(XMLCoverageReport.java:141)
        at com.intellij.rt.coverage.report.XMLCoverageReport.writePackage(XMLCoverageReport.java:123)
        at com.intellij.rt.coverage.report.XMLCoverageReport.writeProject(XMLCoverageReport.java:93)
        at com.intellij.rt.coverage.report.XMLCoverageReport.write(XMLCoverageReport.java:58)
        at com.intellij.rt.coverage.report.Reporter.createXMLReport(Reporter.java:42)
        at com.intellij.rt.coverage.report.Main.main(Main.java:38)
``
shanshin commented 1 year ago

@tjerkw , could you provide a reproducer? Kover currently only works with JVM tasks, so excluding jsTest and iosTest won't help in this case.

tjerkw commented 1 year ago

I found it:

in commonMain

expect class PlatformLogOutput() : LogOutput

And in jvmMain I have an actual.

I solved it now by just ignoring this class:

kover {
    filters {
        classes {
            // Kover doesnt work well with actuals:
            // https://github.com/Kotlin/kotlinx-kover/issues/228
            excludes += listOf("my.project.PlatformLogOutput")
        }
    }
}
shanshin commented 1 year ago

@tjerkw, thanks!

zuevmaxim commented 1 year ago

NPE is fixed in agent version 1.0.688

shanshin commented 1 year ago

To use custom engine you need to configure it in all projects where Kover is used

for Kotlin Gradle script

kover {
    engine.set(kotlinx.kover.api.IntellijEngine("1.0.688"))
}

for Groovy

kover {
    engine = new kotlinx.kover.api.IntellijEngine("1.0.688")
}
shanshin commented 1 year ago

Fixed in 0.7.0-Alpha