StackOverflowError during parallel build

Hello,

we are
currently migrating from maven to gradle and our java build contains currently
at least 25 modules with tests. The build is working very well (incl. prallel
builds) except with following use case:

When I
execute a full parallel build, then the execution of the task test is running
into a StackOverflowError:

:moduleXY:test

Unexpected
exception thrown.

java.lang.StackOverflowError

    at

java.security.AccessController.doPrivileged(Native Method)

    at

java.io.ObjectStreamClass.(ObjectStreamClass.java:455)

    at

java.io.ObjectStreamClass.lookup(ObjectStreamClass.java:352)

    at java.io.ObjectStreamClass.<init>(ObjectStreamClass.java:451)

    at

java.io.ObjectStreamClass.lookup(ObjectStreamClass.java:352)

    at

java.io.ObjectStreamClass.(ObjectStreamClass.java:451)

    at

java.io.ObjectStreamClass.lookup(ObjectStreamClass.java:352)

    at

java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1130)

    at

java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1528)

    at

java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1493)

    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416)

    at

java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)

    at

java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1528)

    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1493)

    at

java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416)

    at

java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)

    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1528)

    at

java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1493)

    at

java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416)

    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)

    at

java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1528)

    at

java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1493)

    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416)

    at

java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)

… and so
on

The gradle
process does not terminate after the error above. The process seems to be in a
frozen state. When I abort the process and restart the all tests again
(incremental execution of the module tests), then the StackOverflowError does
not occur. As far as I can see from the log output (gradle started with
activated debug logger) all tests of all modules were executed. According to
the log output gradle starts for each module a “Gradle Test Executor” and
according to the output all Executors were completed:

For each
instantiated test executor following lines exists in the log output:

[QUIET]
[system.out] 11:47:30.216 [DEBUG]
[org.gradle.process.internal.child.ActionExecutionWorker] Completed Gradle Test
Executor 26.

And also following
line (except for one test executor):

[DEBUG]
[org.gradle.process.internal.DefaultExecHandle] Process ‘Gradle Test Executor
26’ finished with exit value 0 (state: SUCCEEDED)

To
reproduce this issue I execute a “full build” by following steps:

  1. gradlew
    clean

  2. gradlew
    assemble

  3. gradlew
    testClasses

  4. gradlw
    test (-> the StackOverflowError occurs)

This issue
occurs with gradle 2.6, 2.7, 2.8 and 2.9.

I would
like to provide more information, but I do not know how to get more details.

Kind
Regards

Markus

Could you provide the output from gradlew test --stacktrace when it fails?

Is the stack overflow always occurring in the same project’s tests?

When you reproduce the issue, does it occur every time with those steps or only occasionally?

Are the test tasks themselves using any concurrency (e.g., a custom setting for forkEvery or maxParallelForks)?

Hi Sterling,

here the answers to your questions:

Attached you can find the relevant parts of the output (complete stacktrace).
The issue occurs every time, the issue occurs in the same project’s tests and there is no concurrency within the tests itself.

Regards
Markus

log.zip (840 Bytes)

Hi Markus,

The stack trace in the log file might be truncated.
Could you repeat the test and provide the output after adding -XX:MaxJavaStackTraceDepth=-1 to JVM options for Gradle? It might also be necessary to use the --full-stacktrace/-S option for gradlew, gradlew test -S.

One way to add JVM options on Unixes is to issue
export GRADLE_OPTS="-XX:MaxJavaStackTraceDepth=-1 -Xmx2g -XX:MaxPermSize=256m -Dorg.gradle.jvmargs='-XX:MaxJavaStackTraceDepth=-1 -Xmx2g -XX:MaxPermSize=256m'" .

Using -XX:MaxJavaStackTraceDepth=-1 makes it possible to see where the call started. That’s usually required for investigating StackOverflowErrors in Java.

-Lari

Hi Lari,

attached you find the stack trace produced with the additional JVM options.

Markuslog.zip (2.9 KB)

This might be a bug in Gradle’s ExceptionReplacingObjectOutputStream and ExceptionPlaceholder solution. Similar to https://issues.gradle.org/browse/GRADLE-1996 , but different.