【问题标题】:If a jar file is required by multiple web applications?如果多个 Web 应用程序需要一个 jar 文件?
【发布时间】:2016-05-25 06:05:20
【问题描述】:

如果多个 Web 应用程序需要一个 jar 文件,那么您会选择哪个选项?将其保存在服务器类路径中还是为每个 Web 应用程序的 lib 文件夹保留一份 jar 文件的副本?

【问题讨论】:

    标签: java jakarta-ee web-applications


    【解决方案1】:

    如果该库尚未包含在您的应用程序服务器中(例如 Java EE 库),我建议为每个 Web 应用程序准备一份副本,并且不要为此更改服务器类路径。

    我将使管理您的 Web 应用程序及其版本的依赖项变得更容易。

    【讨论】:

      【解决方案2】:

      从技术上讲,这取决于它是哪种 JAR 文件,通常您只有一种选择。

      如果它是基于 Java EE 的“Web 片段”JAR 文件,可通过 /META-INF/web-fragment.xml 文件和/或 /META-INF/faces-config.xml 和/或 /META-INF/*.tld 文件和/或 /META-INF/resources 文件夹来识别包含 web 内容文件 (JSP/CSS/JS/etc),那么它肯定属于 WAR 的/WEB-INF/lib。否则,注释/注册的 Web 片段工件(模块化 servlet、过滤器、侦听器、标签、组件、bean 等)将不会被自动扫描、发现和安装,和/或 Web 片段资源(共享 JSP/Facelets/CSS/JS/图片文件)不能包含在 webapp 中。

      或者,如果它代表 Java EE API 的实现,例如 JSF、JSTL、JAX-RS 等,那么它可以(应该)进入服务器的/lib,但是你必须确保你替换任何现有/较旧的实现,否则您可能会遇到运行时类路径中重复的不同版本库导致的类加载问题(可通过类/方法/字段相关异常识别,例如NoSuchMethodErrorLinkageError 等)。如果您仍然将其包含在 WAR 中,那么您需要确保您指示相关的服务器或 API 使用 WAR 捆绑的实现而不是服务器捆绑的实现。

      否则,它很可能是一个“普通的”基于 Java SE 的库,例如 Apache Commons 和朋友。这样的库可以安全地进入服务器的/lib 并在所有 webapps 之间共享。这至少对于 JDBC 驱动程序和具有service loader 的类似 JAR 是必需的,它在 JVM 启动期间自动将内容加载到内存中,可通过基于 Java SE 的 API 的/META-INF/services 文件夹识别。否则,当此类库放置在 webapp 的 /WEB-INF/lib 中时,热部署期间可能会发生内存泄漏风险,因为它无法发出 Java EE 取消部署的信号,并且在 JVM 尚未关闭时再次盲目地自动加载内容。

      另见:

      【讨论】:

      • 感谢您的简洁解释。
      【解决方案3】:

      如果您的大多数 Web 应用程序都使用相同的库,那么您很可能需要将其保存在服务器类路径中。每个 Web 应用程序都由隔离的(新的)类加载器加载 - 因此在运行时此类加载器将从库中加载和定义类并存储在 perm gen 中。这可能会导致不必要的内存分配。唯一的逃避是在服务器上注册库和(不一定因为类加载器遵循delegation model)不包括这个库的包战争。

      但如果只有少数,请将其保存在 WEB-INF 下的 lib 中。如果依赖应用程序将被取消部署以释放资源 - 库类仍将被加载且无用

      Apache Tomcat 类加载器参考:
      https://tomcat.apache.org/tomcat-8.0-doc/class-loader-howto.html

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-25
        • 2018-04-23
        • 1970-01-01
        • 1970-01-01
        • 2017-12-31
        • 1970-01-01
        相关资源
        最近更新 更多