gpt4 book ai didi

scala - 驱逐 sbt 中的特定传递依赖

转载 作者:行者123 更新时间:2023-12-02 17:58:04 26 4
gpt4 key购买 nike

假设一个小型测试项目(sbt 0.13.8,完整项目为 gist ):

name := "test"

organization := "org.example"

version := "0.1.0-SNAPSHOT"

scalaVersion := "2.11.6"

libraryDependencies ++= Seq (
"com.lowagie" % "itext" % "4.2.1",
"com.github.wookietreiber" %% "scala-chart" % "0.4.2"
)

依赖树如下所示:

dependencyTree
[info] org.example:test_2.11:0.1.0-SNAPSHOT [S]
[info] +-com.github.wookietreiber:scala-chart_2.11:0.4.2 [S]
[info] | +-org.jfree:jfreechart:1.0.17
[info] | | +-org.jfree:jcommon:1.0.21
[info] | | +-xml-apis:xml-apis:1.3.04
[info] | |
[info] | +-org.scala-lang.modules:scala-swing_2.11:1.0.1 [S]
[info] |
[info] +-com.lowagie:itext:4.2.1
[info] +-bouncycastle:bctsp-jdk14:138
[info] | +-org.bouncycastle:bctsp-jdk14:1.38
[info] | +-org.bouncycastle:bcmail-jdk14:1.38
[info] | | +-org.bouncycastle:bcprov-jdk14:1.38
[info] | |
[info] | +-org.bouncycastle:bcprov-jdk14:1.38
[info] |
[info] +-dom4j:dom4j:1.6.1
[info] | +-xml-apis:xml-apis:1.0.b2 (evicted by: 1.3.04)
[info] | +-xml-apis:xml-apis:1.3.04
[info] |
[info] +-jfree:jfreechart:1.0.12
[info] | +-jfree:jcommon:1.0.15
[info] |
[info] +-org.swinglabs:pdf-renderer:1.0.5
[info]
[success] Total time: 0 s, completed Jun 2, 2015 12:16:14 PM

问题是依赖项 jfreechartscala-chartitext 拉入(同样适用于 >jcommon,但我将重点关注 jfreechart)。但是,itext 引入的稍旧版本使用另一个组织名称(jfreeorg.jfree)。

通常,如果它们使用相同的组织,较旧的组织将被驱逐(如 xml-apis 示例中所做的那样),并且只要存在二进制文件,就不会发生冲突兼容性。

现在真正的冲突是依赖项 jfree:jfreechartorg.jfree:jfreechart 都位于类路径上并提供相同的类。编译工作正常,sbt 甚至没有提示。以以下示例应用程序:

package org.example

import scalax.chart.api._

object Main extends App {
val data = for {
i <- 1 to 5
category = i.toString
date = new org.jfree.data.time.Day(i, 2, 1998)
value = i * 2
} yield category -> Map(date -> value)

val chart = XYAreaChart.stacked(data.toTimeTable)

chart.saveAsPDF("/tmp/my-chart.pdf")
}

这编译得很好!我不知道 sbt 如何选择使用哪个依赖项。如果你尝试实际运行它,一切都会崩溃:

sbt @ test $ compile
[info] Updating {file:/home/wookietreiber/projects/scala/jfree-itext-test/}jfree-itext-test...
[info] Resolving jline#jline;2.12.1 ...
[info] Done updating.
[info] Compiling 1 Scala source to /tmp/sbt/test/scala-2.11/classes...
[success] Total time: 1 s, completed Jun 2, 2015 1:18:36 PM
sbt @ test $ run
[info] Running org.example.Main
[error] (run-main-1) java.lang.NoSuchMethodError: org.jfree.data.time.TimeTableXYDataset.add(Lorg/jfree/data/time/TimePeriod;Ljava/lang/Number;Ljava/lang/Comparable;Z)V
java.lang.NoSuchMethodError: org.jfree.data.time.TimeTableXYDataset.add(Lorg/jfree/data/time/TimePeriod;Ljava/lang/Number;Ljava/lang/Comparable;Z)V
at scalax.chart.module.RichChartingCollections$RichCategorizedTuple2s$$anonfun$toTimeTable$1$$anonfun$apply$4.apply(RichChartingCollections.scala:300)
...

为了解决这个问题,我需要从依赖项列表/类路径中专门逐出/删除旧的 jfree:jfreechartjfree:jcommon 版本。这可能吗?如果可能的话,如何实现?

<小时/>

我发现的另一个问题是 sbt-assemble 出现如下错误(对于每个重复文件):

[error] deduplicate: different file contents found in the following:
[error] /home/wookietreiber/.ivy2/cache/jfree/jfreechart/jars/jfreechart-1.0.12.jar:org/jfree/data/KeyedValues2D.class
[error] /home/wookietreiber/.ivy2/cache/org.jfree/jfreechart/jars/jfreechart-1.0.17.jar:org/jfree/data/KeyedValues2D.class

最佳答案

您需要在 *.sbt 或 *.scala 项目定义中定义 mergeStratey in assembly 才能使用 sbt-assemble 命令。下面是一个示例。

mergeStrategy in assembly <<= (mergeStrategy in assembly) { (old) =>
{
case PathList("javax", "servlet", xs @ _*) => MergeStrategy.last
case PathList("javax", "activation", xs @ _*) => MergeStrategy.last
case PathList("org", "apache", xs @ _*) => MergeStrategy.last
case PathList("com", "google", xs @ _*) => MergeStrategy.last
case PathList("com", "esotericsoftware", xs @ _*) => MergeStrategy.last
case PathList("com", "codahale", xs @ _*) => MergeStrategy.last
case PathList("com", "yammer", xs @ _*) => MergeStrategy.last
case "about.html" => MergeStrategy.rename
case "META-INF/ECLIPSEF.RSA" => MergeStrategy.last
case "META-INF/mailcap" => MergeStrategy.last
case "META-INF/mimetypes.default" => MergeStrategy.last
case "plugin.properties" => MergeStrategy.last
case "log4j.properties" => MergeStrategy.last
case x => old(x)
}
}

如果您清楚是什么传递 jar 导致了问题,您可以将其排除在您的库依赖项中。例如,我从对 play 2.3.6 的直接依赖中排除了 httpclient jar,它依赖于更高版本的 httpclient,这不是我想要的。

 "com.typesafe.play" %% "play" % "2.3.6" exclude("org.apache.httpcomponents", "httpclient") 

就您而言,您可以对引入此旧 jar 的直接依赖项执行 exclude("jfree", "jfreechart") 操作。

关于scala - 驱逐 sbt 中的特定传递依赖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30593889/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com