spotless icon indicating copy to clipboard operation
spotless copied to clipboard

plugin-gradle: Build shadow jar and relocate jgit

Open rickard-von-essen opened this issue 1 year ago • 6 comments

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

rickard-von-essen avatar Jan 10 '24 12:01 rickard-von-essen

I'll do some further testing before this is ready.

rickard-von-essen avatar Jan 10 '24 14:01 rickard-von-essen

This works for me™️

rickard-von-essen avatar Jan 11 '24 13:01 rickard-von-essen

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-lib
  • spotless-lib-extra
  • jgit

Or include everything except the org.eclipse & equo, and leave the others out?

nedtwigg avatar Jan 15 '24 00:01 nedtwigg

So I updated this to now:

  • Bundle JGit and it's deps
  • Bundle com.diffplug.durian:* and it's deps
  • Relocate org.eclipse.jgit into spotless.shadow.org.eclipse.jgit
  • Include spotless-lib and spotless-lib-extra normal 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 😞

rickard-von-essen avatar Jan 17 '24 18:01 rickard-von-essen

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-extra is shadow.spotlessextra
  • prefix for jgit is shadow.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

nedtwigg avatar Jan 17 '24 19:01 nedtwigg

  • I think this is what we need, but for only jgit https://github.com/johnrengelman/shadow/issues/330

nedtwigg avatar Feb 13 '24 06:02 nedtwigg