GoogleContainerTools / jib

🏗 Build container images for your Java applications.
Apache License 2.0
13.67k stars 1.44k forks source link

Support for Gradle Configuration Cache #3132

Open Fabian-K opened 3 years ago

Fabian-K commented 3 years ago

Environment:

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
chanseokoh commented 3 years ago

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

ssp commented 2 years ago

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)
egaga commented 2 years ago

Any news on this?

elefeint commented 2 years ago

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

wwadge commented 2 years ago

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");
         }); }```
rocketraman commented 1 year ago

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")
}
gavvvr commented 9 months ago

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")
}
hfhbd commented 9 months ago

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

simondemartini commented 2 weeks ago

Since this was last updated, it looks like Gradle announced that they will deprecate disabling of the configuration cache in Gradle 9.

In Gradle 9.0, the Configuration Cache will be the preferred mode of execution, and turning it off will be deprecated.

Is this something this project has plans to support sooner than later?