【问题标题】:SBT scala monkey patch librarySBT scala猴子补丁库
【发布时间】:2018-01-08 19:31:15
【问题描述】:

我想用具有更多参数的自定义类替换库中的案例类。

我不想从库中排除任何内容。我正在做的是在我的项目中创建一个具有相同包名的类,但它在运行时引发错误。

例子:

  • 图书馆:mamilo.rosa.jar:/com/mamilo/rosa/CaseClassA.scala
  • 我的项目:src/scala/com/mamilo/rosa/CaseClassA.scala

我想要做的是从库中删除该类或将其替换为我的类,但它仍然会引发运行时错误:

java.lang.NoSuchMethodError: com.mamilo.rosa.CaseClassA.<init>(Lscala/collection/Seq;...)

编辑

我正在尝试向这个案例类添加一个新参数:https://github.com/sksamuel/elastic4s/blob/master/elastic4s-core/src/main/scala/com/sksamuel/elastic4s/searches/SearchDefinition.scala

这将被使用并转换为 HTTP 请求(我也会尝试覆盖)。我想做的是在他的库上添加一些更改,当它变得很好时,我可以提交带有一些更改的 PR,但我正在我的项目上执行此操作,该项目包含该库作为依赖项。

【问题讨论】:

  • 你能提供更多的上下文吗?当一个项目有两个(二进制)不兼容的依赖项时,我看到了类似的错误,例如同一个库的两个不同版本。
  • 完成,我添加更多上下文(我认为)

标签: java scala sbt monkeypatching


【解决方案1】:

这里有两个选择:

1) 添加implicit class 转换,例如RichSearchDefinition,当隐式转换在范围内时,这将允许您使用自己的方法。这被称为“丰富我的图书馆”(或有时是“皮条客我的图书馆”)模式。代码大致如下所示:

object Implicits {
  implicit class RichSearchDefiniton(sd: SearchDefinition) {
    // Define methods here that you'd like to use on `SearchDefinition`
    def printSomething: Unit = println("This is an example of enriching a library.")
  }
}

无论您在哪里需要此功能,都可以简单地导入隐式转换:import mypackage.Implicits._

2) 在本地对库进行更改,将版本号更改为0.0.1-LOCAL,然后使用sbt publishLocal 发布它的本地副本。在您的项目中,您可以依赖这个本地发布的库。当您对它的工作感到满意时,您可以提交包含更改的拉取请求。这里需要注意的是,如果 elastic4s 通过另一个依赖项传递包含,您必须在您的 build.sbt 文件中 exclude

【讨论】:

    【解决方案2】:

    您可以定义从它们的类型到您的类型的隐式转换,反之亦然,如下所示:

    // All of their existing stuff
    case class TheirType(a: Int, b: String)
    def theirFunction(x: TheirType) = Unit
    
    // Your new case class
    case class YourType(a: Int, b: String, c: Boolean)
    def yourFunction(yourType: YourType) = Unit
    
    // Define the implicit functions to convert from one type to another (and back)
    implicit def theirsToYours(t: TheirType): YourType = YourType(t.a, t.b, true /* You will need to supply some value here */)
    implicit def yoursToTheirs(y: YourType): TheirType = TheirType(y.a, y.b)
    
    // You can now pass your type to their functions and vice-versa
    val y = YourType(10, "abc", false)
    theirFunction(y)
    
    val t = TheirType(99, "123")
    yourFunction(t)
    

    这里的缺点是您需要为新参数确定一些默认值,因为它们现有的函数无法自行创建该值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-09-01
      • 2012-09-16
      • 2012-12-18
      • 2020-01-09
      • 1970-01-01
      • 1970-01-01
      • 2010-09-29
      • 2021-04-04
      相关资源
      最近更新 更多