Java war包与共享库之间的依赖关系

Java war包与共享库之间的依赖关系,java,deployment,maven,shared-libraries,Java,Deployment,Maven,Shared Libraries,通常,依赖项捆绑在Java.war包中 但是,还可以将依赖项放到共享库中,以便对每个已部署的构件使用相同的依赖项 问题:每种方法的优点和缺点是什么?在什么情况下你会使用它们 最大的要求是直观性/可维护性。我不太在乎内存消耗、磁盘空间使用、bandwith等,因为这些东西都很便宜 无论如何,每种方法都有一些要点: 包括战争内部的依赖关系: “事实”方法(?) 易于维护(需要更少的配置和脚本等) 易于部署到app server 每个模块都可以定义库的特定版本 降低类加载错误的风险 使用共享库:

通常,依赖项捆绑在Java.war包中

但是,还可以将依赖项放到共享库中,以便对每个已部署的构件使用相同的依赖项

问题:每种方法的优点和缺点是什么?在什么情况下你会使用它们

最大的要求是直观性/可维护性。我不太在乎内存消耗、磁盘空间使用、bandwith等,因为这些东西都很便宜

无论如何,每种方法都有一些要点:

包括战争内部的依赖关系:

  • “事实”方法(?)
  • 易于维护(需要更少的配置和脚本等)
  • 易于部署到app server
  • 每个模块都可以定义库的特定版本
  • 降低类加载错误的风险
使用共享库:

  • 减少内存消耗(微不足道?)
  • WAR部署可以访问相同的实例/变量等,因为它们共享类路径?听起来真的很糟糕?(它真的是这样工作的,还是在不同的上下文中运行,只是使用相同的物理文件?)
  • 由于依赖关系必须单独维护/部署,使得分发和部署变得更加困难
  • 包的大小较小(微不足道)
  • 依赖项可以升级,而无需实际重新部署WAR应用程序(真正的好处是什么…)
当然,我们可以利用这两种方法的最佳方面,只需将公共库作为共享库提供,并在WAR中包含版本特性。但是,这会使维护工作量加倍,感觉像是一个禁忌


目前我正在使用Glassfish 3.1.1,但这个问题实际上与应用程序服务器无关。

这取决于您的操作。如果您在服务器上部署应用程序,并且此类服务器的数量非常有限(例如集成、QA、生产),并且您有很多依赖项,那么您可以将这些依赖项放到共享库中

如果您要将war发送给必须在其服务器上部署此war的第三方用户,这是非常烦人的。较差的用户必须在其共享库中安装所有必需的依赖项(以及依赖项的依赖项)


如果您必须在非您的服务器上安装应用程序,或者必须运行多个企业应用程序的服务器上安装应用程序,则不能使用此方法。您必须将所有依赖项打包到war文件中。否则冲突是不可避免的。

鉴于你上面列出的赞成/反对意见,我觉得你已经回答了你的问题。正如您所说,内存/磁盘很容易获得。另一方面,时间不是那么容易得到的。将依赖项放入WEB-INF/lib是经过验证的、简单的,并且可以防止您的应用程序与其他应用程序或系统类加载器进行奇怪的交互。如果它没有损坏…

优点如您所说-每个应用程序都是独立的,即您不需要在所有部署的应用程序中同时升级库。另外,只有当同一个库位于容器和应用程序中时,才会发生类路径冲突-我无法很好地回忆它,并且类加载在不同的容器中可能会有所不同

如果您所说的“战争部署”是指各种应用程序,那么不要期望共享任何东西——这些应用程序是设计隔离的。共享依赖项可以在磁盘上单独升级,但升级的时间和方式取决于容器的类加载器


因此,建议是:使用标准方法,只检查您构建的WAR/JAR是否存在不必要的依赖关系。

感谢您澄清类加载器。听起来像是捆绑战争正在赢得这场战争:)是的,尽管即使使用1台服务器,我也可能坚持将依赖项与战争捆绑在一起。它只是简单得多,没有麻烦…有趣的是,似乎我必须更详细地阅读FAQ。我想我提出了两个严格的问题——考虑到直觉性/可维护性,询问什么是好的,在什么情况下选择哪种方法。我一般不会问哪一个更好——这取决于每个人根据给出的事实自行决定。我甚至给了一个很好的起点来扩展,并得到了建设性的答案。