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

发布于 2024-08-11 00:56:21 字数 149 浏览 4 评论 0原文

我们正在为其他内部应用程序提供客户端 jar,以连接到我们应用程序的 REST API。我们的 API 依赖于一些标准 Jakarta 库。将这些 JAR 文件包含在我们的客户端 jar 文件中是否是最佳实践?或者您只是记录依赖关系,并由客户端来确保他们的类路径上有这些 jar 吗?

We're providing a client jar for other internal apps to connect to our app's REST API. Our API depends on a few standard Jakarta libraries. Is it a best practice to include those JAR files within our client jar file? Or do you just document the dependencies and it's up to the clients to ensure they have those jars on their classpath?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

一页 2024-08-18 00:56:21

您不应该将任何第三方 jar 作为 uber jar 捆绑到您自己的 jar 中,但最好包含您的发行版中所需的所有 jar 的副本,例如在 lib 目录中或任何。

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

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

编辑:回应 Marcus Leon 评论:

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

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

最后,要真正确保您拥有所需的依赖项是非常困难的,因为 java 是一种后期绑定语言,您的依赖项(即使是捆绑的)可能会被某些人覆盖,包括类路径上您之前的不同版本。

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

You should not bundle the any third party jars into your own jar as an uber jar, but it would be good to include a copy of all the jar's that are required in your distribution say in a lib directory or what ever.

The main reason for this is that your clients may be using some form of dependency management system (maven/ivy etc) and providing packages and classes that don't actually belong to your project will invalidate these schemes.

There is one alternative and that is to use something like the maven shade plugin to relocate your dependencies into your own package namespace. This of course has the down side that you will increase the code size of your library but on the up side you can almost guarantee the versions of your dependencies with out effecting any other libraries your clients may be using.

EDIT: in response to Marcus Leon comment:

Possible solutions with out bundling/relocating:

  • Documentation, make sure you document your dependencies and any known conflicts with previous versions - nobody actually reads it
  • Distribute you library via a dependency managed system... like a maven or ivy repo, these allow you to document in a very specific set of bounds (including upper) what your dependencies are - can still be overridden just your clients will know that they are doing it
  • Add OSGi information in the MANIFEST.MF - only useful if your clients actually use OSGi
  • If your dependencies have been built using maven or have version information in there manifest files you could write some sort of checking routine that scans the classpath for these and checks there versions - a bit extreme

In the end it is extremely hard to actually ensure you have the dependencies you want as java is a late bound language it is possible to have your dependencies (even if bundled) overridden by somebody including a different version before yours on the classpath.

Note: I've recently spent a very bad day trying to find out why one of our apps failed to find a new version of log4j. the cause: somebody trying to be helpful had bundled it into a random completely unrelated jar.

疑心病 2024-08-18 00:56:21

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

You should include any jars you depend on. If you allow a client to provide standard jars, you rely on them to supply the correct version. It's a lot more painless for you both if you include the versions that you know your app works with.

孤独陪着我 2024-08-18 00:56:21

捆绑到单个 jar 的优点显然是:

  • 客户端简单

捆绑的缺点是:

  • 无法更新依赖库的版本
  • 隐藏必要的库实际上可能会导致客户端与这些额外的库发生潜在冲突
  • 复杂性构建过程(但在 Ant/Maven 中很容易做到这一点的方法)
  • 一些带有清单的库不能只是 unjared 和 rejared - 您需要实际合并清单信息。 Ant 和 Maven 对此有支持。

另一种选择是使用单个主 jar(您的代码),并将类路径清单属性设置为吸收其他 jar。我个人不喜欢这样,因为很容易错过这些半隐藏的依赖项。

最后,如果你只谈论一两个罐子,我会把它们分开。如果您谈论的是 10 或 15 个,您可能需要考虑捆绑。

The pros of bundling into a single jar are obviously:

  • simplicity for the client

The cons of bundling are:

  • inability to update the versions of the dependent libraries
  • hiding necessary libraries can actually lead to potential conflicts in the client with those extra libraries
  • complexity for you in the build process (but ways to do this pretty easily in Ant/Maven)
  • some libraries with manifests cannot just be unjared and rejared - you need to actually merge the manifest information. There is Ant and Maven support for this though.

Another option is to use a single main jar (your code) with the class-path manifest attribute set to suck in the other jars. Personally I don't like this as it's really easy to miss these semi-hidden dependencies.

In the end, if you're talking just one or two jars, I'd leave them split out. If you're talking 10 or 15, you might want to consider bundling.

静谧幽蓝 2024-08-18 00:56:21

如果您将应用程序部署为独立应用程序,则应该包含这些 jar。如果您正在部署源代码供某人构建并且您提供了 Maven pom 文件,那么您不一定需要这样做。

You should include those jars if you're deploying the app as a standalone application. If you're deploying the source for someone to build and you provide a maven pom file then you don't necessarily need to.

尛丟丟 2024-08-18 00:56:21

你表达了对非常具体的库版本依赖关系的紧张(我可以理解,考虑到 Hibernate 在其不同模块之间的耦合程度如何——只有某些版本的 Hibernate 注释与一个 hibernate 核心一起工作,而 Hibernate 核心又必须与特定的休眠验证器一起使用)。

如果您知道一个包需要作为更大平台的一部分工作(例如,作为可能加载自己的 jar 的框架的插件),那么您确实需要更强大的 OSGI 多版本类加载(又名 JSR -291):
OSGI 技术

使用支持 OSGI 的框架,例如 Spring、Eclipse、Jonas 或 Glassfish,您可以可以在 XML 文件中指定您的特定版本依赖项,如果您依赖于 libfoo-1.1.4 包,而另一个插件依赖于 libfoo-2.0a,OSGI 依赖项管理器将确保每个插件加载正确的版本。

You're expressing nervousness about very specific library version dependencies (and I can understand that, given how tightly coupled, say, Hibernate is between its different modules -- only certain versions of Hibernate-annotations work with one hibernate-core, which in turn must be used with a specific hibernate-validator).

If you know a package needs to work as part of a much larger platform (say, as a plugin to a framework which may be loading its own jars), you really need the more powerful multi-versioned class-loading of OSGI (aka JSR-291):
OSGI Technology

With an OSGI-enabled framework, like Spring, Eclipse, Jonas, or Glassfish, you may specify in an XML file your specific version dependencies, and if you depend upon the bundle libfoo-1.1.4, while another plugin depends upon libfoo-2.0a, the OSGI dependency manager will ensure each loads the correct version.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文