Java EE WebApp ServiceLoader 将外部 jar 作为插件加载

标签 java jakarta-ee plugins

我有一个非常简单的 POC 设置,我在 Wildfly 9 上部署 JEE7 Web 应用程序。 通过 jaxRs 资源端点,我可以触发“插件加载器”。

PluginLoader 确实使用目录并扫描目录中的 jar 文件,然后将这些 URL 馈送到 URLClassLoader 中。

之后,我使用 ServiceLoader 从这些 URL 加载简单接口(interface)的实现。

当 ServiceLoader 开始迭代找到的实现时,我收到此错误:

Caused by: java.util.ServiceConfigurationError: com.test.MyIface: Provider com.test.MyImpl not a subtype

结构也很简单: MyIface.jar 是接口(interface)。 MyImpl.jar 是 MyIface 的实现,同时它包含一个 META-INF/services 文件,其中包含 MyIface 的正确命名和内容。 当然,Web 应用程序本身只知道 MyIFace。

在 JavaSE 中,使用简单的主入口点并从那里调用加载器,一切正常。 在 JavaEE 中,服务文件似乎被忽略了......至少这是我从异常中得到的。

我把它放在 src/main/resources/META-INF/services 中 并在 src/main/resource/WEB-INF/classes/META-INF/services 中(正如我在 SPI 和 webapps 的上下文中读到的那样)

最佳答案

为了使其发挥作用,必须遵循以下 2 个步骤:

  1. 实例化一个 ClassLoader(普通的 URLClassLoader 即可),它既知道目标 jar Web 应用程序的类加载器。
    • 显然需要知道目标 jar 才能加载服务实现
    • 它需要将 Web 应用程序的类加载器作为父级,以便所有类加载器共享接口(interface)类;否则,即使自定义类加载器加载了该接口(interface),您也会遇到 ClassCastException,例如 “MyIface 不是 MyIface 的实例”
  2. 指定您使用 ServiceLoader.load(Class, ClassLoader) 方法创建的类加载器

关于Java EE WebApp ServiceLoader 将外部 jar 作为插件加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57221944/

相关文章:

java - Web 应用程序中异步任务的线程池配置

java - 在servlet或任何其他J2EE技术​​中调用Java独立程序

c# - VST插件: using FFT on audio input buffer with arbitrary size,怎么办?

java - 如何使用javacv识别长宽可变的正方形或矩形?

java - Dagger 2 - 注入(inject)非 Android 类

Java用户输入?

internet-explorer - css3pie 是如何工作的?

java - 我的项目中的插页式广告

java - 我可以从哪里获得使用 Java EE 开发的示例 Web 应用程序以便从中学习?

asp.net-mvc - NopCommerce 使用插件在管理区域添加额外或自定义选项卡菜单