解决 sbt 中的 jar 加载冲突

Posted

技术标签:

【中文标题】解决 sbt 中的 jar 加载冲突【英文标题】:troubleshooting jar loading conflicts in sbt 【发布时间】:2016-12-27 01:42:56 【问题描述】:

当两个特定的 sbt 插件一起添加到其构建定义中的项目时,我在 sbt 启动时收到以下错误。这些 sbt 插件之一是 scalikejdbc,另一个是 my own,显然它们在项目的构建定义中相互包含会导致 sbt 启动时出现此错误:

scala.reflect.internal.Types$TypeError: package macros contains object
and package with same name: blackbox

显然,似乎每个插件都带来了不同版本的scala.reflect.macros,从而导致了这个错误。我可以在 sbt 插件的罐子里戳戳,确实其中一个似乎带来了 scala/reflect/macros/blackbox.class

$ jar -tvf scalikejdbc-core_2.10/jars/scalikejdbc-core_2.10-2.4.2.jar | grep black

  0 Sat Jun 11 15:51:10 IDT 2016 scala/reflect/macros/blackbox/    
405 Sat Jun 11 15:51:04 IDT 2016 scala/reflect/macros/blackbox/package$.class    
419 Sat Jun 11 15:51:04 IDT 2016 scala/reflect/macros/blackbox/package.class

——然而,很难肯定地断定在这个早期启动阶段 sbt 加载了什么,以便确定这里涉及到这个包的哪些版本以及哪些依赖项带来了它们。

感谢您就如何进行这项调查提出建议!


为了完整起见——我只在下面包含了 sbt 给出的完整错误——但我真诚地怀疑它添加了任何信息,所以你可能会忽略它。

