Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exceptions in @OutputFiles method can hang Gradle 4.0 without reporting the exceptions #2407

Closed
rkrisztian opened this issue Jul 7, 2017 · 2 comments

Comments

@rkrisztian
Copy link

rkrisztian commented Jul 7, 2017

This is related to #2406, where we discussed that the use case wasn't valid, however, this time, I think it is important to fix regardless of the use case.

Expected Behavior

Gradle 4.0 should not hang when a Task method annotated with @OutputFiles throws any kind of exception.

Current Behavior

I executed gw myPreceedingTask --stacktrace --info with the example build script below, and I was expecting an NPE to be reported.

> Task :myPreceedingTask
Putting task artifact state for task ':myPreceedingTask' into context took 0.0 secs.
Executing task ':myPreceedingTask' (up-to-date check took 0.0 secs) due to:
  Task has not declared any outputs.
Hello from myPreceedingTask!

:myPreceedingTask (Thread[Task worker Thread 2,5,main]) completed. Took 0.014 secs.
<======-------> 50% EXECUTING [4m 6s]
> IDLE
^C

It just does not terminate.

I did some debugging, and found that the related code part that is interesting for us is org.gradle.execution.taskgraph.DefaultTaskExecutionPlan#executeWithTask:

                    try {
                        selected.set(DefaultTaskExecutionPlan.this.selectNextTask(workerLease));
                    } catch (Throwable var3) {
                        DefaultTaskExecutionPlan.this.abortAndFail(var3);
                        workRemaining.set(false);
                    }

where:

    private void abortAndFail(Throwable t) {
        this.abortExecution();
        this.failures.add(t);
    }

where:

    private boolean abortExecution() {
        boolean aborted = false;
        Iterator i$ = this.executionPlan.values().iterator();

        while(i$.hasNext()) {
            TaskInfo taskInfo = (TaskInfo)i$.next();
            if(taskInfo.isRequired()) {
                taskInfo.skipExecution();
                aborted = true;
            }
        }

        return aborted;
    }

Then, TaskInfo.isRequired is false for both :myTestTask and :myPreceedingTask, causing the build to hang. I think one of those should still be required.

If I replace the association from myPreceedingTask.finalizedBy myTestTask to myPreceedingTask.dependsOn myTestTask, then I get the right error message and the build terminates.

Context

In my actual code, the task that I represented here with myTestTask, is actually not a finalizer, but I have no idea why it is not required in the TaskInfo.

Steps to Reproduce (for bugs)

This time my gradle.build looks like this:

group 'myTest'
version '1.0-SNAPSHOT'

task wrapper(type: Wrapper) {
	gradleVersion = '4.0'
	distributionUrl = "https://services.gradle.org/distributions/gradle-$gradleVersion-all.zip"
}

apply plugin: 'groovy'

repositories {
	mavenCentral()
}

dependencies {
	compile gradleApi()
	compile 'org.codehaus.groovy:groovy-all:2.4.11'
}

class MyTestTask extends DefaultTask {
	MyTestTask() {
		outputs.upToDateWhen { false }
	}

	@OutputFiles
	List<File> getMyOutputs() {
		throw new NullPointerException('my exception')
	}

	@TaskAction
	void printHello() {
		println 'Hello from myTestTask!'
	}
}

task myPreceedingTask {
	doLast {
		println 'Hello from myPreceedingTask!'
	}
}

task myTestTask(type: MyTestTask) {
}

myPreceedingTask.finalizedBy myTestTask

Your Environment

Still shouldn't matter.

@rkrisztian rkrisztian changed the title Exceptions in @OutputFiles method can hang Gradle without reporting the exceptions Exceptions in @OutputFiles method can hang Gradle 4.0 without reporting the exceptions Jul 7, 2017
@ghale
Copy link
Member

ghale commented Jul 7, 2017

@rkrisztian Thanks for reporting. This is indeed a bug. That logic is intended to allow finalizer tasks to run when task execution fails, but when we have a failure while walking the task graph, we should abort all tasks. We'll get this fixed.

@ghale ghale self-assigned this Jul 7, 2017
@ghale ghale added the a:bug label Jul 7, 2017
@ghale ghale added this to the 4.1 RC1 milestone Jul 7, 2017
ghale added a commit that referenced this issue Jul 11, 2017
Fixes issue #2407 where an exception thrown while walking a task
graph with a finalizer can cause the build to hang.
@eriwen eriwen modified the milestones: 4.0.2, 4.1 RC1 Jul 11, 2017
jjohannes pushed a commit that referenced this issue Jul 12, 2017
Fixes issue #2407 where an exception thrown while walking a task
graph with a finalizer can cause the build to hang.
ghale added a commit that referenced this issue Jul 12, 2017
Fixes issue #2407 where an exception thrown while walking a task
graph with a finalizer can cause the build to hang.
@eriwen
Copy link
Contributor

eriwen commented Jul 20, 2017

@ghale I'm going to close this as complete and will be delivered in 4.0.2 next week.

@eriwen eriwen closed this as completed Jul 20, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants