Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cobertura gives Argument list too long

I am trying to generate code coverage reports using cobertura plugin.

I have this dependency in my pom.xml

<plugin>
     <groupId>org.codehaus.mojo</groupId>
     <artifactId>cobertura-maven-plugin</artifactId>
     <version>2.6</version>
     <executions>
         <execution>
             <phase>test</phase>
             <goals>
              <goal>cobertura</goal>
             </goals>
             <configuration>
                 <formats>
                     <format>html</format>
                     <format>xml</format>
                  </formats>
             </configuration>
         </execution>
     </executions>
  <configuration>
      <formats>
          <format>html</format>
          <format>xml</format>
    </formats>
</configuration>

When I build my project using this goal -U -B clean install cobertura:cobertura, i get the below error on my jenkins CI

 16:37:31 [ERROR] Failed to execute goal org.codehaus.mojo:cobertura-maven-plugin:2.6:instrument (default-cli) on project TestModule: Unable to execute Cobertura. Error while executing process. Cannot run program "/bin/sh": error=7, Argument list too long -> [Help 1]
16:37:31 org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.codehaus.mojo:cobertura-maven-plugin:2.6:instrument (default-cli) on project TestModule: Unable to execute Cobertura.
16:37:31    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:216)
16:37:31    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
16:37:31    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
16:37:31    at org.apache.maven.lifecycle.internal.MojoExecutor.executeForkedExecutions(MojoExecutor.java:364)
16:37:31    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:198)
16:37:31    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
16:37:31    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
16:37:31    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:84)
16:37:31    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:59)
16:37:31    at org.apache.maven.lifecycle.internal.LifecycleStarter.singleThreadedBuild(LifecycleStarter.java:183)
16:37:31    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:161)
16:37:31    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:317)
16:37:31    at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:152)
16:37:31    at org.apache.maven.cli.MavenCli.execute(MavenCli.java:555)
16:37:31    at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:214)
16:37:31    at org.apache.maven.cli.MavenCli.main(MavenCli.java:158)
16:37:31    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
16:37:31    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:76)
16:37:31    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
16:37:31    at java.lang.reflect.Method.invoke(Method.java:602)
16:37:31    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289)
16:37:31    at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229)
16:37:31    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415)
16:37:31    at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356)
16:37:31 Caused by: org.apache.maven.plugin.MojoExecutionException: Unable to execute Cobertura.
16:37:31    at org.codehaus.mojo.cobertura.tasks.AbstractTask.executeJava(AbstractTask.java:244)
16:37:31    at org.codehaus.mojo.cobertura.tasks.InstrumentTask.execute(InstrumentTask.java:139)
16:37:31    at org.codehaus.mojo.cobertura.CoberturaInstrumentMojo.execute(CoberturaInstrumentMojo.java:162)
16:37:31    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:106)
16:37:31    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:208)
16:37:31    ... 23 more
16:37:31 Caused by: org.codehaus.plexus.util.cli.CommandLineException: Error while executing process.
16:37:31    at org.codehaus.plexus.util.cli.Commandline.execute(Commandline.java:656)
16:37:31    at org.codehaus.plexus.util.cli.CommandLineUtils.executeCommandLine(CommandLineUtils.java:144)
16:37:31    at org.codehaus.plexus.util.cli.CommandLineUtils.executeCommandLine(CommandLineUtils.java:107)
16:37:31    at org.codehaus.mojo.cobertura.tasks.AbstractTask.executeJava(AbstractTask.java:240)
16:37:31    ... 27 more
16:37:31 Caused by: java.io.IOException: Cannot run program "/bin/sh": error=7, Argument list too long
16:37:31    at java.lang.ProcessBuilder.start(ProcessBuilder.java:1042)
16:37:31    at java.lang.Runtime.exec(Runtime.java:615)
16:37:31    at java.lang.Runtime.exec(Runtime.java:526)
16:37:31    at org.codehaus.plexus.util.cli.Commandline.execute(Commandline.java:636)
16:37:31    ... 30 more
16:37:31 Caused by: java.io.IOException: error=7, Argument list too long
16:37:31    at java.lang.UNIXProcess.<init>(UNIXProcess.java:139)
16:37:31    at java.lang.ProcessImpl.start(ProcessImpl.java:152)
16:37:31    at java.lang.ProcessBuilder.start(ProcessBuilder.java:1023)
16:37:31    ... 33 more

The build is successful on my windows machine but fails on jenkins. When I downgrade cobertura version to 2.5.1 this error goes away but I get some parse exceptions since the parser for cobertura for 2.5.1 is not up to date with java syntax.

Can someone help me get this working for 2.6.0 versions and higher for cobertura

like image 703
user2973475 Avatar asked Apr 08 '15 19:04

