We have a situation in which two dependencies have exactly the same class (because one of the dependencies copied it and included in their own source).
This is causing sbt assembly
to fail its deduplication checks.
How can I exclude a class from a particular jar?
You need a mergeStrategy
, which will take one of the files.
mergeStrategy in assembly := {
case PathList("path", "to", "your", "DuplicatedClass.class") => MergeStrategy.first
case x => (mergeStrategy in assembly).value(x)
}
If you want to handle the file depending on the JAR which it came from, I don't think you can with the merge strategies that assembly plugin defines. What you could do you could define your own strategy.
I would invert your condition though. I think the question should be "How can I include a class from a particular JAR?". The reason is that there can be more than two JARs having the same class, and you can only include one in the end.
You can tell from where the file comes by using AssemblyUtils.sourceOfFileForMerge
.
project/IncludeFromJar.scala
import sbtassembly._
import java.io.File
import sbtassembly.Plugin.MergeStrategy
class IncludeFromJar(val jarName: String) extends MergeStrategy {
val name = "includeFromJar"
def apply(args: (File, String, Seq[File])): Either[String, Seq[(File, String)]] = {
val (tmp, path, files) = args
val includedFiles = files.flatMap { f =>
val (source, _, _, isFromJar) = sbtassembly.AssemblyUtils.sourceOfFileForMerge(tmp, f)
if(isFromJar && source.getName == jarName) Some(f -> path) else None
}
Right(includedFiles)
}
}
build.sbt
mergeStrategy in assembly := {
case PathList("path", "to", "your", "DuplicatedClass.class") => new IncludeFromJar("jarname.jar")
case x => (mergeStrategy in assembly).value(x)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With