I have this task which works in Gradle 8 but not in Gradle 9:
tasks.register('copyResources') {
def schemaFile = project(':manualWorker').file('src/main/resources/schema.json')
doLast {
copy { // <-- THIS IS SEEMINGLY THE ISSUE
from '../../workers/utils/sharedScripts'
exclude 'dashboard.sh'
into 'build/deploy'
}
copy {
from schemaFile
into 'build/deploy'
}
}
}
The error I’m getting is:
* What went wrong:
Execution failed for task ':manualWorker:copyResources'.
> Invocation of 'copy' references a Gradle script object from a Groovy closure at execution time, which is unsupported with the configuration cache.
Is there an easy way to fix it? I tried some AI and I read some documentation but I’m still not entirely sure how to fix it myself.
You probably enabled configuration cache or created a new build with Gradle 9 which enabled configuration cache by default.
Even with Gradle 8 your snippet will fail with configuration cache enabled due to you calling project.copy { ... } in the execution phase.
Your task should probably more look something like
tasks.register('copyResources', Sync) {
from('../../workers/utils/sharedScripts') {
exclude 'dashboard.sh'
}
from project(':manualWorker').file('src/main/resources/schema.json')
into 'build/deploy'
}
then it can also be properly up-to-date and also eliminate stale files in the target directory.
If you really need the task to always run and not properly track inputs and outputs, it is probably the easiest to create a proper task class into which you inject an instance of FileSystemOperations and use the copy method of that, or use the more hacky
interface FileSystemOperationsProvider {
@Inject
FileSystemOperations getFs()
}
tasks.register('copyResources') {
def schemaFile = file('src/main/resources/schema.json')
def fs = objects.newInstance(FileSystemOperationsProvider).fs
doLast {
fs.copy { // <-- THIS IS SEEMINGLY THE ISSUE
from '../../workers/utils/sharedScripts'
exclude 'dashboard.sh'
into 'build/deploy'
}
fs.copy {
from schemaFile
into 'build/deploy'
}
}
}
You do not “add Sync to a task”. That declares a task of type Sync. It is like Copy, just that it deletes files it did not copy to the destination so does not leave stale files. The point is, that by using a task of type Sync or Copy, you do not need to call project.copy or project.sync in execution phase, which is your problem.