【问题标题】:JVM: most simple way to alter code of a dependency library?JVM:更改依赖库代码的最简单方法?
【发布时间】:2015-04-22 15:14:43
【问题描述】:

大多数时候,我不喜欢 Javascript,而更喜欢严格的编译语言,例如 Scala、Java、Haskell...

然而,Javascript 的优点之一是能够轻松更改外部依赖项的代码。例如,如果您有一个错误并且您认为它是您的依赖库之一,您可以轻松破解并通过您自己的覆盖交换库方法并检查它是否更好。您甚至可以向 Array 或 String 原型添加方法以及类似的东西...如果他愿意,甚至可以转到 node_modules 并在此处临时更改库代码。

在 JVM 世界中,这对我来说似乎是一个刚开始的繁重过程:

  • 克隆依赖源
  • 破解它
  • 编译它
  • 将其发布到某个本地 maven/ivy 存储库
  • 将固定版本集成到您的项目中

这很痛苦,我只是不想一年多做一次 今天我试图修复我的应用程序中的一个错误,而 lib 没有为我提供足够的信息。我本来希望能够在该库的一行上放置一个记录器,以便更好地了解正在发生的事情,但是我试图用调试器破解但没有成功(无论如何,该错误在我的计算机上无法重现.. .)

难道没有任何简单的替代方法可以快速更改依赖项的代码吗?

我会对 Scala、Java、Clojure 或任何其他 JVM 语言的任何解决方案感兴趣。

我不是在寻找可在生产环境中部署的解决方案,而只是在本地使用并最终可在测试环境中部署的快速解决方案。

编辑:我说的是库作者不打算修改的库内部结构。请假设要更改的类是最终的,不能被库配置替换,也不能以任何方式注入到库中。

【问题讨论】:

  • 您想要的不是直接可能的,因为您提到的语言是通过二进制而不是源提供的。此外,因为它们是静态类型的,所以要求所有传递依赖项在编译时都可用。您可以使用 aspectJ 来接触 JVM 上的二进制文件,但它很难使用。 Clojure 是动态类型的,也许他们有解决二进制分布问题的方法。但它不会是您可以用于其他 JVM 语言的任何东西。总的来说,你(我们)在这里不走运。

标签: java scala maven jar clojure


【解决方案1】:

在 Clojure 中,您可以使用 intern 重新绑定来自其他命名空间的变量。因此,只要您要更改的代码是 Clojure 代码,这就是猴子补丁的一种可能方式。

(intern 'user 'inc dec)
(inc 1)
=> 0

不过,这不是一件容易的事,因为它可能并且会导致其他代码出现问题,而不是预期这种行为。在开发期间使用它可以很方便地临时修复其他库中的边缘情况或错误,但不要在已发布的库或生产代码中使用它。

最好简单地分叉和修复这些库,然后发送拉取请求以将其修复到原始库中。

当您自己编写一个您希望人们需要扩展或重载的库时,请在 Clojure 协议中实现它,其中这些更改可以仅限于扩展/重载命名空间。

【讨论】:

    【解决方案2】:

    我不同意 AspectJ 难以使用,它或其他字节码操作库是您唯一现实的选择。

    加载时编织是解决此问题的明确方法。根据您使用相关类的方式,您甚至可以使用模拟库来获得相同的结果,但是像 AspectJ 这样专门为增强和操作而设计的东西可能是最简单的。

    【讨论】:

      猜你喜欢
      • 2023-01-12
      • 2021-12-03
      • 1970-01-01
      • 2013-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-19
      相关资源
      最近更新 更多