Included dependencies can conflict with other versions#15
Included dependencies can conflict with other versions#15spmiller wants to merge 2 commits intomarceloverdijk:mastermarceloverdijk/lesscss-java:masterfrom
Conversation
|
Hi. Do you still feel strongly about this? |
|
Hi @cpopov, I think this is still a good idea. If we continue to expose internal dependencies (like commons-io), it's only a matter of time before somebody using this in their project has to deal with a version conflict. |
|
I've seen my share of issues with either approach. With shade (assuming you repackage) it then results in possibly having several different versions of a single class on the classpath (the official one, and one or more shaded versions in different packages), which can result in confusion for users of the library. If you don't repackage, it's even worse; multiple versions of the class in the same package, with the use used depending on classpath ordering. Personally, I think it's best for libraries not to shade, and let the users deal with potential version conflicts in the standard mechanism, which provides visibility and techniques to specify the desired resolution. |
|
The good thing is that I'm not proposing we only distribute the shaded artifact. |
|
@spmiller If we would not shade, the user could also check out the code base, exclude the dependencies (Rhino, commons-logging, commons-io) in the pom and install the jar. What advantage would the user have with the configured shade plugin? For users that do nothing and don't care nothing would change and everyone could user lesscss as usual, right? Note: The pull request conflicts with the current code base but it's clear how to resolve them. The fixes of the integration test config and one test case are easy as they are already contained in the pull request for #42. |
|
Hi @sandroboehme, You're broadly correct. The existing jar has dependencies (like Commons IO) that a user must include into their project for our compiler to work. The The advantage is this: if we depend on version X of a library, and a user depends on version Y, the Other implementations of the same concept are Jar Jar Links and OneJar. |
|
Hi @spmiller, Best, Sandro |
|
The issues I have with distributing both a shaded and non-shaded version of a single library are:
I am supportive of the following options:
If we want to go with a util package, I'm willing to provide an initial implementation. |
|
Hi @sandroboehme, Assume for a moment we use SomeClass.someMethod(), which is provided in SomeLibrary version 1.8. In version 2.0 the developers realise that this is a silly name, and rename it do MeaningfulClass.meaningfulName(). If I am a user of our library and I want to use version 2.0 of SomeLibrary, I can't just exclude v1.8 from the pom file because that would break the Less compiler. This means I'm stuck on v1.8 until the Less compiler is upgraded (and then I have to go to v2.0 whether I like it or not). |
|
Hi @spmiller, thanks for the simple, realistic and logical explaination. I appreciate that! Hi @davidmc24, Best, Sandro |
|
@sandroboehme It depends on the build tool in place. For Gradle, there are several dependency management options available. They include forcing a particular versions of a dependency, dependency resolve rules, excluding a particular transitive dependency from a dependency, and disabling transitive dependencies for a dependency. For Maven, I believe it would normally be to use a dependencyManagement section. @spmiller is right that these techniques can't address a situation this library and another library depend on incompatible versions of one of our transitive dependencies. |
|
Hi @davidmc24 and @spmiller, as I understand, even with the dependencyManagement section the user cannot do much about the incompatible versions. Cheers, Sandro |
|
My understanding is that the proposed shaded jar would be an alternative to the standard lesscss-java jar. It would include both the lesscss-java classes as well as the repackaged dependencies. A user of this library would need to include either lesscss-java or lesscss-java-dep in their classpath, but not both. |
|
Thanks for the explaination @davidmc24. |
|
The scenario that you described, where there is both a For example, let's say that the user is writing a Grails app. They have been using the |
|
Hi, I have followed your discussion about shading. I would second the point I've had a look, commons-lang3 is only used in "test" scope at the minute As the used commons-io code is not very likely to change that much, using a Best, On Thu, Mar 27, 2014 at 2:06 AM, David M. Carr notifications@github.comwrote:
|
|
@damaddin Thanks for commenting. I agree with your reasoning. |
|
Guys, I'm not sure where the confusion could come from (especially if you use an explicit name like @sandroboehme is proposing). Having two artifacts seems to work for JUnit, which I hope is pretty widely used. However, it's difficult to debate this without falling back on your own opinion -- either you think it's confusing or you don't, and I don't imagine anybody will change their opinion from their gut instinct. @damaddin is right when he says a library should have as few dependencies as possible. My solution to this problem was to shade the dependencies as it created the least amount of code to maintain. The alternative of manually inlining these specific methods works until the next time somebody adds another dependency and nobody remembers to tell them otherwise. |
|
Ok, I understand that build tools might detect different versions of the same artifact but not different versions of the same class or package. Why aren't classifiers like ´with-inline-deps`a solution here? After removing the two dependencies and check the compile errors I think it is non trivial to replace them. E.g. to replace the BOMInputStream I guess one would have to specify the charset as a user. The version range is a good way to lessen the problem. |
|
@sandroboehme My understanding is that classifiers are mostly intended to attach additional artifacts to a primary artifact. In particular, I don't think that they are able to have their own POM, which is especially important if your intention is that the "main" artifact has a dependency on |
|
To actually try out shading I merged this pull request to https://github.com/sandroboehme/lesscss-java, resolved the merge conflicts, removed commons logging from this pull request, made a trivial change to the code to be able to move commons.lang to the test classpath, configured the shading to replace to current jar and added slf4j to the shading config. |
|
@sandroboehme Checked out that branch, and tried it out. I don't much care about the POM embedded within the resulting JAR. As far as I know, no build tools use it as part of their dependency management support. If we're going this direction (which is fine by me), I'd like to propose two tweaks:
|
|
Thanks for the two tweaks @davidmc24! |
|
It uses the POM, just not the POM embedded in the JAR. Rather, it uses the standalone POM file that's published in the Maven repository. For example, when I run Note that the .pom file that's installed is from the |
|
Thanks for the information David! I tried it by myself and you are right, for some reason Is everybody else also ok with doing it that way? |
…ncy. It was coming from lesscss-java before marceloverdijk/lesscss-java#15 was fixed.
Including this library in my project introduced some dependencies that I would have preferred not to have. Using the maven shade plugin, we can inline these dependencies into a
-depjar, so the commons-io dependency doesn't leak out into the parent project.I was unable to inline Rhino, as
env.rhino.jshas an explicit dependency on Rhino (line #1339,Packages.org.mozilla.javascript.Context.getCurrentContext()), and the shade plugin doesn't seem to be able to rewrite resource files.Normal users can continue to use the existing artifact, but those who want only one dependency can use the
-departifact.