[Example] shouldRunAfter can lead to EmptyStackException

Using shouldRunAfter in a build script can cause throwing of an EmptyStackException. The following simple build script reproduces the issue:

    task a
    task b
    task c
    task d
    
    d.dependsOn a, b, c
    a.shouldRunAfter b
    c.dependsOn d

Running gradle d results in the following stacktrace:

java.util.EmptyStackException
at org.gradle.execution.taskgraph.DefaultTaskExecutionPlan.restorePath(DefaultTaskExecutionPlan.java:280)
at org.gradle.execution.taskgraph.DefaultTaskExecutionPlan.determineExecutionPlan(DefaultTaskExecutionPlan.java:226)
at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter.ensurePopulated(DefaultTaskGraphExecuter.java:148)
at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter.execute(DefaultTaskGraphExecuter.java:82)
at org.gradle.execution.SelectedTaskExecutionAction.execute(SelectedTaskExecutionAction.java:29)
at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:61)
at org.gradle.execution.DefaultBuildExecuter.access$200(DefaultBuildExecuter.java:23)
at org.gradle.execution.DefaultBuildExecuter$2.proceed(DefaultBuildExecuter.java:67)
at org.gradle.execution.DryRunBuildExecutionAction.execute(DryRunBuildExecutionAction.java:32)
at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:61)
at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:54)

I could be wrong, but I think the issue might actually be caused by a cyclic dependency:

d.depndsOn a,b,c
c.dependsOn d

I’ll have to search through the code, but I don’t believe this to be a valid dependsOn structure.

In fact, when I run the sample build script, I get the following output:

FAILURE: Build failed with an exception.

  • What went wrong:
    Circular dependency between the following tasks:
    :c
    -– :d
    -– :c (*)

(*) - details omitted (listed previously)

I just realized that this issue had been resolved.

I just got the same exception on our CI server using Gradle 2.10.

Strangely enough it didn’t occur during local execution on Windows. Instead it brought up the actual problem, which was a cyclic dependency in my task graph (one of the tasks was not executed in a dev environment, which is why I didn’t find that out before). One of the edges in this cycle was based on RealizableTaskCollection depending on GenerateIvyDescriptor tasks created by model rules. May this be a problem?

I don’t have a concise example to reproduce the issue yet. Should I invest the effort?