szpak / gradle-pitest-plugin

Gradle plugin for PIT Mutation Testing
http://gradle-pitest-plugin.solidsoft.info/
211 stars 57 forks source link

Unsupported class file major version Error? #356

Closed JimLynchCodes closed 8 months ago

JimLynchCodes commented 9 months ago

Hi, I'm trying to get pitest running in this java gradle project but having a VERY difficult time... 😢

I have at least two problems: one about packages and one about Java versions.

1)

The first issue is that my project is set up with a public class not contained within any package. I know it is kind of an antipattern to do this, but for a project with only a single java class and test file it seems unnecessary to have an additional package container.

Anyway, it seems like pitest cannot file the file without it being inside of a package. Any I wrong here? Is there something I can put for the "testClasses" value that it would pick up my Lasagna class?

2)

Ok, so in the code here I have declared the "LP" package for my Lasagna class and updated my build.gradle with this pitest block:

pitest {
    targetClasses = ['LP*']  // by default "${project.group}.*"
    threads = 4
    outputFormats = ['XML', 'HTML']
    timestampedReports = false
    junit5PluginVersion = '1.2.0'
}

The problem though is when I run gradle pitest I get an "Unsupported class version" Error...

Task :pitest FAILED 11:17:45 AM PIT >> INFO : Verbose logging is disabled. If you encounter a problem, please enable it before reporting an issue. Exception in thread "main" java.lang.IllegalArgumentException: Unsupported class file major version 65 at org.pitest.reloc.asm.ClassReader.(ClassReader.java:199) at org.pitest.reloc.asm.ClassReader.(ClassReader.java:180) at org.pitest.reloc.asm.ClassReader.(ClassReader.java:166) at org.pitest.classinfo.ClassInfoVisitor.getClassInfo(ClassInfoVisitor.java:41) at org.pitest.classinfo.Repository.nameToClassInfo(Repository.java:70) at org.pitest.classinfo.Repository.fetchClass(Repository.java:60) at org.pitest.classinfo.NameToClassInfo.apply(NameToClassInfo.java:17) at org.pitest.classinfo.NameToClassInfo.apply(NameToClassInfo.java:7) at java.base/java.util.function.Function.lambda$andThen$1(Function.java:88) at java.base/java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:273) at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1708) at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509) at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499) at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921) at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:682) at org.pitest.classpath.CodeSource.getCode(CodeSource.java:44) at org.pitest.mutationtest.verify.DefaultBuildVerifier.verify(DefaultBuildVerifier.java:32) at org.pitest.mutationtest.tooling.MutationCoverage.verifyBuildSuitableForMutationTesting(MutationCoverage.java:275) at org.pitest.mutationtest.tooling.MutationCoverage.runReport(MutationCoverage.java:118) at org.pitest.mutationtest.tooling.EntryPoint.execute(EntryPoint.java:129) at org.pitest.mutationtest.tooling.EntryPoint.execute(EntryPoint.java:57) at org.pitest.mutationtest.commandline.MutationCoverageReport.runReport(MutationCoverageReport.java:98) at org.pitest.mutationtest.commandline.MutationCoverageReport.main(MutationCoverageReport.java:45)

When I run gradle -v I get this output:


Gradle 8.3

Build time: 2023-08-17 07:06:47 UTC Revision: 8afbf24b469158b714b36e84c6f4d4976c86fcd5

Kotlin: 1.9.0 Groovy: 3.0.17 Ant: Apache Ant(TM) version 1.10.13 compiled on January 4 2023 JVM: 21 (Homebrew 21) OS: Mac OS X 12.4 x86_64

When I run java -v it outputs an error, but I do have jabba installed and can switch versions if I need to, but I am unsure if it even wants me to switch the version my current shell is using or which version to switch it to...

szpak commented 9 months ago

Hi. From the exception:

Exception in thread "main" java.lang.IllegalArgumentException: Unsupported class file major version 65 at org.pitest.reloc.asm.ClassReader.(ClassReader.java:199)

and:

JVM: 21 (Homebrew 21)

it seems that PIT might don't support the latest JDK version. The good point is that @hcoles has just bumped the shaded ASM version and it should be available in the next PIT version.

hcoles commented 9 months ago

The recent bump of ASM is for Java 22 support. 21 should already work with the released version (although I don't think the test matrix was updated).

I think the issue in this case might be that an older version of PIT is configured.

szpak commented 9 months ago

You are completely right Henry:

id 'info.solidsoft.pitest' version '1.9.0'

which uses quite old PIT version. @JimLynchCodes please switch to 1.15.0 which uses PIT 1.15.0 by default (and could be also overridden)

JimLynchCodes commented 9 months ago

Thanks @szpak and @hcoles ! 🙏

I added these changes and pushed to the original repo.

It is running the mutations now, but for some reason it's saying they all fail, zero mutations killed...

I don't think that should be the output based on the tests that I have here, right? 🤔

Screen Shot 2023-10-09 at 3 15 10 PM

szpak commented 9 months ago

@JimLynchCodes The class Lasagna states to be in package LP, but the file Lasagna.java is in the wrong directory. That could be a reason. Don't you see any warning in vscode?

Btw, LasagnaTest is not in the same package, it could be, at least for sanity (the tests are not executed by PIT now).

hcoles commented 9 months ago

You have targetClasses set to 'LP' and nothing set for targetTests. Unless the gradle plugin does something different than pitest, this means your targetTests are also implicitly set to 'LP'.

Your code is in the package 'LP' (although the source file is in src/main/java rather than scr/main/java/LP) so is picked up by the filter.

The test is in the default package, so will not be picked up.

To fix move your test into the LP package. I'd also recomend moving the production source file into the standard location.

There are still a lot of other issues though. The tests aren't actually testing the code in the LP pacakge, they're testing another class of the same name that's in the src/test tree. Also, the tests fail.

JimLynchCodes commented 8 months ago

Thanks @hcoles and @szpak 👍

I sort of "inherited" this project so I would rather not change the directory structure or packages here.

However, I was able to get it working as is by just putting "Lasagna" and "LasagnaTest" as the values for TargetClasses and TargetTests, respectively:

pitest {
    targetClasses = ['Lasagna']
    targetTests = ['LasagnaTest']
    threads = 4
    outputFormats = ['XML', 'HTML']
    timestampedReports = false
    junit5PluginVersion = '1.2.0'
}

And I changed the plugin to version '1.15.0'.

It seems to be working, and I can view all the mutations in the nice html report.

So beautiful. 🥹 ☕️