是否应该在客户端 jar 中提供依赖库?

2022-09-03 01:02:50

我们为其他内部应用提供一个客户端 jar,以连接到应用的 REST API。我们的API依赖于一些标准的雅加达库。将这些 JAR 文件包含在客户端 jar 文件中是否是最佳做法?或者,您只是记录依赖项,并由客户端来确保它们的类路径上有这些jar?


答案 1

不应该将任何第三方jar作为uber jar捆绑到你自己的jar中,但是最好在lib目录或其他任何东西中包含分发中所需的所有jar的副本。

这样做的主要原因是,你的客户端可能正在使用某种形式的依赖管理系统(maven/ivy 等),并且提供实际上不属于你的项目的包和类将使这些方案无效。

有一种选择,那就是使用类似maven shade插件的东西将依赖项重新定位到您自己的包命名空间中。这当然有一个缺点,即您将增加库的代码大小,但从好的方面来说,您几乎可以保证依赖项的版本,而不会影响客户端可能正在使用的任何其他库。

编辑:回应马库斯·莱昂的评论:

无需捆绑/重新定位的可能解决方案:

  • 文档,请确保您记录了您的依赖项以及与以前版本的任何已知冲突 - 没有人真正阅读它
  • 通过依赖关系托管系统分发库...就像 maven 或 ivy repo 一样,这些允许你在一组非常具体的边界(包括上部)记录你的依赖关系是什么 - 仍然可以被覆盖,只是你的客户端会知道他们正在这样做
  • 在清单中添加 OSGi 信息。MF - 仅当客户端实际使用 OSGi 时才有用
  • 如果你的依赖项是使用maven构建的,或者其中有版本信息,你可以编写某种检查例程来扫描这些的类路径并检查那里的版本 - 有点极端

最后,很难真正确保你拥有你想要的依赖关系,因为java是一种后期绑定的语言,有可能让你的依赖关系(即使捆绑)被某人覆盖,包括你的类路径上的不同版本。

注意:我最近花了非常糟糕的一天试图找出为什么我们的一个应用程序无法找到新版本的log4j。原因是:有人试图提供帮助,把它捆绑到一个随机的完全不相关的罐子里。


答案 2

您应该包括您依赖的任何 jar。如果允许客户端提供标准 jar,则依靠它们来提供正确的版本。如果您包含您知道您的应用程序可以使用的版本,这对您俩来说都会更加轻松。


推荐