jib icon indicating copy to clipboard operation
jib copied to clipboard

Support for Gradle Configuration Cache

Open Fabian-K opened this issue 5 years ago • 17 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:

  1. 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

Fabian-K avatar Mar 12 '21 11:03 Fabian-K

Interesting. Thanks for the feedback! Sounds like a new feature in the latest Gradle? For now, I added the "help wanted" label.

chanseokoh avatar Mar 12 '21 15:03 chanseokoh

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

jib-build-cache

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)

ssp avatar Dec 14 '21 11:12 ssp

Any news on this?

egaga avatar Oct 05 '22 06:10 egaga

No, but we'd accept a design proposal and a contribution for the feature.

elefeint avatar Oct 05 '22 13:10 elefeint

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");
         }); }```

wwadge avatar Oct 05 '22 13:10 wwadge

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")
}

rocketraman avatar Dec 07 '22 08:12 rocketraman

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")
}

gavvvr avatar Feb 08 '24 10:02 gavvvr

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

hfhbd avatar Feb 08 '24 10:02 hfhbd