Bnd Workspace builds not compatible with Gradle configuration cache
Bnd version: 7.2.0-RC1
Gradle version: 9.2.1
JDK version: 17 (Windows)
My project: applies biz.aQute.bnd.workspace
I tried enabling the configuration cache (hadn't tried it before) and then running a Bndrun task. Unfortunately, something deep in Bnd isn't serializable in the way the configuration cache needs it to be.
Configuration cache state could not be cached: field
lockofaQute.bnd.memoize.CloseableMemoizingSupplierbean found in fieldgenerateofaQute.bnd.build.Project$RefreshDatabean found in fielddataofaQute.bnd.build.Projectbean found in fieldbndProjectofaQute.bnd.gradle.BndPluginbean found in fieldthis$0ofaQute.bnd.gradle.BndPlugin$8bean found in fieldcompilerArgumentProvidersoforg.gradle.api.tasks.compile.CompileOptions_Decoratedbean found in fieldcapturedArgsofjava.lang.invoke.SerializedLambdabean found in fieldspecoforg.gradle.api.internal.tasks.execution.SelfDescribingSpecbean found in task:com.corefiling.magnify:compileJavaof typeorg.gradle.api.tasks.compile.JavaCompile: error writing value of type 'java.util.concurrent.locks.StampedLock' > Unable to make private void java.util.concurrent.locks.StampedLock.readObject(java.io.ObjectInputStream) throws java.io.IOException,java.lang.ClassNotFoundException accessible: module java.base does not "opens java.util.concurrent.locks" to unnamed module @27076647
The HTML report is easier to read.
My instinct is that rather than try to make aQute.bnd.build.Project compatible with Gradle's requirements, it would be better to make it so the Gradle configuration cache code never needs to tangle with aQute.bnd.build.Project.
Configuration Cache Requirements for your Build Logic
Removing the bndProject field from BndPlugin may be enough. A Plugin implementation shouldn't need to have any fields; they're nice for convenience, but they could be refactored away.
BndBuilderPlugin and BndWorkspacePlugin don't appear to have this particular problem.
Thanks. Can you provide a PR? Otherwise, @bjhargrave any thoughts?
I tried, but this approach is not enough on its own.
BndPlugin attaches actions to various tasks, which necessarily reference Bnd objects. Otherwise they can't perform Bnd work using the shared project model.
I'll keep thinking. Recreating the project model for each task is obviously not feasible.
Thanks for your effort @ejjcase
Just to confirm: is this related to BJ's work in https://github.com/bndtools/bnd/pull/6915 and the following PRs?
Just to confirm: is this related to BJ's work in #6915 and the following PRs?
@chrisrueger Not really. #6915 relates to non-workspace builds where Bnd is allowed to reference Gradle properties because most aspects of those builds are configured in Gradle. If the same thing is supported in Bnd workspace builds, I haven't found it yet. At the moment I'm concerned with other reasons why the configuration cache would not work with a Bnd workspace.
Getting there. I have made various things in BndPlugin static and/or accessed only at runtime. BndWorkspacePlugin stashes the Workspace as a property of the Gradle project, so it's easy enough to look it up in there each time and then find the correct Project for our Gradle project.
BndPlugin now seems to be OK, but a couple of properties of the AbstractBndrun task type are now suspect.
Just linking a few things I found, in case they are relevant.
- https://github.com/bndtools/bnd/blob/master/gradle-plugins/README.md#gradle-configuration-cache-support
- https://github.com/bndtools/bnd/issues/4919
- https://github.com/bndtools/bnd/issues/4682#issuecomment-845137504
@ejjcase I am trying to understand:
- Is this a new problem?
- is this only happening with Gradle 9 ? (did this happen in Gradle < 9?
- Is this a problem of bnd gradle plugin or does it depend on the user using the bnd gradle plugin?
- Is the workaround to NOT use the configuration cache?
I don't think there is a way to make Bnd workspace builds (cnf folder) compatible with Gradle configuration cache unless you can make most all Bnd objects serializable.
https://github.com/bndtools/bnd/tree/master/gradle-plugins#gradle-configuration-cache-not-supported
The tasks of the Gradle Plugin for Bnd Workspace Builds use the Bnd Workspace model objects such as Workspace and Project at task execution time to perform Bnd operations. However, Gradle's Configuration Cache support requires that all objects used at task execution time must be serializable and the Bnd Workspace model objects are not serializable. So the Gradle Plugin for Bnd Workspace Builds cannot be used with Gradle's Configuration Cache.
We did the work to make non-Bnd workspace builds (no cnf) compatible.
https://github.com/bndtools/bnd/tree/master/gradle-plugins#gradle-configuration-cache-support
So I think this issue can be closed as won't (can't) fix.
@chrisrueger
- Is this a new problem?
No.
- is this only happening with Gradle 9 ? (did this happen in Gradle < 9?
It would happen with any version of Gradle.
- Is this a problem of bnd gradle plugin or does it depend on the user using the bnd gradle plugin?
It happens because the bnd gradle plugin does some things that the configuration cache doesn’t support. There are additional things a user might do that would break configuration cache compatibility, like adding task properties with non-serializable values, but I don’t think a Bnd workspace user would be likely to do that. I can’t think of anything a user could do in a bnd or bndrun file that would make a project less compatible than usual.
- Is the workaround to NOT use the configuration cache?
Yes. I wasn’t even using it until I thought to try it out the other day.
This is certainly not worth holding up the release for.
Thanks @ejjcase for the update and also thanks @bjhargrave for clarifying.
So I leave it up to you @ejjcase to continue or close it. I assigned it to you right now. If you don't feel continuing on it it's fine too. We can the close it and add the abbayance label on it.
@chrisrueger Thanks. I would like to continue, but I also have a very busy week coming up, so it will have to wait a little while.
Gradle's Configuration Cache support requires that all objects used at task execution time must be serializable
While this is true up to a point, it is not universally true. I still think there's a way round it for Bnd.
This is worth pursuing because the Gradle project's long-term goal is to make the configuration cache mandatory in a future major release.
I would like to continue, but I also have a very busy week coming up, so it will have to wait a little while.
No problem. I think there is no hurry here. Also linking the Gradle Configuration Cache Roadmap and Community Plugin Compatibility Matrix.