hcoles / pitest

State of the art mutation testing system for the JVM

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

NPE with retrolambda

8armed-monkey opened this issue · comments

Hi I am getting the following exception after upgrading to Kotlin v1.1:

Exception in thread "main" java.lang.NullPointerException
        at org.pitest.mutationtest.filter.KotlinFilter$1.apply(KotlinFilter.java:34)
        at org.pitest.mutationtest.filter.KotlinFilter$1.apply(KotlinFilter.java:31)
        at org.pitest.functional.predicate.Not.apply(Not.java:33)
        at org.pitest.functional.predicate.Not.apply(Not.java:23)
        at org.pitest.functional.FCollection.filter(FCollection.java:84)
        at org.pitest.functional.FCollection.filter(FCollection.java:77)
        at org.pitest.mutationtest.filter.KotlinFilter.filter(KotlinFilter.java:27)
        at org.pitest.mutationtest.filter.CompoundMutationFilter.filter(CompoundMutationFilter.java:22)
        at org.pitest.mutationtest.build.MutationSource.createMutations(MutationSource.java:52)
        at org.pitest.mutationtest.build.MutationTestBuilder$2.apply(MutationTestBuilder.java:100)
        at org.pitest.mutationtest.build.MutationTestBuilder$2.apply(MutationTestBuilder.java:97)
        at org.pitest.functional.FCollection.flatMapTo(FCollection.java:56)
        at org.pitest.functional.FCollection.flatMap(FCollection.java:66)
        at org.pitest.mutationtest.build.MutationTestBuilder.createMutationTestUnits(MutationTestBuilder.java:56)
        at org.pitest.mutationtest.tooling.MutationCoverage.buildMutationTests(MutationCoverage.java:277)
        at org.pitest.mutationtest.tooling.MutationCoverage.runReport(MutationCoverage.java:133)
        at org.pitest.mutationtest.tooling.EntryPoint.execute(EntryPoint.java:103)
        at org.pitest.mutationtest.tooling.EntryPoint.execute(EntryPoint.java:45)
        at org.pitest.mutationtest.commandline.MutationCoverageReport.runReport(MutationCoverageReport.java:87)
        at org.pitest.mutationtest.commandline.MutationCoverageReport.main(MutationCoverageReport.java:45)

I am running it with Gradle:
./gradlew clean pitest

I'm guessing that Kotlin is now not including source file debug information in one or more classes.

Although it will be easy enough to fix the NPE here this might cause other problems as pitest relies on this debug info to generate the final report.

If you can put together a minimal example that reproduces the problem I can take a look.

Ah, the thing is my project doesn't contain any Kotlin source code. I am using Java only.

Don't quite follow how/why you are upgrading kotlin if you are not using it.

If you can put together a minimal example that reproduces the problem I can take a look.

I am using Kotlin for other projects but not this particular one. I'll try to setup a minimum example later and let you know.

Hi, it looks like it might be caused by Retrolambda. The sample project is available here:
https://github.com/8armed-monkey/sample-npe-pitest-retrolambda

Thanks @8armed-monkey for SSCCE. It helped me to reproduce the issue.

First, I was suspecting that Kotlin is somehow leaking into the classpath use but PIT, but it's not the case:

CP is :pitest-1.2.0.jar:/tmp/sample-npe-pitest-retrolambda/meh/build/classes/test:/tmp/sample-npe-pitest-retrolambda/meh/build/classes/main:rxjava-2.0.6.jar:junit-4.12.jar:mockito-all-1.10.19.jar:hamcrest-all-1.3.jar:reactive-streams-1.0.0.jar:hamcrest-core-1.3.jar

Later on, I realized that you mentioned that the problem occur even in projects which don't use Kotlin (like that one :) ).

The NPE is in the line:

return a.getFilename().toLowerCase().endsWith(".kt") && a.getLineNumber() == 0;

which suggests that a filename is null. I debugged that and the ill-fated object is:

MutationDetails [id=MutationIdentifier [location=Location [clazz=test.event.EventBroadcasterImpl$$Lambda$1, method=test, methodDesc=(Ljava/lang/Object;)Z], indexes=[6], mutator=org.pitest.mutationtest.engine.gregor.mutators.ReturnValsMutator], filename=null, block=1, lineNumber=0, description=replaced return of integer sized value with (x == 0 ? 1 : 0), testsInOrder=[]]

The filename is null, but it shouldn't. The problem may be related to retrolamba.

@8armed-monkey Could you check if the problem occurs also without retrolambda? If not, could you try to use the latest version of retrolambda (2.5.1) to verify that the problem hasn't been already fixed? If not, it would be good to report it :).

@hcoles Maybe it would be good to perform a sanity check of (some) input parameters when MutationDetails is created to be able to fail fast with some more details about the context where MutationDetails was being created?

Btw, just in case, as it may not be documented (yet), to debug PIT in a Gradle build it is enough to set:

pitest {
    mainProcessJvmArgs = ["-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005"]
}

@szpak The problem doesn't occur if I change the lambda / method reference to anonymous inner classes (the Retrolambda plugin is still being used, but it doesn't create additional classes).

I updated the Retrolambda plugin as well, but the problem is still there. Will report the issue to Retrolambda devs.

This has been fixed in Retrolambda 2.5.3