【问题标题】:Override Class loader "Parent First"覆盖类加载器“父优先”
【发布时间】:2025-11-27 04:10:02
【问题描述】:

我在 Web 应用程序服务器单节点设置上运行 Java Web 应用程序,其中我使用了一个库,我包含在我的 Web-Inf 中并在我的代码中使用。

问题是我有另一个应用程序将其库添加到 WebSphere 父 lib 文件夹,其中一个库与我正在使用的库相同,但版本较旧,从而产生冲突并干扰我的代码。

不幸的是,服务器类加载器首先配置为父级,我无法改变这一事实。我的问题是,如何让我的应用程序使用我的库,而忽略类加载器使用的库?

【问题讨论】:

  • 你不能。如果您无法将类加载器重新配置为“最后一个父”,那么您需要一个不同的实例,因此 1)父加载器中没有冲突的类,或者 2)您可以配置“最后一个父”来解决冲突。

标签: java jakarta-ee websphere classloader


【解决方案1】:

解决方案是将有冲突的包移动到共享库,将库配置为使用隔离的类加载器,并将该库与您的应用程序或模块相关联。 “隔离类加载器”设置为共享库创建一个单独的父类加载器,因此您可以将该行为仅针对需要它的工件,而不必将其应用于整个应用程序或模块。

https://www.ibm.com/support/knowledgecenter/en/SSAW57_8.5.5/com.ibm.websphere.nd.multiplatform.doc/ae/tcws_sharedlib.html

我专门引用了“为此共享库使用隔离的类加载器”设置。

【讨论】:

    【解决方案2】:

    如果您无法更改应用服务器设置,基本上可以做三件事:

    1. 将您的应用程序依赖项降级到 WebSphere 服务器使用的较低版本并保持同步。这是最好的,因为它最省事。

    2. 在构建过程中将依赖项隐藏到您自己的包中,以防止包冲突。这可以通过Maven Shade Plugin 完成,请参阅Relocating Classes 用法示例。

    3. 编写一个新的自定义类加载器来解决这个问题。

    我会按 1 -> 2 -> 3 的顺序尝试它们。选项 3 是可能的,但它是一个容易出错的噩梦。我宁愿部署到另一台服务器而不是这样做。

    【讨论】:

    • 4.启动另一个 WebSphere 实例。
    • “我宁愿部署到另一台服务器而不是这样做。” - 我也会。OP的问题是有些人说“应用程序服务器已死”的原因之一。将服务器视为应用程序的依赖项通常比经历此类不兼容性带来的所有麻烦更容易。