Jacoco-related failure in multiproject build


(Mark Petrovic) #1

I have a multi-project Gradle v1.8 build that applies the jacoco plugin to one of the subprojects:

apply plugin: 'jacoco'

When I build from the top-level directory of the parent project, I see a lot of stack traces indicating something failing:

:common:page-object-core:test
Exception in thread "main" FATAL ERROR in native method: processing of -javaagent failed
java.lang.ClassNotFoundException: org.jacoco.agent.rt.internal_5d10cad.PreMain
 at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
 at java.security.AccessController.doPrivileged(Native Method)
 at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
 at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
 at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
 at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
 at sun.instrument.InstrumentationImpl.loadClassAndStartAgent(InstrumentationImpl.java:280)
 at sun.instrument.InstrumentationImpl.loadClassAndCallPremain(InstrumentationImpl.java:338)
Could not write standard input into: Gradle Worker 2.
java.io.IOException: Broken pipe
 at java.io.FileOutputStream.writeBytes(Native Method)
 at java.io.FileOutputStream.write(FileOutputStream.java:282)
 at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:65)
 at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:123)
 at org.gradle.process.internal.streams.ExecOutputHandleRunner.run(ExecOutputHandleRunner.java:50)
 at org.gradle.internal.concurrent.DefaultExecutorFactory$StoppableExecutorImpl$1.run(DefaultExecutorFactory.java:66)
 at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
 at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
 at java.lang.Thread.run(Thread.java:680)
Exception in thread "main" java.lang.ClassNotFoundException: org.jacoco.agent.rt.internal_5d10cad.PreMain
FATAL ERROR in native method: processing of -javaagent failed
 at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
 at java.security.AccessController.doPrivileged(Native Method)
 at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
 at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
 at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
 at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
 at sun.instrument.InstrumentationImpl.loadClassAndStartAgent(InstrumentationImpl.java:280)
 at sun.instrument.InstrumentationImpl.loadClassAndCallPremain(InstrumentationImpl.java:338)
Could not write standard input into: Gradle Worker 3.
java.io.IOException: Broken pipe
...

But when I go into the subproject directory and build there, I see no such error.

Can anyone comment?

Thanks.


(Mark Petrovic) #2

Here is a test project that reproduces the failure:

https://github.com/ae6rt/gradle-jacoco-lab

From the top level directory, this fails:

$ ./gradlew clean build
:clean UP-TO-DATE
:proj1:clean UP-TO-DATE
:proj2:clean UP-TO-DATE
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:jar
:assemble
:compileTestJava UP-TO-DATE
:processTestResources UP-TO-DATE
:testClasses UP-TO-DATE
:test UP-TO-DATE
:check UP-TO-DATE
:build
:proj1:compileJava
:proj1:processResources UP-TO-DATE
:proj1:classes
:proj1:jar
:proj1:assemble
:proj1:compileTestJava
:proj1:processTestResources UP-TO-DATE
:proj1:testClasses
:proj1:test
Exception in thread "main" FATAL ERROR in native method: processing of -javaagent failed
java.lang.ClassNotFoundException: org.jacoco.agent.rt.internal_5d10cad.PreMain
 at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
 at java.security.AccessController.doPrivileged(Native Method)
 at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
 at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
 at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
 at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
 at sun.instrument.InstrumentationImpl.loadClassAndStartAgent(InstrumentationImpl.java:280)
 at sun.instrument.InstrumentationImpl.loadClassAndCallPremain(InstrumentationImpl.java:338)
Could not write standard input into: Gradle Worker 1.
java.io.IOException: Broken pipe
 at java.io.FileOutputStream.writeBytes(Native Method)
 at java.io.FileOutputStream.write(FileOutputStream.java:282)
 at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:65)
 at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:123)
 at org.gradle.process.internal.streams.ExecOutputHandleRunner.run(ExecOutputHandleRunner.java:50)
 at org.gradle.internal.concurrent.DefaultExecutorFactory$StoppableExecutorImpl$1.run(DefaultExecutorFactory.java:66)
 at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
 at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
 at java.lang.Thread.run(Thread.java:695)
:proj1:test FAILED
  FAILURE: Build failed with an exception.
  * What went wrong:
Execution failed for task ':proj1:test'.
> Process 'Gradle Worker 1' finished with non-zero exit value 134
  * Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
  BUILD FAILED
  Total time: 1.948 secs

But from proj1/, to which jacoco plugin has been applied, this does not fail:

proj1> ../gradlew clean build
:proj1:clean
:proj1:compileJava
:proj1:processResources UP-TO-DATE
:proj1:classes
:proj1:jar
:proj1:assemble
:proj1:compileTestJava
:proj1:processTestResources UP-TO-DATE
:proj1:testClasses
:proj1:test
:proj1:check
:proj1:build
  BUILD SUCCESSFUL
  Total time: 2.465 secs

(jbisotti) #3

Looks like you have stumbled upon GRADLE-2859, which is caused by GRADLE-2860. I had the same problem with my integ tests. The following fixed it for me:

task integTest(type: Test) {
        ...
        // GRADLE-2859
        systemProperties['user.dir'] = workingDir
    }

(Mark Petrovic) #4

Thanks. I’m just getting back to this.

Your solution works for me, too.

But is there a way to arrange for this assigment to take place for all tasks of type Test in a multiproject build?

I tried

allprojects {
    tasks.withType(Test) {
        systemProperties['user.dir'] = workingDir
    }
}

but found that the jacoco failure still obtains. I have a 25-submodule build. I’d like to centralize this in one place, rather than maintain it for all test/intTest tasks explicity.

Thanks much.


(Mark Petrovic) #5

I find that this works to flow the config down to subprojects:

apply from: file("${rootDir}/gradle/jacoco.gradle")

where this apply-from-file is used in place of

apply plugin: 'jacoco'

and contains

apply plugin: 'jacoco'
  test {
    systemProperties['user.dir'] = workingDir
}