-
Notifications
You must be signed in to change notification settings - Fork 450
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
Use shading to build the packages #587
base: main
Are you sure you want to change the base?
Conversation
This generates a package with shaded third-party dependencies to avoid conflicts.
I'm not 100% sure I follow; could you please elaborate? |
…and, much more importantly, thank you for the contribution! |
Yup. Rereading now I've not made myself very clear. As pushy exports Netty classes, when shaded, the package of the classes wil have changed, thus breaking source compatibility –albeit in a minor way–. Here's the diff when replacing pushy to the shaded version of pushy:
As a suggestion, if this is a concern, maybe there could be two pushy artifacts, the regular one (like the current) and a shaded one. |
Interesting. Yeah, the other (worse?) case would be that something else has Netty on the classpath, so the
If we're going to publish shaded artifacts, I think that's the way to go. Poking quickly at Maven Central, I can find a number of projects that seem to follow that pattern. It's a brave new world for me, though; are you aware of any best practices in terms of publishing shaded/unshaded artifacts? |
Right now, with the changes in this PR users should be able to decide if they want the shaded version by adding: I'm not sure if other changes would need to be done for the deployment of the release. |
Ohhhhh yeah. Classifiers. Forgot about those ;) Cool. I'll definitely have to do some prodding to get the deployment process right, but I think we're on the right track. Thanks kindly! |
@@ -40,6 +40,7 @@ | |||
<groupId>${project.groupId}</groupId> | |||
<artifactId>pushy</artifactId> | |||
<version>${project.version}</version> | |||
<classifier>shaded</classifier> |
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.
This feels a little odd to me; I don't think we want to make the Dropwizard metrics listener explicitly dependent upon the shaded version of Pushy. The Maven docs aren't quite clear on this point; if we leave out a classifier here, will any classification of com.turo.pushy at the same version fulfill the requirement?
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.
Hmm. You're right, that's a bit strange.
What could be done, for example, is also providing a shaded dropwizard-metrics-listener
that had the shaded pushy
dependency. However I don't even know if that's possible with maven.
What also could be done, which I think would be easier, is marking the pushy
dependency in dropwizard-metrics-listener
as optional, which would force users of the artifact, to also add pushy
as a dependency explicitly (and then they'd be able to use either the shaded or the non-shaded one).
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.
@jchambers From https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html: NOTE: In two of these dependency references, we had to specify the <type/> element. This is because the minimal set of information for matching a dependency reference against a dependencyManagement section is actually {groupId, artifactId, type, classifier}. In many cases, these dependencies will refer to jar artifacts with no classifier. This allows us to shorthand the identity set to {groupId, artifactId}, since the default for the type field is jar, and the default classifier is null.
+1 on this PR. I was just about to start working on this one myself when I found this PR. So thank you for your efforts! |
is it important that netty-tcnative-boringssl-static dependency is not shaded? I'm unclear on how netty searches the classpath at runtime to find this... update: yes, it's important (see below) |
As you guys already noted, with the shaded jar, Pushy exposes netty classes in a different package, thus breaking source compatibility for users. Consequently, imo this PR needs to expand significantly and modify Pushy to completely hide Netty dependencies from clients. Here is a sample error I get when dropping the shaded jar into my project: The good news is that these errors demonstrate that there is no need to worry about the concern that @jchambers express above wrt how these shaded classes are seen by client. Meaning that no, clients can't accidentally use these classes. |
I updated the shade configuration as follows:
The artifactSet exclusion is critical. Netty needs to find the boringssl on the classpath. This modifies the shaded jar build output to the following: Also, pointing out one technical wrinkle with this configuration... the exclusions of NativeLibraryLoader and friends means that the shaded jar includes those classes in their original package. E.g.,
Therefore, there will still be conflicts with the original jar they come from (netty-common-.jar). I can't think of an easy solution to this problem, but perhaps one solution is for users of the shaded jar only to specify the version of netty common they want to use and for the shading config to exclude the this artifact (so the classes will not be in the resulting jar and must be supplied by the user). |
Also, users will need to exclude the dependencies from the shaded jar, as the default POM is published to maven (and used by clients) (and the default POM lists the netty, etc. deps):
Also, users will need to explicitly depend on the boringssl dep:
|
FWIW, I have a project that uses Pushy and Twitter Finagle (which also uses Netty). I am able to compile my project and run everything successfully with the shaded jar (using my versions/changes I put in comments above). Having thought about this a bit more, I think the only way to do this properly is to update Pushy API to completely hide Netty. Then a shaded jar can be used without source modification (and Pushy's dependencies will be completely hidden from users, which is a huge benefit to everyone already using Netty elsewhere). |
I'm coming to the same conclusion, but am worried that the cure is worse than the disease. The two big things that we expose publicly (and deliberately) are:
I guess we can resolve the first problem as things stand now, though I'm not entirely convinced the benefit is worth the cost. To address the "many clients" part of the second problem, I think we'd need to get #540 done so callers would still have a clear mechanism for controlling overall thread usage. In all, I recognize that this is valuable for many users, but I think the costs are high and there are some big tasks to finish before we can seriously consider merging it. I say this not to shut down the effort, but to be clear that it will probably take significant time and effort before we can merge it. Seem legit? Am I missing anything? |
Some new upstream developments on the shading front: |
Now that we've moved to Java 8 in #746, I think we have a reasonable path to getting around this obstacle. We might be able to use |
This is covered in #757. |
This PR adds generation of JARs shading the dependencies. It shades
io.netty
,com.google.code.gson
andorg.apache.commons
intocom.turo.pushy.external
.This PR addresses #498. This is especially useful when used with newer versions of Spring Webflux, which use Netty with their Project Reactor, as it's more likely to produce version conflicts.
This also introduces the drawback of breaking source compatibility when using Netty extensions. For example, in my project, I had to rename the import of Netty's Future.
What are your thoughts?