scala.reflect.internal.Types$TypeError: package macros contains object and package with same name: blackbox
one of them needs to be removed from classpath
    at scala.tools.nsc.symtab.SymbolLoaders.enterPackage(SymbolLoaders.scala:66)
    at scala.tools.nsc.symtab.SymbolLoaders$PackageLoader$$anonfun$doComplete$4.apply(SymbolLoaders.scala:244)
    at scala.tools.nsc.symtab.SymbolLoaders$PackageLoader$$anonfun$doComplete$4.apply(SymbolLoaders.scala:243)
    at scala.collection.Iterator$class.foreach(Iterator.scala:727)
    at scala.collection.AbstractIterator.foreach(Iterator.scala:1157)
    at scala.collection.IterableLike$class.foreach(IterableLike.scala:72)
    at scala.collection.AbstractIterable.foreach(Iterable.scala:54)
    at scala.tools.nsc.symtab.SymbolLoaders$PackageLoader.doComplete(SymbolLoaders.scala:243)
    at scala.tools.nsc.symtab.SymbolLoaders$SymbolLoader.complete(SymbolLoaders.scala:194)
    at scala.reflect.internal.Symbols$Symbol.info(Symbols.scala:1231)
    at scala.reflect.internal.pickling.UnPickler$Scan.scala$reflect$internal$pickling$UnPickler$Scan$$fromName$1(UnPickler.scala:207)
    at scala.reflect.internal.pickling.UnPickler$Scan.readExtSymbol$1(UnPickler.scala:226)
    at scala.reflect.internal.pickling.UnPickler$Scan.readSymbol(UnPickler.scala:250)
    at scala.reflect.internal.pickling.UnPickler$Scan.readSymbolRef(UnPickler.scala:783)
    at scala.reflect.internal.pickling.UnPickler$Scan.readType(UnPickler.scala:335)
    at scala.reflect.internal.pickling.UnPickler$Scan$$anonfun$readTypeRef$1.apply(UnPickler.scala:792)
    at scala.reflect.internal.pickling.UnPickler$Scan$$anonfun$readTypeRef$1.apply(UnPickler.scala:792)
    at scala.reflect.internal.pickling.UnPickler$Scan.at(UnPickler.scala:171)
    at scala.reflect.internal.pickling.UnPickler$Scan.readTypeRef(UnPickler.scala:792)
    at scala.reflect.internal.pickling.UnPickler$Scan.readType(UnPickler.scala:345)
    at scala.reflect.internal.pickling.UnPickler$Scan$$anonfun$readTypeRef$1.apply(UnPickler.scala:792)
    at scala.reflect.internal.pickling.UnPickler$Scan$$anonfun$readTypeRef$1.apply(UnPickler.scala:792)
    at scala.reflect.internal.pickling.UnPickler$Scan.at(UnPickler.scala:171)
    at scala.reflect.internal.pickling.UnPickler$Scan.readTypeRef(UnPickler.scala:792)
    at scala.reflect.internal.pickling.UnPickler$Scan.readAnnotationInfo(UnPickler.scala:466)
    at scala.reflect.internal.pickling.UnPickler$Scan.readSymbolAnnotation(UnPickler.scala:491)
    at scala.reflect.internal.pickling.UnPickler$Scan.run(UnPickler.scala:88)
    at scala.reflect.internal.pickling.UnPickler.unpickle(UnPickler.scala:37)
    at scala.tools.nsc.symtab.classfile.ClassfileParser.scala$tools$nsc$symtab$classfile$ClassfileParser$$parseAttribute$1(ClassfileParser.scala:908)
    at scala.tools.nsc.symtab.classfile.ClassfileParser.parseAttributes(ClassfileParser.scala:1084)
    at scala.tools.nsc.symtab.classfile.ClassfileParser.parseClass(ClassfileParser.scala:580)
    at scala.tools.nsc.symtab.classfile.ClassfileParser.parse(ClassfileParser.scala:88)
    at scala.tools.nsc.symtab.SymbolLoaders$ClassfileLoader.doComplete(SymbolLoaders.scala:261)
    at scala.tools.nsc.symtab.SymbolLoaders$SymbolLoader.complete(SymbolLoaders.scala:194)
    at scala.reflect.internal.Symbols$Symbol.info(Symbols.scala:1231)
    at scala.reflect.internal.SymbolTable.openPackageModule(SymbolTable.scala:244)
    at scala.reflect.internal.SymbolTable.openPackageModule(SymbolTable.scala:300)
    at scala.tools.nsc.symtab.SymbolLoaders$PackageLoader.doComplete(SymbolLoaders.scala:247)
    at scala.tools.nsc.symtab.SymbolLoaders$SymbolLoader.complete(SymbolLoaders.scala:194)
    at scala.tools.nsc.symtab.SymbolLoaders$SymbolLoader.load(SymbolLoaders.scala:210)
    at scala.reflect.internal.Symbols$Symbol.typeParams(Symbols.scala:1489)
    at scala.reflect.internal.Types$class.scala$reflect$internal$Types$$isRawIfWithoutArgs(Types.scala:4394)
    at scala.reflect.internal.Types$$anon$11.apply(Types.scala:4416)
    at scala.reflect.internal.Symbols$TermSymbol.scala$reflect$internal$Symbols$TermSymbol$$cook$1(Symbols.scala:2581)
    at scala.reflect.internal.Symbols$TermSymbol.doCookJavaRawInfo(Symbols.scala:2589)
    at scala.reflect.internal.Symbols$Symbol.cookJavaRawInfo(Symbols.scala:1442)
    at scala.tools.nsc.typechecker.Infer$Inferencer.checkAccessible(Infer.scala:384)
    at scala.tools.nsc.typechecker.Typers$Typer.scala$tools$nsc$typechecker$Typers$Typer$$makeAccessible(Typers.scala:605)
    at scala.tools.nsc.typechecker.Typers$Typer.typedIdent$2(Typers.scala:5201)
    at scala.tools.nsc.typechecker.Typers$Typer.typedIdentOrWildcard$1(Typers.scala:5218)
    at scala.tools.nsc.typechecker.Typers$Typer.typed1(Typers.scala:5561)
    at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:5642)
    at scala.tools.nsc.typechecker.Typers$Typer.typedQualifier(Typers.scala:5727)
    at scala.tools.nsc.typechecker.Typers$Typer.typedQualifier(Typers.scala:5735)
    at scala.tools.nsc.typechecker.Namers$Namer.importSig(Namers.scala:1357)
    at scala.tools.nsc.typechecker.Namers$Namer.getSig$1(Namers.scala:1460)
    at scala.tools.nsc.typechecker.Namers$Namer.typeSig(Namers.scala:1463)
    at scala.tools.nsc.typechecker.Namers$Namer$$anonfun$monoTypeCompleter$1$$anonfun$apply$1.apply$mcV$sp(Namers.scala:728)
    at scala.tools.nsc.typechecker.Namers$Namer$$anonfun$monoTypeCompleter$1$$anonfun$apply$1.apply(Namers.scala:727)
    at scala.tools.nsc.typechecker.Namers$Namer$$anonfun$monoTypeCompleter$1$$anonfun$apply$1.apply(Namers.scala:727)
    at scala.tools.nsc.typechecker.Namers$Namer.scala$tools$nsc$typechecker$Namers$Namer$$logAndValidate(Namers.scala:1496)
    at scala.tools.nsc.typechecker.Namers$Namer$$anonfun$monoTypeCompleter$1.apply(Namers.scala:727)
    at scala.tools.nsc.typechecker.Namers$Namer$$anonfun$monoTypeCompleter$1.apply(Namers.scala:726)
    at scala.tools.nsc.typechecker.Namers$$anon$1.completeImpl(Namers.scala:1611)
    at scala.tools.nsc.typechecker.Namers$LockingTypeCompleter$class.complete(Namers.scala:1619)
    at scala.tools.nsc.typechecker.Namers$$anon$1.complete(Namers.scala:1609)
    at scala.reflect.internal.Symbols$Symbol.info(Symbols.scala:1231)
    at scala.reflect.internal.Symbols$Symbol.initialize(Symbols.scala:1374)
    at scala.tools.nsc.typechecker.Typers$Typer.scala$tools$nsc$typechecker$Typers$Typer$$typedStat$1(Typers.scala:2912)
    at scala.tools.nsc.typechecker.Typers$Typer$$anonfun$61.apply(Typers.scala:3032)
    at scala.tools.nsc.typechecker.Typers$Typer$$anonfun$61.apply(Typers.scala:3032)
    at scala.collection.immutable.List.loop$1(List.scala:170)
    at scala.collection.immutable.List.mapConserve(List.scala:186)
    at scala.tools.nsc.typechecker.Typers$Typer.typedStats(Typers.scala:3032)
    at scala.tools.nsc.typechecker.Typers$Typer.typedPackageDef$1(Typers.scala:5301)
    at scala.tools.nsc.typechecker.Typers$Typer.typed1(Typers.scala:5587)
    at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:5642)
    at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:5704)
    at scala.tools.nsc.typechecker.Analyzer$typerFactory$$anon$3.apply(Analyzer.scala:99)
    at scala.tools.nsc.Global$GlobalPhase.applyPhase(Global.scala:464)
    at scala.tools.nsc.typechecker.Analyzer$typerFactory$$anon$3$$anonfun$run$1.apply(Analyzer.scala:91)
    at scala.tools.nsc.typechecker.Analyzer$typerFactory$$anon$3$$anonfun$run$1.apply(Analyzer.scala:91)
    at scala.collection.Iterator$class.foreach(Iterator.scala:727)
    at scala.collection.AbstractIterator.foreach(Iterator.scala:1157)
    at scala.tools.nsc.typechecker.Analyzer$typerFactory$$anon$3.run(Analyzer.scala:91)
    at sbt.compiler.Eval$$anonfun$compile$1$1.apply$mcV$sp(Eval.scala:177)
    at sbt.compiler.Eval$$anonfun$compile$1$1.apply(Eval.scala:177)
    at sbt.compiler.Eval$$anonfun$compile$1$1.apply(Eval.scala:177)
    at scala.reflect.internal.SymbolTable.atPhase(SymbolTable.scala:207)
    at sbt.compiler.Eval.compile$1(Eval.scala:177)
    at sbt.compiler.Eval.compileAndLoad(Eval.scala:182)
    at sbt.compiler.Eval.evalCommon(Eval.scala:152)
    at sbt.compiler.Eval.evalDefinitions(Eval.scala:122)
    at sbt.EvaluateConfigurations$.evaluateDefinitions(EvaluateConfigurations.scala:271)
    at sbt.EvaluateConfigurations$.evaluateSbtFile(EvaluateConfigurations.scala:109)
    at sbt.Load$.sbt$Load$$loadSettingsFile$1(Load.scala:725)
    at sbt.Load$$anonfun$sbt$Load$$memoLoadSettingsFile$1$1.apply(Load.scala:731)
    at sbt.Load$$anonfun$sbt$Load$$memoLoadSettingsFile$1$1.apply(Load.scala:730)
    at scala.collection.MapLike$class.getOrElse(MapLike.scala:128)
    at scala.collection.AbstractMap.getOrElse(Map.scala:58)
    at sbt.Load$.sbt$Load$$memoLoadSettingsFile$1(Load.scala:730)
    at sbt.Load$$anonfun$loadFiles$1$2.apply(Load.scala:738)
    at sbt.Load$$anonfun$loadFiles$1$2.apply(Load.scala:738)
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
    at scala.collection.mutable.ResizableArray$class.foreach(ResizableArray.scala:59)
    at scala.collection.mutable.ArrayBuffer.foreach(ArrayBuffer.scala:47)
    at scala.collection.TraversableLike$class.map(TraversableLike.scala:244)
    at scala.collection.AbstractTraversable.map(Traversable.scala:105)
    at sbt.Load$.loadFiles$1(Load.scala:738)
    at sbt.Load$.discoverProjects(Load.scala:749)
    at sbt.Load$.discover$1(Load.scala:555)
    at sbt.Load$.loadTransitive(Load.scala:584)
    at sbt.Load$.loadProjects$1(Load.scala:452)
    at sbt.Load$.loadUnit(Load.scala:456)
    at sbt.Load$$anonfun$18$$anonfun$apply$11.apply(Load.scala:291)
    at sbt.Load$$anonfun$18$$anonfun$apply$11.apply(Load.scala:291)
    at sbt.BuildLoader$$anonfun$componentLoader$1$$anonfun$apply$4$$anonfun$apply$5$$anonfun$apply$6.apply(BuildLoader.scala:91)
    at sbt.BuildLoader$$anonfun$componentLoader$1$$anonfun$apply$4$$anonfun$apply$5$$anonfun$apply$6.apply(BuildLoader.scala:90)
    at sbt.BuildLoader.apply(BuildLoader.scala:140)
    at sbt.Load$.loadAll(Load.scala:344)
    at sbt.Load$.loadURI(Load.scala:299)
    at sbt.Load$.load(Load.scala:295)
    at sbt.Load$.load(Load.scala:286)
    at sbt.Load$.apply(Load.scala:140)
    at sbt.Load$.defaultLoad(Load.scala:36)
    at sbt.BuiltinCommands$.liftedTree1$1(Main.scala:492)
    at sbt.BuiltinCommands$.doLoadProject(Main.scala:492)
    at sbt.BuiltinCommands$$anonfun$loadProjectImpl$2.apply(Main.scala:484)
    at sbt.BuiltinCommands$$anonfun$loadProjectImpl$2.apply(Main.scala:484)
    at sbt.Command$$anonfun$applyEffect$1$$anonfun$apply$2.apply(Command.scala:59)
    at sbt.Command$$anonfun$applyEffect$1$$anonfun$apply$2.apply(Command.scala:59)
    at sbt.Command$$anonfun$applyEffect$2$$anonfun$apply$3.apply(Command.scala:61)
    at sbt.Command$$anonfun$applyEffect$2$$anonfun$apply$3.apply(Command.scala:61)
    at sbt.Command$.process(Command.scala:93)
    at sbt.MainLoop$$anonfun$1$$anonfun$apply$1.apply(MainLoop.scala:96)
    at sbt.MainLoop$$anonfun$1$$anonfun$apply$1.apply(MainLoop.scala:96)
    at sbt.State$$anon$1.process(State.scala:184)
    at sbt.MainLoop$$anonfun$1.apply(MainLoop.scala:96)
    at sbt.MainLoop$$anonfun$1.apply(MainLoop.scala:96)
    at sbt.ErrorHandling$.wideConvert(ErrorHandling.scala:17)
    at sbt.MainLoop$.next(MainLoop.scala:96)
    at sbt.MainLoop$.run(MainLoop.scala:89)
    at sbt.MainLoop$$anonfun$runWithNewLog$1.apply(MainLoop.scala:68)
    at sbt.MainLoop$$anonfun$runWithNewLog$1.apply(MainLoop.scala:63)
    at sbt.Using.apply(Using.scala:24)
    at sbt.MainLoop$.runWithNewLog(MainLoop.scala:63)
    at sbt.MainLoop$.runAndClearLast(MainLoop.scala:46)
    at sbt.MainLoop$.runLoggedLoop(MainLoop.scala:30)
    at sbt.MainLoop$.runLogged(MainLoop.scala:22)
    at sbt.StandardMain$.runManaged(Main.scala:54)
    at sbt.xMain.run(Main.scala:29)
    at xsbt.boot.Launch$$anonfun$run$1.apply(Launch.scala:109)
    at xsbt.boot.Launch$.withContextLoader(Launch.scala:128)
    at xsbt.boot.Launch$.run(Launch.scala:109)
    at xsbt.boot.Launch$$anonfun$apply$1.apply(Launch.scala:35)
    at xsbt.boot.Launch$.launch(Launch.scala:117)
    at xsbt.boot.Launch$.apply(Launch.scala:18)
    at xsbt.boot.Boot$.runImpl(Boot.scala:41)
    at xsbt.boot.Boot$.main(Boot.scala:17)
    at xsbt.boot.Boot.main(Boot.scala)
error: error while loading package, class file '/home/user/.sbt/boot/scala-2.10.6/org.scala-sbt/sbt/0.13.11/sbt-0.13.11.jar(sbt/package.class)' is broken
(class java.lang.RuntimeException/error reading Scala signature of package.class: package macros contains object and package with same name: blackbox
one of them needs to be removed from classpath)
sbt.compiler.EvalException: Type error in expression

【问题讨论】:

当使用任何一个碰撞插件单独加载项目时(没有任何错误),然后使用sbt-dependency-graph观察依赖关系,项目依赖于org.scala-lang:scala-reflect:2.11.8在这两种情况下。所以那里没什么好找的...... 您是否尝试将您的插件编译为与 scalikejdbc 完全相同的 scala 版本?我知道当你编译一个插件时,你需要在 SBT 的 Scala 版本上编译它。那是在 2.10.X 范围内,肯定不是 2.11。 是的,我已尽力通过构建文件确认这一点,但是有没有办法通过 jar 本身来验证? 嗯,我不认为有。如果您确实在 build.sbt 中定义了它,那么它应该已将其编译为正确的 scala 版本。您可以在 POM 文件中添加排除规则吗?有什么要说的是提供了依赖项还是只是简单地排除了它?您是否真的发布了您的插件(本地或 maven 存储库)? @marios 要使用我的插件,即 WIP,我sbt publishLocal。我猜一个 jar 不能包含它构建时使用的 Scala 版本,因为 jar 文件规范或类似的东西没有促进这一点。 【参考方案1】:

在此处复制@jrudolph 的评论:

FWIW 向后来遇到插件类路径问题的人提供一些建议。尝试将scalacOptions ++= Seq("-verbose", "-Ylog-classpath") 添加到project/plugins.sbt。这将在 scala 编译器在编译构建时加载类时打印出详细信息。这应该会提示冲突的类来自哪个 jar。

【讨论】:

以上是关于解决 sbt 中的 jar 加载冲突的主要内容,如果未能解决你的问题,请参考以下文章

Android引入多个jar包,冲突问题解决方案

JAR冲突问题的解决以及运行状态下如何查看加载的类

如何解决包冲突问题

maven依赖导致的jar包冲突解决方式

maven依赖导致的jar包冲突解决方式

weblogic下包冲突 导致@Valid失效 不能正确校验表单 分析与解决