plugin-gradle: Build shadow jar and relocate jgit
This builds a shadow jar with all dependencies bundled in the plugin and relocates ~~most dependencies~~ jgit under shadow. This will fix issues where other Gradle plugins uses incompatible versions of the same dependencies.
Fixes #587
I'll do some further testing before this is ready.
This works for me™️
I think that everything that gets embedded should have a prefix, relocationPrefix 'spotless.shadow'.
If JGit is the problematic dep, it could be just these that get embedded
spotless-libspotless-lib-extrajgit
Or include everything except the org.eclipse & equo, and leave the others out?
So I updated this to now:
- Bundle
JGitand it's deps - Bundle
com.diffplug.durian:*and it's deps - Relocate
org.eclipse.jgitintospotless.shadow.org.eclipse.jgit - Include
spotless-libandspotless-lib-extranormal deps, since they include all deps that are problematic to bundle.
The built plugin works and resolves the issues with clashing JGit versions between plugins, but this breaks almost all tests in plugin-gradle with this error:
java.lang.NoClassDefFoundError: com/diffplug/spotless/Jvm
And I couldn't figure out how to resolve that 😞
If we shade a transitive (like JGit), we have to shade all the code which calls into it (spotless-lib-extra) so that lib-extra can updated to look for shadow.jgit.
The problem is that there are some dependencies (like everything related to Eclipse) which use reflection, so those cannot be shaded because it breaks the reflection.
A quick workaround is to shade eclipse/equo stuff, but have them not have prefixes. That will blow up fast, because if the "real" jars are on the classpath from another plugin, we will get truly horrific errors, because it's random which classfiles will end up getting used.
If you can shade spotless-lib-extra and jgit without shading all of the others, we would be in business. One hacky way I can imagine doing something like this:
- shade spotless-lib-extra and all its dependencies
- prefix for
spotless-lib-extraisshadow.spotlessextra - prefix for
jgitisshadow.jgit - no prefix for everything else
- then, in the classfile, remove every class except
shadow.* - then, in the pom, add back the jars we need that got removed by shadow
- I think this is what we need, but for only jgit https://github.com/johnrengelman/shadow/issues/330