user2973475


2 Answers

This borders on the lines of relevance but may offer assistance

This is caused by a linux limitation whereby the arguments can't exceed 128kb in size See Linux Kernel constant: MAX_ARG_STRLEN https://github.com/torvalds/linux/blob/master/include/uapi/linux/binfmts.h

Within Jenkins once you read from/to a variable where this value is exceeded, you will hit this error. In my case, I had a github webhook that launched a Jenkins job and set a payload parameter to some string > than this limit. Attempting to read this parameter would throw this error.

In order to work around the problem, I have a child job that uses a rest-api call to read the value from parent

You can let the parent job throw a failure, but allow the child job to be launched in all cases. Below is a slightly refined function I used to pull the information (Stripped out error checking and comments for brevity)

def get_parameter_value_from_parent():
    host = 'https://[YOUR_COMPANY].ci.cloudbees.com'
    this_build_url = os.environ.get('BUILD_URL')
    request_auth = (JENKINS_USER, JENKINS_TOKEN)

    url = '{0}/api/json'.format(this_build_url)
    parameter_name = 'payload'
    payload = ''

    #
    # Get the upstreamBuild number, and the upstreamUrl
    # so we can put together a link to the upstream job
    #

    response = requests.get(url, auth=request_auth)
    this_build = json.loads(response)

    build_number = ''
    short_url = ''
    actions = this_build['actions']
    for action in actions:
        if action.get('causes'):
            for cause in action.get('causes'):
                build_number = cause['upstreamBuild']
                short_url = cause['upstreamUrl']

    parent_url = '{host}/{short_url}{build}/api/json'.format(host=host,
            short_url=short_url, build=build_number)

    #
    # Now get the payload from the parent job by making REST api call
    #

    response = requests.get(parent_url, auth=request_auth)
    upstream_build = json.loads(response)

    actions = upstream_build['actions']
    for action in actions:
        if action.get('parameters'):
            for parameter in action.get('parameters'):
                if parameter['name'] == parameter_name:
                    value = parameter['value']
                    payload = value
                    return payload

    print 'Error: Unable to return payload from parent jenkins job: {0}'.format(parent_url)
    sys.exit(1)
like image 102
Tylee Avatar answered Oct 19 '22 09:10

Tylee


All shell have a limit for the command line length. UNIX / Linux / BSD system has a limit on how many bytes can be used for the command line argument and environment variables.

When you start a new process or type a command these limitations are applied and you will see an error message as follows on screen:

Argument list too long

Cobertura is trying to execute a shell command:

getLog().debug( "Working Directory: " + cl.getWorkingDirectory() );
getLog().debug( "Executing command line:" );
getLog().debug( cl.toString() );

int exitCode;
try
{
    exitCode = CommandLineUtils.executeCommandLine( cl, stdout, stderr );
}
catch ( CommandLineException e )
{
    throw new MojoExecutionException( "Unable to execute Cobertura.", e );
}

In fact, the plugin is trying to execute a java process to run cobertura:

 Commandline cl = new Commandline();
 File java = new File( SystemUtils.getJavaHome(), "bin/java" );
 cl.setExecutable( java.getAbsolutePath() );
 cl.addEnvironment("CLASSPATH", createClasspath());

 String log4jConfig = getLog4jConfigFile();
 if ( log4jConfig != null )
 {
     cl.createArg().setValue( "-Dlog4j.configuration=" + log4jConfig );
 }

 cl.createArg().setValue( "-Xmx" + maxmem );

 cl.createArg().setValue( taskClass );

 if ( cmdLineArgs.useCommandsFile() )
 {
     String commandsFile;
     try
     {
          commandsFile = cmdLineArgs.getCommandsFile();
     }
     catch ( IOException e )
     {
           throw new MojoExecutionException( "Unable to obtain CommandsFile location.", e );
     }
     if ( FileUtils.fileExists( commandsFile ) ) 
     {
            cl.createArg().setValue( "--commandsfile" );
            cl.createArg().setValue( commandsFile );
      }
      else 
      {
             throw new MojoExecutionException( "CommandsFile doesn't exist: "  + commandsFile );
      }
 }
 else
 {
      Iterator<String> it = cmdLineArgs.iterator();
      while ( it.hasNext() )
      {
          cl.createArg().setValue( it.next() );
      }
 }

So, first of all, enable cobertura DEBUG traces to show the shell command executed.

I think the problem would be the classpath used in version 2.6 vs the one used in version 2.5.1.

Please, enable debug traces and post the result:

https://wiki.jenkins-ci.org/display/JENKINS/Logging

like image 32
jfcorugedo Avatar answered Oct 19 '22 08:10

jfcorugedo