Who/what is deleting jars from .gradle/caches/modules-2/files-2.1

I am on Linux and (sometimes) after a reboot some of the jars (dependencies) in .gradle/caches/modules-2/files-2.1 are missing. The folder is not entirely empty. And not only old jars are gone - also new jars.

I always have to run the Gradle build again for projects where jars are missing. This is annoying.

Does anybody have a clue as to what is going on?

If I remember correctly this is a “feature”. I don’t recall when it was introduced, but if one uses different Gradle versions over time, newer versions of Gradle cleanup cached artifacts created by earlier versions of Gradle. The designers of this “feature” seemingly made the (rather impractical) assumption that multiple versions of Gradle are not used on the same machine.

This is annoying. I’m building different projects on my local development machine using different major Gradle versions, just because these projects need to use those different versions. In particular, there are projects that use Gradle 6 and some that use Gradle 7. I often see that artifacts (JARs) are downloaded again from repositories after switching between versions. I really would like to be able to control (disable) this behavior. Alternatively, Gradle should introduce a kind of housekeeping task by which one could run such cleanup tasks on purpose (and only on purpose). Not sure if there is a feature request for this already.

1 Like

So far I only noticed the problem when rebooting my PC. I didn’t notice it because of running different Gradle versions, which I do. Still, I just noticed it after a reboot but maybe its just when I noticed it and not when it happened.

What you are saying though, is that I need to run Gradle for the automatic cleanup to happen, correct? And Gradle shouldn’t be running when I shut down my PC or when I boot it.

Thinking a little bit more about this…Gradle runs as daemon in the background. Sometimes there are possibly even several daemons, each for a different Gradle version. What happens when I shut down my PC and consequently all daemons? Are they doing some last second cleanup?

https://docs.gradle.org/current/userguide/directory_layout.html#dir:gradle_user_home

"From version 4.10 onwards, Gradle automatically cleans its user home directory. The cleanup runs in the background when the Gradle daemon is stopped or shuts down.

Files in shared caches used by the current Gradle version in caches/ (e.g. jars-3 or modules-2) are checked for when they were last accessed.Depending on whether the file can be recreated locally or would have to be downloaded from a remote repository again, it will be deleted after 7 or 30 days of not being accessed, respectively."

I am not 100% sure, but it doesn’t seem to me that 30 days have passed when my “jars” are deleted. It seems to happen much quicker. The question is, what means “accessed”? When for example Eclipse just “reads in” a jar, does this mean it was “accessed” under Linux?

Thanks for the reference to the documentation.

The question is, what means “accessed”? When for example Eclipse just “reads in” a jar, does this mean it was “accessed” under Linux?

Honestly, I don’t know. The documentation page doesn’t give a clue how Gradle tracks access of JARs, nor whether the Gradle Eclipse plugin also causes accesses according to this definition.

If there are any Gradle developers reading this post, could you please shed a light on this.

1 Like

I am not using the Gradle Eclipse plugin. I am writing out an Eclipse project via Gradle ‘Eclipse’ plugin.

I don’t use Gradle inside any IDE. It is a curse and the source of many problems and much wasted time.

Dito…

Dito, sigh …

1 Like

The main issue here is that Buildship does not trigger a refresh automatically when this happens, hence a manual “refresh Gradle project” is needed, otherwise a build path error is shown in the Eclipse project.

I don’t use Gradle inside any IDE. It is a curse and the source of many problems and much wasted time.

Maybe with Eclipse, but well, Eclipse itself is always a source of annoyance. :smiley:
When using Gradle with IntelliJ, it is working lovingly. :wink:

Last accessed means by Gradle afair.
So if you run a Gradle build that touches those files and then work a month only using the IDE without running Gradle again for that project (or any using those jars) and then run a different Gradle build, that run will indeed wipe the files that are unused by Gradle for 30 days.

Using different version of Gradle will not cause files to be delete, this access-tracking is working cross-Gradle-version.

If you really insist on using such a workflow (working over a month without using Gradle) you might consider to not use the files from the Gradle cache in the IDE directly, but configure your project file generation to instead copy those jar files to another location (for example <build dir>/libs/) and use those in the generated project files.

This is not how Buildship (which is Gradle integration for Eclipse made by the Gradle team) is supposed to work. In fact, the issue lies within Buildship, not Eclipse: if I use my IDE with Buildship, this one is supposed to invoke Gradle when needed. Of course, if you don’t change the build script, most probably you won’t need to refresh your Gradle dependencies and hence you won’t need to invoke Gradle itself, however if this is a scenario in which Buildship should detect that an invocation is still needed, it should take care of doing this.

So, this time it’s not Eclipse the source of annoyance :wink:

I will never use any marriage of build system and IDE. If Gradle forces me to - because they drop the Eclipse plugin - I will drop Gradle. Actually I don’t like how much attention Gradle already demands, growing its tentacles into everything. Also the arrogance to use Groovy to design a completely new script which has an impossible learning curve and is an insult to debug. I could rant for hours.

I know it works in IntelliJ and Eclipse MOST of the time. Still. I don’t need additional complexity and mysterious failures the moment I have no time. Just the Cache-Example should be enough. Gradle does something clever in the background - which makes sense for some - but annoys the heck out of me.

Is there an easy command to tell Gradle to store those files somewhere else, where they don’t fall victim to cache cleanup?

Or can I globally deactivate any and all cache cleanup automation?

I actually didn’t mean that detail.
That’s even the same for the IntelliJ integration.
Neither detects that files are missing and that rerunning the Gradle import might fix it.
That would be a candidate for a feature request to Buildship and the IntelliJ integration.
But the OP does not use Buildship, but generates the project files.

I don’t use Buildship. It’s not the cause.

I will never use any marriage of build system and IDE. If Gradle forces me to - because they drop the Eclipse plugin - I will drop Gradle.

Noone said they will drop it.
But well, the IDE plugins are not really developed any further and the proper integrations work much better.
If you don’t want to use them, then don’t, noone said you need to, you just should. :smiley:

Also the arrogance to use Groovy to design a completely new script which has an impossible learning curve and is an insult to debug. I could rant for hours.

Never had a problem debugging the Groovy build scripts when I still used Groovy DSL.
But actually I exclusively use Kotlin DSL by now as it is much better and has much better IDE support.
Actually I don’t know why you call it arrogance to use a well established technology to build a DSL.
But actually if you use Gradle properly / idiomatically, it is not so important which underlying language it is, as build scripts should be declaratively and not contain substantial logic.
But well, if you don’t like how Gradle works, I suggest you actually don’t use it. :slight_smile:

Is there an easy command to tell Gradle to store those files somewhere else, where they don’t fall victim to cache cleanup?

No, as this is an absolute uncommon and non-standard use-case.
Gradle provides the power and flexibility to bend it like you want to use it, but it cannot provide easy-to-use options for each and every use-case very few people tend to use.

You probably need to configure a Sync task that copies the compileClasspath configuration to some directory which should b a 4-liner and probably the same for runtimeClasspath, and then you need to customize the eclipse plugin to use the result of those tasks in the generated project files. Something like that. You can also search for some plugin that does it, maybe someone had the same problem as you and published a plugin for it, but I’m not aware of one.

Or can I globally deactivate any and all cache cleanup automation?

Not that I know of.
But maybe there is some internal property to configure it.
But you probably have to look in the Gradle sources to find it.