如何为不可执行的Scala库设置依赖关系?

时间:2016-10-21 20:21:31

标签: scala sbt sbt-assembly

花了几个小时试图弄清楚如何做到这一点。在整个过程中,我看了几个看似很有希望的问题,但它们似乎都不适合我正在做的事情。

我有三个图书馆罐子,我们称之为MSH。图书馆M包含以下内容:

case class MyModel(x: Int, s: String) 

然后库S使用play-json库2.3.8版为M

定义的类提供隐式序列化器
trait MyModelSerializer {
    implicit val myModelFormt = Json.format[MyModel]
}

然后将它们捆绑在一起成为便于导入的对象

package object implicits extends MyModelSerializer extends FooSerizlier // etc

这样,在库H中,当它对各种服务执行HTTP调用时,它只从implicits导入S,然后我调用Json.validate[MyModel]来取回模型我需要从我的网络服务。这一切都很好,但是我正在开发一个正在运行2.4的应用程序,当我将H包含在项目中并尝试使用它时,我遇到了反对:

java.lang.NoSuchMethodError: play.api.data.validation.ValidationError.<init>(Ljava/lang/String;Lscala/collection/Seq;)

我相信这是由play-json版本2.4.6引起的。不幸的是,这些是一个小版本,这意味着尝试只使用旧库,如:

// In build.sbt
 "com.typesafe.play" %% "play-json" % "2.3.8" force()

导致应用程序中的所有代码无法编译,因为我使用的是JsError.toJson之类的东西,这些东西不是play-json 2.3.8的一部分。我可以改变尝试使用该方法的14个左右的地方,但是在我感觉到即使我这样做之后也没有帮助的情况下给出了例外。

在这一点上,我记得在我的maven时代,我可以在构建过程中隐藏依赖关系。所以我开始想,如果我可以在H中使用play-json 2.3.8依赖关系来解决这个问题。因为问题似乎是在Json.*中调用H正在使用play-json 2.4.6中的Json对象。

不幸的是,我唯一可以在网上找到的表明阴影能力的是sbt-assembly。我找到了great answer关于如何为胖罐子做这件事。但我不认为我可以使用sbt-assembly,因为H不可执行,它只是一个库jar。我通过question like my own阅读,但答案是指sbt-assembly,所以它对我没有帮助。

Another question seems somewhat promising但我真的无法理解我将如何使用它/我将放置代码本身的位置。我也查看了sbt manual,但没有任何事情可以解释为我需要的东西。

我不能只将S更改为使用play-json 2.4.6,因为我们在play 2.3应用程序中也使用H所以它需要能够在两者中使用。

现在,如果我无法完成某种着色,我唯一能想到的就是让H不使用S而是需要某种串行器/解串器隐式地然后连接到适当的json(dee)序列化器。所以我在这里询问如何使用不是可执行jar的东西正确地使用sbt进行着色,因为如果我绝对需要,我只想重写。如果我错过了某些东西(例如sbt-assembly也可以为不可执行的罐子加盖阴影),如果你能指出我必须错过的文档,我会把它作为答案。

1 个答案:

答案 0 :(得分:0)

Yuval Itzchakov所示,sbt-assembly不必构建可执行jar,也可以遮蔽库代码。此外,除了需要着色的依赖项之外,还可以进行包装,但是这样可以保持打包的jar的大小,并让其余的依赖项像往常一样通过。

手动搜索传递依赖项是我最终必须要做的事情,但如果有人有办法自动执行此操作,那么这将是对此答案的一个很好的补充。无论如何,这是我需要对compile 'com.squareup.picasso:picasso:2.5.2'库的构建文件做的,以使其正确地着色play-json库。

  1. 在sbt控制台
  2. 中找出使用H的依赖项
  3. 抓住任何相关的游戏(因为我只使用play-json而没有其他我可以假设游戏=需要着色)
  4. 同样遮蔽了show compile:dependencyClasspath模型,因为它们也依赖于S,所以为了避免传递依赖性将非阴影游戏2.3.8重新插入,我必须遮蔽我的序列化器。
  5. 将sbt-assembly添加到项目中,然后更新build.sbt文件
  6. build.sbt

    play-json

    然后,我再也不会因为尝试运行它而获得任何例外。我希望这可以帮助其他有类似问题的人,如果有人有办法自动获取依赖关系并通过它们进行过滤,我会很乐意用它来更新答案。