pitest gradle plugin sometimes fails with Argument list too long

83 views
Skip to first unread message

Ugo Delle Donne

unread,
Feb 8, 2023, 5:50:50 AM2/8/23
to pitu...@googlegroups.com
Hello folks,
I just experienced a weird issue.

We configured pitest in a big gradle project.

Everything used to work fine, then all of a sudden we started experiencing some weird error when the pitest task runs in CD pipelines.

The gradle plugin (version 1.9.11) is configured as follows, and I'm configuring the useClasspathFile argument

```
apply plugin: 'info.solidsoft.pitest'
pitest {
        targetClasses = propertyAsSetWithDefault('targetClasses', DEFAULT_PACKAGES)
        targetTests = propertyAsSetWithDefault('targetTests', DEFAULT_PACKAGES)
        excludedClasses = propertyAsSetWithDefault('excludedClasses', ['*.wiring.*'])
        excludedTestClasses = propertyAsSetWithDefault('excludedTestClasses', [])
        avoidCallsTo = propertyAsSetWithDefault('avoidCallsTo', [])


        reportDir = file("$rootDir/reports/pitest/$moduleReportPath/")
        mutators = propertyAsSetWithDefault('mutators', DEFAULT_MUTATORS)

        jvmArgs = ['-Xmx1024m']
        jvmArgs.addAll(
                                '--add-opens=java.base/java.lang=ALL-UNNAMED',
                                '--add-opens=java.base/java.lang.reflect=ALL-UNNAMED',
                                '--add-opens=java.base/java.lang.ref=ALL-UNNAMED',
                        )

        mainProcessJvmArgs = ['-Djdk.attach.allowAttachSelf=true']
        useClasspathFile = true
        withHistory = true
}
```
when the pitest task is executed on CD machines it returns the error:
Exception in thread "main" org.pitest.util.PitError: Cannot run program "/opt/jdk17/bin/java": error=7, Argument list too long Please copy and paste the information and the complete stacktrace below when reporting an issue VM : Java HotSpot(TM) 64-Bit Server VM Vendor : Oracle Corporation Version : 17.0.1+12-LTS-39 Uptime : 1318 Input -> 1 : -Djdk.attach.allowAttachSelf=true 2 : -Dfile.encoding=UTF-8 3 : -Duser.country=US 4 : -Duser.language=en 5 : -Duser.variant BootClassPathSupported : false   at org.pitest.util.Unchecked.translateCheckedException(Unchecked.java:20)   at org.pitest.coverage.execute.DefaultCoverageGenerator.calculateCoverage(DefaultCoverageGenerator.java:106)   at org.pitest.coverage.execute.DefaultCoverageGenerator.calculateCoverage(DefaultCoverageGenerator.java:52)   at org.pitest.mutationtest.tooling.MutationCoverage.runAnalysis(MutationCoverage.java:149)   at org.pitest.mutationtest.tooling.MutationCoverage.runReport(MutationCoverage.java:139)   at org.pitest.mutationtest.tooling.EntryPoint.execute(EntryPoint.java:125)   at org.pitest.mutationtest.tooling.EntryPoint.execute(EntryPoint.java:52)   at org.pitest.mutationtest.commandline.MutationCoverageReport.runReport(MutationCoverageReport.java:98)   at org.pitest.mutationtest.commandline.MutationCoverageReport.main(MutationCoverageReport.java:45) Caused by: java.io.IOException: Cannot run program "/opt/jdk17/bin/java": error=7, Argument list too long   at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1143)   at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1073)   at org.pitest.process.WrappingProcess.start(WrappingProcess.java:48)   at org.pitest.coverage.execute.CoverageProcess.start(CoverageProcess.java:30)   at org.pitest.coverage.execute.DefaultCoverageGenerator.gatherCoverageData(DefaultCoverageGenerator.java:137)   at org.pitest.coverage.execute.DefaultCoverageGenerator.calculateCoverage(DefaultCoverageGenerator.java:90)   ... 7 more Caused by: java.io.IOException: error=7, Argument list too long   at java.base/java.lang.ProcessImpl.forkAndExec(Native Method)   at java.base/java.lang.ProcessImpl.<init>(ProcessImpl.java:314)   at java.base/java.lang.ProcessImpl.start(ProcessImpl.java:244)   at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1110)   ... 12 more

The error is not occurring on machines where development occurs (they are both linux machines).
I noticed in the logs of the machines where the task fails that it's logging: 
useClasspathJar=false

so I tried to modify the gradle configuration to include the 
useClasspathJar=true next to the already present 
useClasspathFile=true

and it seems that this allowed the task to run correctly.

Both environments are using the same major java version:

Environment that works without useClasspathJar:

java version "17.0.1" 2021-10-19 LTS
Java(TM) SE Runtime Environment (build 17.0.1+10-LTS-37)
Java HotSpot(TM) 64-Bit Server VM (build 17.0.1+10-LTS-37, mixed mode, sharing)

Environment that works only if useClasspathJar is specified:

java version "17.0.1" 2021-10-19 LTS
Java(TM) SE Runtime Environment (build 17.0.1+12-LTS-39)
Java HotSpot(TM) 64-Bit Server VM (build 17.0.1+12-LTS-39, mixed mode, sharing)

Has anybody else experienced something like this?

Thanks and regards,
Ugo

henry

unread,
Feb 8, 2023, 8:11:08 AM2/8/23
to PIT Users
I'm guessing that the path to either the code checkout location, or to the location of some of the included jars is longer on the CI server than the development machines. If a dependency was added recently, this may have been enough to trigger the limit on the CI server but not the development machines.

It's also possible that MAX_ARG_STRLEN is different on the development machines and the CI machine (I'm not clear on if/how this varies by linux distro, version and configuration, but if the machines are not an exact match it is a possibility).

Either way, using a classpath jar is the correct soloution. I'm trying to now remember if there is a disadvantage to doing this which means it couldn't be set as the default.

Henry

Ugo Delle Donne

unread,
Feb 8, 2023, 9:35:09 AM2/8/23
to pitu...@googlegroups.com
The checkout path is indeed longer on CI machines, but the command getconf ARG_MAX returns the same value on both environments.

I always had the issue with too many arguments, and the fix from when we started using the library was to configure the parameter useClasspathFile.

Now that parameter alone does not seem to be enough, I had to set also the useClasspathJar, that I don't see in the documentation, and has happened with the plugin version 1.7.0, and 1.9.11


--
You received this message because you are subscribed to the Google Groups "PIT Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pitusers+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/pitusers/61bdd594-5e40-43e6-9338-4f0246da8889n%40googlegroups.com.

Marcin Zajączkowski

unread,
Feb 8, 2023, 6:24:49 PM2/8/23
to PIT Users
useClasspathFile and useClasspathJar should help with too long
classpath. I'm glad you were able to fix it in your project.

useClasspathJar is not mentioned in the plugin README as it covers only
the elements specific for the Gradle integration and refers to the
official PIT documentation instead [2] (and also to the extension object
[3], but it's rather for syntax, not for description).

@Henry, I wonder if it should be covered there ([2]) or GPP should link
to some other page to have all available PIT parameters summarized?

Btw, support for useClasspathJar has been added in gradle-pitest-plugin
1.4.6 in the late 2019 [1].


[1] - https://github.com/szpak/gradle-pitest-plugin/issues/92
[2] - https://pitest.org/quickstart/commandline/
[3] -
https://github.com/szpak/gradle-pitest-plugin/blob/master/src/main/groovy/info/solidsoft/gradle/pitest/PitestPluginExtension.groovy


Marcin
https://blog.solidsoft.pl/ - Solid Soft - Working code is not enough

Reply all
Reply to author
Forward
0 new messages