我们为其他内部应用提供了一个客户端jar,以连接到我们应用的REST API。我们的API依赖于一些标准的Jakarta库。将这些JAR文件包含在我们的客户端jar文件中是最佳做法吗?或者你只记录依赖关系,并由客户确保他们在类路径上有这些jar?
答案 0 :(得分:13)
你应该不将任何第三方罐子作为超级罐子捆绑到你自己的罐子里,但最好包括你的分配中所需的所有罐子的副本。 lib目录或者什么。
主要原因是您的客户可能正在使用某种形式的依赖管理系统(maven / ivy等),并且提供实际上不属于您的项目的包和类将使这些方案无效。
有一种替代方法,即使用maven shade plugin之类的东西将依赖项重新定位到您自己的包名称空间中。这当然有一个缺点,你将增加你的库的代码大小,但从好的方面,你可以几乎保证你的依赖项的版本,而不影响你的客户可能使用的任何其他库。
编辑:回应Marcus Leon的评论:
捆绑/重新定位的可能解决方案:
最后,实际上确保你拥有你想要的依赖是非常困难的,因为java是一种后期绑定语言,你可以在你的类路径上覆盖你的依赖项(即使是捆绑的)被某些人覆盖,包括一个不同的版本。
注意:我最近花了一个非常糟糕的一天试图找出我们的某个应用程序未能找到新版本的log4j的原因。原因:有人试图将其捆绑成一个随机完全无关的罐子。
答案 1 :(得分:5)
您应该包括您依赖的任何罐子。如果您允许客户端提供标准jar,您可以依赖它们来提供正确的版本。如果您包含您知道应用程序使用的版本,那么对您而言,这将更加轻松。
答案 2 :(得分:4)
捆绑到一个罐子里的优点很明显:
捆绑的缺点是:
另一种选择是使用单个主jar(您的代码),并将class-path manifest属性设置为吸入其他jar。我个人不喜欢这个,因为很容易错过这些半隐藏的依赖。
最后,如果你只说一两个罐子,我会把它们分开。如果您正在谈论10或15,您可能需要考虑捆绑。
答案 3 :(得分:2)
如果您将应用程序部署为独立应用程序,则应包括这些jar。如果您要为某人构建源代码并提供maven pom文件,那么您不一定需要。
答案 4 :(得分:0)
你对非常具体的库版本依赖关系表达了紧张(我可以理解,考虑到Hibernate在不同模块之间的紧密耦合 - 只有某些版本的Hibernate-annotations与一个hibernate-core一起使用,反过来必须与特定的休眠验证器一起使用。)
如果你知道一个包需要作为一个更大平台的一部分工作(比如,作为一个可能加载自己的jar的框架的插件),你真的需要更强大的多版本类OSGI加载(又名JSR-291): OSGI Technology
使用支持OSGI的框架(如Spring,Eclipse,Jonas或Glassfish),您可以在XML文件中指定特定的版本依赖项,如果依赖于bundle libfoo-1.1.4,则另一个插件依赖于libfoo-2.0a,OSGI依赖管理器将确保每个加载正确的版本。