sbt-assembly | NoSuchMethodError at runtime when shading

419 Views Asked by At

I'm trying to use sbt-assembly for shading some dependencies. I've shaded and published a jar for project X as mentioned in the sbt-assembly github readme file. When I'm trying to use that published jar in project Y, I'm getting NoSuchMethodError error at runtime.

Below are my shade rules used for project X

 val shadePackage = "mycompany.spark.v1.shaded"
  Seq(
    ShadeRule.rename("cats.**" -> s"$shadePackage.cats.@1").inAll,
    ShadeRule.rename("com.mycompany.sdk.scala.**" -> s"$shadePackage.sdk.scala.@1").inAll,
    ShadeRule.rename("com.google.protobuf.**" -> s"$shadePackage.com.google.protobuf.@1").inAll,
    ShadeRule.rename("fs2.**" -> s"$shadePackage.fs2.@1").inAll,
    ShadeRule.rename("io.circe.**" -> s"$shadePackage.io.circe.@1").inAll,
    ShadeRule.rename("jawn.**" -> s"$shadePackage.jawn.@1").inAll, <==============
    ShadeRule.rename("shapeless.**" -> s"$shadePackage.shapeless.@1").inAll,
    ShadeRule.rename("sttp.client3.**" -> s"$shadePackage.sttp.client3.@1").inAll,
  )

For jawn, When I use the below shade rule,

ShadeRule.rename("jawn.**" -> s"$shadePackage.jawn.@1").inAll

it gives me the below error at runtime for project Y which includes project X jar as a dependency.

java.lang.NoSuchMethodError: org.typelevel.jawn.Facade.$init$(Lorg/typelevel/jawn/Facade;)V

But when I use the shade rule as below, it works fine.

ShadeRule.rename("org.typelevel.jawn.**" -> s"$shadePackage.org.typelevel.jawn.@1").inAll,

In project Y, I'm using the below dependencies which have transitive dependencies with jawn

val CirceVersion = "0.14.0"
val Http4sVersion = "0.22.2"

"org.http4s" %% "http4s-blaze-client" % Http4sVersion,
"org.http4s" %% "http4s-circe" % Http4sVersion,

"io.circe" %% "circe-generic" % CirceVersion,
"io.circe" %% "circe-derivation" % CirceVersion,
"io.circe" %% "circe-literal" % CirceVersion,
"io.circe" %% "circe-generic-extras" % CirceVersion,

I would appreciate if anyone could explain whats going on here.

1

There are 1 best solutions below

0
tharindu_DG On

I was able to fix it by shading as below

assemblyShadeRules := {
  val shadePackage = "shaded"
  Seq(
    ShadeRule.rename("cats.**" -> s"$shadePackage.cats.@1").inAll,
    ShadeRule.rename("com.google.protobuf.**" -> s"$shadePackage.com.google.protobuf.@1").inAll,
    ShadeRule.rename("fs2.**" -> s"$shadePackage.fs2.@1").inAll,
    ShadeRule.rename("io.circe.**" -> s"$shadePackage.io.circe.@1").inAll,
    ShadeRule.rename("org.typelevel.jawn.**" -> s"$shadePackage.org.typelevel.jawn.@1").inAll,
    ShadeRule.rename("shapeless.**" -> s"$shadePackage.shapeless.@1").inAll,
    ShadeRule.rename("sttp.client3.**" -> s"$shadePackage.sttp.client3.@1").inAll,
  )
},

and making a new project in sbt as,

lazy val fatJar = project.settings(
  commonSettings,
  name := "my-project-fat",
  Compile / packageBin := (library / assembly).value
)

sbt packageBin will create run the assembly phase and create the fat-jar

Details can also be found here.