Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remote BuildCache calculation is broken due to InstrumentingClasspathFileTransformer generates unstable jars #14057

Closed
AndreasTu opened this issue Aug 7, 2020 · 4 comments

Comments

@AndreasTu
Copy link

AndreasTu commented Aug 7, 2020

The Gradle Remote BuildCache is broken for Tasks types defined by Gradle-Plugins which are not part of the Gradle distribution.
Gradle calculates a BuildCache hash for the task implementation via the classloaders.
The classloader-hash calculation is done on the Transformed Jar files from ClasspathTransformerCache of the folder jars-8.
But the InstrumentingClasspathFileTransformer class does not produce the same Jar file content on different machines.
This leads to different hashes for the task implementation, which leads to a remote BuildCache miss.

One of the causes why InstrumentingClasspathFileTransformer is generating unstable output is:

 // Remove the signature from the manifest, as the classes may have been instrumented
Manifest manifest = new Manifest(new ByteArrayInputStream(entry.getContent()));

This uses the java.util.jar.Manifest API, which internally represents the manifest entries with a HashMap, which is not stable in different processes. This leads to different Manifest.MF files on different machines.

Expected Behavior

A @CacheableTask task from an external plugin shall be remote cacheable.

Current Behavior

The task contributed from a external plugins gets different ClassLoader Hashes, so Gradle generates a different hash for the task implementation class.

Context

Steps to Reproduce

Add an external plugin in the buildSrc/build.gradle which supports Caching.
Execute the task on two machines.
The second machine will not get the Cache entry of the first.

Note: This has to be a non-Gradle Task type, because for the Built-in type gradle uses another "constant" hash value, without tranforming the gradle plugin jar files.

Your Environment

Internal BuildScans are available.
Gradle: 6.5.1
Java: 11.0.5
Windows

@AndreasTu
Copy link
Author

@wolfs can you please have a look at it, because it is BuildCache related.
@adammurdoch can you also have a look at it, you where the last person editing the InstrumentingClasspathFileTransformer

@wolfs
Copy link
Member

wolfs commented Aug 7, 2020

I think this is a duplicate of #13874 and has been fixed in 6.6.

@wolfs
Copy link
Member

wolfs commented Aug 7, 2020

In 6.6 we also normalize manifest, so the manifest generation doesn't need to be reproducible. Though it should be: #13875.

@AndreasTu
Copy link
Author

Thanks for the fast information!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants