-
Couldn't load subscription status.
- Fork 543
Relocate ASM and JNR classes in shaded JAR #272
Conversation
|
👍 Imho all dependent classes must be relocated. |
|
On closer inspection, it looks like the published shaded JAR is currently including ASM classes without relocating them, which seems really bad because it means that dependency conflicts between those bundled-but-non-relocated classes and other copies of ASM that exist on the classpath: Similarly, it looks like the shaded JAR contains all of the un-relocated JNR classes, which is going to cause hard-to-debug classpath ordering issues if a library which depends on Unless I've overlooked something, this library's current use of shading doesn't make sense. I think that it would be better to either shade and relocate all dependencies or to relocate all shaded dependencies and use Maven to pull in the un-relocated dependencies. |
|
(I'm using docker-java, but shading issue is the same for both libs) But then you will get issue if you are using 2 different library versions as they may have different versions of shaded artifacts that has the same package names. Now i think that you need shade library with deps yourself in your application (but note that maven-3.3 has bug https://issues.apache.org/jira/browse/MNG-5807 and we had different related discussion in Jenkins) with different prefixes. In this case shading in library pom.xml will be just an example of shading configuration. |
|
If there's agreement that we should relocate every third-party class that is bundled into the |
|
I spent a bunch of time investigating this today and it looks like there's no easy solutions here. With a shaded artifact, my goals would be to a) relocate every third-party class included in the JAR, and b) drop those bundled dependencies from the POM while promoting transitive dependencies. In principle, the createDependencyReducedPom and promoteTransitiveDependencies shade options should handle this by generating a new POM. However, these options only take effect if shadedArtifactAttached is false. Other projects have run into this problem and have come up with a few solutions:
The HBase solution seems to work nicely, but it's a large maintenance burden and would also require a shift to a multi-module Maven build. It's also kind of complex; see https://github.com/apache/hbase/blob/44367f55e8bbd252ae824d1ddb626b5ce91fe75d/hbase-shaded/pom.xml Other people have also run into the limitations of a classifier-based approach: http://maven.40175.n5.nabble.com/shade-plugin-attached-artifact-and-dependency-reduced-pom-td5765599.html Given all of this, one low-effort way to move forward might be the following:
|
|
Also, it would be good to shade Guava: it doesn't have any transitive dependencies and is quite conflict-prone itself. |
|
@stephenc maybe you have some generic opinion for such cases? |
|
It seems like what you really want to be doing is publishing the shaded artifact under a different artifactId rather than as an attached artifact... https://maven.apache.org/plugins/maven-shade-plugin/shade-mojo.html#shadedArtifactId would seem to be what you want, and with that case (as long as you do not try to consume the shaded artifact from the same reactor that is building it) then you should not hit the POM immutablity issue in Maven 3.3.x (though @jvanzyl is of the opinion that a different packaging type for shaded artifacts is the correct solution... which would again drive you to publish the shaded artifact to a different artifactId from the unshaded one) @jvanzyl here is a case in point w.r.t. the shade plugin and modifying the project model |
|
@stephenc right! I forgot this classical trick with package names :) Classifier sounds right but it seems in maven classifier usage is not designed well i.e. using it for branch builds instead of maven version set. IMHO multi-module or other artifactId looks good |
|
A classifier gets the same dependencies as the main artifact... which is not what you want here, rather you want a different artifactId as the dependencies are different |
|
I've updated this to also relocate the JNR classes. While I feel that publishing a shaded artifact using a dependency-reduced POM would make sense, I'm glad to defer that larger build change to a different PR. In the meantime, how does this relocation of these shaded classes look? Is there still interest in getting this relocation merged in? |
pom.xml
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I realized that this is the wrong relocation pattern: while the artifact's organization name is com.github.jnr, the JNR classes are under the jnr.* namespace.
Current coverage is 50.45% (diff: 100%)@@ master #272 diff @@
==========================================
Files 130 83 -47
Lines 4418 3219 -1199
Methods 0 0
Messages 0 0
Branches 651 456 -195
==========================================
- Hits 2061 1624 -437
+ Misses 2161 1445 -716
+ Partials 196 150 -46
|
|
Do people still want this? If not, can I close? |
|
We're no longer blocked on this, so I'll close. I still think this is ultimately worth fixing from a best-practices POV, though, since including other libraries' classes without relocating them to a new namespace can be problematic from a class conflict POV. |
|
I'm experiencing a conflict between cassandra-driver-core which has a couple of dependencies to (Actually, the conflict is missinglink complaining about missing methods depending on whether Edit: Sorry, I meant relocating |
|
Thanks for reporting this. If you could make a PR, we can review it.
--
David Xia
Software Engineer
[email protected]
|
The goal of this patch is to relocate the ASM and JNR classes that are included in the shaded JAR.
This change is motivated by a dependency conflict issue that I ran into while trying to use
docker-clientin Apache Spark's tests. There's a longer writeup at apache/spark#9503 (comment) which describes our dependency conflict issues, but the TL;DR of it is that we are stuck running Jersey 1.9, which depends on ASM 3, and this causes conflicts with the ASM 5 that JNR uses.Specifically:
org.objectweb.asmnamespace.org.objectweb.asmnamespace, producing a binary incompatibility conflict which Maven doesn't detect.Given that the primary motivation for having a shaded artifact seems to be avoiding conflicts with old versions of Jersey, I think that the best solution here is to relocate the ASM and JNR classes in
docker-client's shaded JAR.This change is