How to debug "One or more additional actions for task ':<name>' have changed"

Hi,
I’m converting a large project (100+ sub projects) from ant to gradle.
In that process I’m running into the following issue when debugging/building from IntelliJ through gradle.
I’m starting the app in debug mode, and change a class, recompile it with intelliJ (calling gradlew :project:classes) and now the changed class can be hotswap’ed into the running application. However, at some of the :project:classes gradle invocations, I’ll hit a case where a task, which should be up-to-date, will trigger, and gradle reports the following reason:

> Task :server:codegenRest
Caching disabled for task ':server:codegenRest' because:
  Build cache is disabled
Task ':server:codegenRest' is not up-to-date because:
  One or more additional actions for task ':server:codegenRest' have changed.
Starting process 'command 'C:\Program Files\Java\jdk1.8.0_221\bin\java.exe''....

The task generates code, which is compiled by another task, this task fails with

:server:compileCodegenJava (Thread[Execution worker for ':' Thread 13,5,main]) started.

> Task :server:compileCodegenJava FAILED
Caching disabled for task ':server:compileCodegenJava' because:
  Build cache is disabled
Task ':server:compileCodegenJava' is not up-to-date because:
  Input property 'stableSources' file C:\Work\dev\server\src\codegenRest\java\com\some\package\server\integration\rest\Foo.java has changed.
  Input property 'stableSources' file C:\Work\dev\server\src\codegenRest\java\com\some\package\server\integration\rest\Bar.java has changed.
  Input property 'stableSources' file C:\Work\dev\server\src\codegenRest\java\com\some\package\server\integration\rest\FooBar.java has changed.
Created classpath snapshot for incremental compilation in 0.062 secs.
:server:compileCodegenJava(Thread[Execution worker for ':' Thread 13,5,main]) completed. Took 0.955 secs.
Stopped 1 worker daemon(s).
The daemon has finished executing the build.

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':server:compileCodegenJava'.
> Failed to clean up stale outputs

Failed to clean up stale outputs

Probably due to windows file-locking the class files while the application is running. But I don’t think the codegen task should run in the first place, how can I debug what is causing the task to trigger as not-up-to-date (One or more additional actions for task ':server:codegenRest' have changed.)

Br,
Aske

What is the codegenRest task? Is it provided by a plugin or is it a task you have written yourself? Can you share its source and configuration?

Sorry for not answering sooner - I solved the issue and forgot about this post.
But if anyone else experience issues with gradle and intelliJ and debug hotswap stuff, there might be of the following which can be used.
Then running a gradle task from intelliJ in debug mode intelliJ will add debug parameters to ALL JavaExec tasks the target task is dependent on. In my case the :server:codegenRest task is a JavaExec task.
So everytime I started the app I would run my tasks with debug enabled, then I would change a file (not in the :server:codegenRest target, but because the debug arguments for the :server:codegenRest tasks now i different the classpath differs and triggers a new invocation og the :server:codegenRest task. The Failed to clean up stale outputs I experienced was due to file locking in windows.

I made the following change to my codegenRest task to make it not trigger based on debug args to JavaExec (code is Kotlin):


    // HACK to avoid rebuilding codegen when IntelliJ passes in debug in jvmArgs
    // comment this to debug codegen tasks
    override fun getJvmArgs(): MutableList<String> {
        return mutableListOf()
    }

    // HACK to avoid rebuilding codegen when IntelliJ passes in debug as doFirst and doLast
    @Internal
    override fun getActions(): MutableList<Action<in Task>> {
        val rv = super.getActions()
        if (rv.size == 1)
            return mutableListOf( rv[0] )
        return rv
    }

    // HACK to avoid rebuilding codegen when IntelliJ passes in debug as doFirst and doLast
    @Internal
    override fun getTaskActions(): kotlin.collections.MutableList<org.gradle.api.internal.tasks.InputChangesAwareTaskAction> {
        val rv = super.getTaskActions()
        if ( rv.size == 1 )
            return mutableListOf( rv[0] )
        return rv
    }

It could probably also be solved by changing the JavacExec to a Exec task

Br
Aske