我有两个asm
依赖项具有完全相同的类名和不同依赖项包含的项目结构。尽管这些库具有相同的项目结构,但它们具有不同的 Maven 坐标。因此,依赖项覆盖将不起作用。
我的一个依赖项(jnr-ffi
)使用了一个org.objectweb.asm.ClassVisitor
类。In "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 。
我尝试过 exclude "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 中的类并在 build.sbt 中排除另一个 jar 的相同类?