Two libraries bring in different version of the same dependency. How to import them both?
Asked Answered
C

1

11

I have the following situation:

+ DentistApp
   L TreatsLibrary
     L IceCream 1.0
   L CavityCausesLib
     L IceCream 2.0

Now I get a VerifyError because TreatsLibrary is using IceCream.giveToKidAfterDrill() which was removed in version 2.0 because of legal reasons.

How do I import both versions and make sure that each uses its own?

Content answered 10/11, 2017 at 22:25 Comment(6)
This cannot be done by just using one ClassLoader as in one ClassLoader, only one version of the class can exist. You may want to take a look at OSGi if you don't want to implement your own class loading mechanism.Sake
Yes it can be done, I just don't remember how, it had to do with renaming librariesContent
You tagged this with sbt-assembly, which will only help you if you package your libraries using an uber JAR.Anastasiaanastasie
I am using a Uber jarContent
"No they are not used in the project only in dependencies" What does this have to do with what I've answered? Shading happens when you package your uber JAR, and at runtime these classes will have different package namesAnastasiaanastasie
Alright. I now get it that sbt-assembly has the ability to shading the classes. github.com/sbt/sbt-assembly#shadingSake
A
7

This answer assumes you're talking about how to load these libraries from a packaged uber JAR at runtime.

You need to shade your dependencies using sbt-assembly. This can be done as follows:

assemblyShadeRules in assembly ++= Seq(
  ShadeRule.rename("IceCream.**" -> "my_icecream.@1")
    .inLibrary("com.library.treats" % "TreatsLibrary" % "1.0.0")
    .inProject
)

This will shade the IceCream dependency in your com.library.treats and change every package name to begin with my_icecream.

Anastasiaanastasie answered 15/11, 2017 at 12:27 Comment(9)
No they are not used in the project only in dependenciesContent
@Content Not sure what that has to do with my answer. This will shade any dependency, regardless if it's written by you or packaged by a third party.Anastasiaanastasie
What does inproject do?Content
@Content Goes over all your library dependencies in your project. i.e. if it has a reference to com.library.treats.TreatsLibrary it now needs to change it to my_icecream.TreatsLibrary.Anastasiaanastasie
from the README: call .inProject to match your project source so no it would be uselessContent
@Content If you change a librarys namespace, and your code references the old namespace, how will your code compile? Trust me, you need it.Anastasiaanastasie
@YuvalItzchakov but you still have the nonshaded IceCream 2.0 on your classpath, don't you? or else how does CavityCausesLib work?Overwork
@K.M I do, but now they have different artifact ids, so they no longer clash.Anastasiaanastasie
@YuvalItzchakov if the non-shaded one is still on the classpath, does that mean that the .inProject line is not necessary? if my code references the old namespace, the old namespace should still be there. however, i tried a setup similar to this, and it actually doesn't work without .inProject and I don't understand why. shouldn't my IceCream.** refs in my code still hit IceCream 2.0?Overwork

© 2022 - 2024 — McMap. All rights reserved.