I am aware of quiet a couple of questions in the forum/slack and in general about sharing the gradle cache and the new Problems ( gradle > 3). I want to gather, summarize but also narrow the scope of those question.
After i broadly migrated from maven to gradle, i focused on the bits and pieces of development/CI integrations with Gradle.
I found several issues with this setup in general while i was most probably tricked by one issue in particular and maybe digested the wrong thing out of that. Long story short, i learned that there are 2 caches:
a) project cache (class file caches and other): $PROJECT_PWD/.gradle
b) global cache (AFAIR that’s where all the nexus artifacts are gathered) ~/.gradle/cache
A. Project Cache
In usual docker-based java project a) becomes an issue by accident due to the nature of the layout of those projects:
~/project
./src
./build.gradle
./docker-compose.yml
./.gralde <- project cache
To be able to build in the container you need the build.gradle
file and all its configuration, thus you usually you would mount the code-base using ./:/src
into the container (so $PWD i ~/project) and thus accidentally leaking the project cache of the host-system to the container.
This leads to arbitrary issues with --continuous
and much more and should be avoided - but i suspect since that is the very much default project layout for any java project, this will be done a lot.
To mitigate that issue i run all tasks in the container using --project-cache-dir=/tmp/projectcache
so use a non-share folder.
This solves this issues very much finally.
A little side question - is there any way to set project-cache-dir
using any `.properties file or such? Seems to be a cli parameter only ( i think we should do something about that ).
I understand that sharing project cache is not desired and have no further questions here - this was just a finding and a thing i had to learn ( the long /hard way ). AFAICS this particular topic is hardly ever covered when docker-based java development stacks are discussed.
B. Global Cache
First i learned tat sharing the global cache to the container using ~/.gradle/cache:~/.gradle/cache
seems to be a bad idea leading to issues - but i seem i was wrong and my issues were from sharing the project-cache ( which i was not aware about at the time)
Since the global cache includes all the downloaded nexus dependecies, which could become quiet a list very fast, it is very desirable to share this, especially since a lot of common dependencies can be found across microservices.
Since those nexus-artefacts are normalized and well packaged, they are actually very “portable” and should be shareable without any big issues.
This leads to the actual question / suggests / thought:
Question
How would one share the gradle-cache which holds all the dependency artifacts across systems/containers,
Motivation
The motivation is for development and CI.
I) Development: This would massively speed up initial compile time across all microservices in the docker container. not downloading the nexus artefacts for each container over and over again.
II) CI : A even more important case is CI, where integration tests, build times can be cut down by more then 50% sharing the artefact storage and is supported widely by a lot of CIs by defining e.g. ~/.m2
being a persitent storage across all build containers.
The scope of this question should not be, how to share compiled classes, build artifacts or more complex, project specific or very “context aware” assets - but only share the dependecy artefacts which are very portable by nature.
- Can one share
~/.gradle/cache
for this purpose, should we share a folder in a deeper level to avoid sharing build caches? According to this issue it seems to be problematic - but is there any part where just the dependencies are stored? - Is this possible at all? Is Gradle remote cache an alternative ( or the only alternative ) - is this one part of EE only (for this purpose) - i am not sure this would be the right reference - at least according to that EE Gradle uses it for storing build cache ( not dependency cache)
In case, i am perfectly aware on running nexus-proxies and all those things, which could solve some issues for CI running it there - but the transport / IO / time it needs to consume the packages from a nexus is by far optimal - and for developers thats hardly a good option, i do not thing a lot of companies run an nexus-proxy per office to reduce downloads - still IO is a huge factor anyway, not to speak about the devop complexity … compared to just sharing / mounting a local folders ( as we all used to do with `~/.m2 )
Thanks for reading!
UPDATE:
A good read on the different caches can be found here