Support for Gradle Configuration Cache
Fabian-K opened this issue · 9 comments
Environment:
- Jib version: 2.8.0
- Build tool: Gradle 6.8.1
- OS: Mac
Description of the issue:
Gradle 6.8 has a new configuration cache feature that helps to improve build performance. Unfortunately, there are some restrictions on what plugins can use and jib is currently not compatible with this. I don´t think that jib, in particular, is bad wrt to build performance, still, I think it would be cool if it supports the configuration cache at some point :)
Steps to reproduce:
gradle --configuration-cache jib
Log output:
- Task `:html5-controller:jib` of type `com.google.cloud.tools.jib.gradle.BuildImageTask`: cannot serialize object of type 'org.gradle.api.internal.project.DefaultProject', a subtype of 'org.gradle.api.Project', as these are not supported with the configuration cache.
See https://docs.gradle.org/6.8.1/userguide/configuration_cache.html#config_cache:requirements:disallowed_types
- Task `:html5-controller:jib` of type `com.google.cloud.tools.jib.gradle.BuildImageTask`: invocation of 'Task.project' at execution time is unsupported.
See https://docs.gradle.org/6.8.1/userguide/configuration_cache.html#config_cache:requirements:use_project_during_execution
Interesting. Thanks for the feedback! Sounds like a new feature in the latest Gradle? For now, I added the "help wanted" label.
Any news about this one? Many Gradle plugins have embraced the configuration cache by now and jib would be a great addition to that as it seems quite essential for today’s container-centric builds.
I tried to dig into this myself but got the impression that the design of the plugin relies on getting hold of the Project
object at various times of the build. Unfortunately my understanding of the jib plugin’s working isn’t sufficient to see an obvious way of fixing that.
Essentially using the configuration cache requires the Project
(and other Gradle objects) not to be accessed at build time but only at configuration time. https://docs.gradle.org/7.3.1/userguide/configuration_cache.html#config_cache:requirements:disallowed_types
The report generated by Gradle 7.3.1 for running jibDockerBuild
, for example, contains these pointers
and throws an Exception at
org.gradle.api.InvalidUserCodeException: Invocation of 'Task.project' by task ':fulfill:reporting:jibDockerBuild' at execution time is unsupported.
at org.gradle.configurationcache.initialization.DefaultConfigurationCacheProblemsListener.onTaskExecutionAccessProblem(ConfigurationCacheProblemsListener.kt:75)
at org.gradle.configurationcache.initialization.DefaultConfigurationCacheProblemsListener.onProjectAccess(ConfigurationCacheProblemsListener.kt:55)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.internal.event.DefaultListenerManager$ListenerDetails.dispatch(DefaultListenerManager.java:464)
at org.gradle.internal.event.DefaultListenerManager$ListenerDetails.dispatch(DefaultListenerManager.java:446)
at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:61)
at org.gradle.internal.event.DefaultListenerManager$EventBroadcast$ListenerDispatch.dispatch(DefaultListenerManager.java:434)
at org.gradle.internal.event.DefaultListenerManager$EventBroadcast.dispatch(DefaultListenerManager.java:221)
at org.gradle.internal.event.DefaultListenerManager$EventBroadcast.dispatch(DefaultListenerManager.java:192)
at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
at jdk.proxy1/jdk.proxy1.$Proxy117.onProjectAccess(Unknown Source)
at org.gradle.api.internal.AbstractTask.notifyProjectAccess(AbstractTask.java:1020)
at org.gradle.api.internal.AbstractTask.getProject(AbstractTask.java:228)
at org.gradle.api.DefaultTask.getProject(DefaultTask.java:59)
at com.google.cloud.tools.jib.gradle.BuildDockerTask.buildDocker(BuildDockerTask.java:110)
Any news on this?
No, but we'd accept a design proposal and a contribution for the feature.
If you're in need of workaround:
['jibDockerBuild', 'jibBuildTar', 'jib'].each { taskName ->
getTasksByName(taskName, true).each(it -> {
it.notCompatibleWithConfigurationCache("Jib is not compatible with configuration cache");
}); }```
Thank you @wwadge , this version seems to work for Kotlin DSL:
// workaround https://github.com/GoogleContainerTools/jib/issues/3132
tasks.filter { it.name in setOf("jibDockerBuild", "jibBuildTar", "jib") }.onEach {
it.notCompatibleWithConfigurationCache("Jib is not compatible with configuration cache")
}
Even more concise and type-safe workaround for now:
import com.google.cloud.tools.jib.gradle.JibTask
// ...
tasks.withType<JibTask>().configureEach { // <-- updated, thanks to @hfhbd
notCompatibleWithConfigurationCache("because https://github.com/GoogleContainerTools/jib/issues/3132")
}
Even more concise and type-safe workaround for now:
import com.google.cloud.tools.jib.gradle.JibTask // ... tasks.withType<JibTask> { notCompatibleWithConfigurationCache("because https://github.com/GoogleContainerTools/jib/issues/3132") }
Better to use task.withType<JibTask>().configureEach {
, without configureEach
you are creating the task during configuration even if you don't need these tasks, see also https://docs.gradle.org/current/userguide/task_configuration_avoidance.html#sec:how_do_i_defer_configuration