Как я могу принудительно использовать класс из определенного jar-файла и исключить тот же класс другого jar-файла в build.sbt?
У меня два asm
зависимости, которые имеют одинаковые имена классов и структуры проекта, включенные в разные зависимости. Хотя эти библиотеки имеют одинаковую структуру проекта, они имеют разные координаты Maven. Поэтому переопределение зависимости не будет работать.
Одна из моих зависимостей (jnr-ffi
) использует org.objectweb.asm.ClassVisitor
учебный класс. В "org.objectweb" % "asm" % "3.3.1"
, org.objectweb.asm.ClassVisitor
Интерфейс, и это выдает ошибку. Мне нужно использовать "org.ow2.asm" % "asm" % "5.0.3"
Реализация org.objectweb.asm.ClassVisitor
потому что это фактический класс. Банки обеих реализаций загружаются в ~/.ivy2/cache
, К сожалению, тот, который мне нужен, не используется, учитывая мои стратегии слияния.
Выдается следующая ошибка:
Exception in thread "main" java.lang.IncompatibleClassChangeError: Found interface org.objectweb.asm.ClassVisitor, but class was expected
at jnr.ffi.provider.jffi.AsmLibraryLoader.generateInterfaceImpl(AsmLibraryLoader.java:104)
at jnr.ffi.provider.jffi.AsmLibraryLoader.loadLibrary(AsmLibraryLoader.java:89)
at jnr.ffi.provider.jffi.NativeLibraryLoader.loadLibrary(NativeLibraryLoader.java:43)
at jnr.ffi.LibraryLoader.load(LibraryLoader.java:325)
at jnr.unixsocket.Native.<clinit>(Native.java:80)
at jnr.unixsocket.UnixSocketChannel.<init>(UnixSocketChannel.java:101)
at jnr.unixsocket.UnixSocketChannel.open(UnixSocketChannel.java:65)
я использую sbt
0,13,5 и sbt assembly
0.14.2 .
Я пытался исключить "org.objectweb" % "asm" % "3.3.1"
, Это не сработало:
libraryDependencies ++= Seq(. . .).map(_.exclude("org.objectweb" % "asm" % "3.3.1"))
Я также попытался использовать следующие стратегии слияния
assemblyMergeStrategy in assembly := {
case PathList("asm-3.2.jar") => MergeStrategy.discard
case PathList(ps @ _*) if ps.last endsWith ".asm-3.2.jar" => MergeStrategy.discard
case PathList("asm-5.0.3.jar") => MergeStrategy.first
case PathList(ps @ _*) if ps.last endsWith ".asm-5.0.3.jar" => MergeStrategy.first
case PathList("META-INF", xs @ _*) => MergeStrategy.discard
case x => MergeStrategy.first
}
Я также пытался исключить банку:
assemblyExcludedJars in assembly := {
val cp = (fullClasspath in assembly).value
cp filter {_.data.getName == "asm-3.2.jar"}
}
Я также пытался реализовать собственную стратегию слияния project/IncludeFromJar.scala
из "Как можно исключить дублирующийся класс из сборки sbt?", Но IncludeFromJar.scala
не скомпилируется, и я верю, потому что я использую неправильную версию sbt assembly
для их примера.
case PathList("org", "objectweb", "asm", "ClassVisitor.class") => new IncludeFromJar("asm-5.0.3.jar")
Отсюда вопрос: как я могу принудительно использовать класс из определенного jar-файла и исключить тот же класс другого jar-файла в build.sbt?
0 ответов
Недавно я столкнулся с подобной проблемой. Решение, которое я нашел, заключалось в использовании затенения зависимостей для сборки. Вот настройки, которые я использовал в своемbuild.sbt
файл.
assemblyShadeRules in assembly := Seq(
ShadeRule.rename("org.objectweb.asm.**" -> "asm503.@1").inLibrary(
"org.ow2.asm" % "asm" % "5.0.3"
).inLibrary(
"org.ow2.asm" % "asm-tree" % "5.0.3"
).inLibrary(
"org.ow2.asm" % "asm-analysis" % "5.0.3"
).inLibrary(
"org.ow2.asm" % "asm-commons" % "5.0.3"
).inLibrary(
"org.ow2.asm" % "asm-util" % "5.0.3"
).inLibrary(
"com.github.jnr" % "jnr-ffi" % "2.1.9"
).inProject // For your own code
)
В .inProject
заявление также затеняет ваш собственный импорт (при необходимости).
Я знаю, что тема старая, но это может кому-то помочь.