URLClassLoader 是否适合 SPI?

Could URLClassLoader be approperiate for SPI?

我正在尝试通过 URLClassLoader 通过服务提供商 API 在运行时加载一个 jar。然而,结果失败了。

以下是我所做的:

  1. 创建一个名为shadow-plugin-api的模块,其中包含将由插件实现的接口com.github.soiff.shadow.api.Plugin
  2. 创建名为 shadow-pluginshadow-plugin-api 实现并打包为 shadow-plugin-0.0.1-SNAPSHOT.jar,实现 class 为 com.github.soiff.shadow.plugin.SpringPlugin
  3. 创建名为 shadow-core 的 spring 启动应用程序并包含 shadow-plugin-api;
  4. 通过 URLClassLoader 动态加载 shadow-plugin-0.0.1-SNAPSHOT.jar 并尝试通过 ServiceLoader 加载我的 com.github.soiff.shadow.plugin.SpringPlugin 但它什么也得不到。

我的 git 存储库是:https://github.com/soiff/soiff-shadow.

我尝试了以下解决方案,但仍然无法正常工作。请给我一些建议,在此先感谢!

  1. 我试过抽象class代替我的SPI接口的接口,当我无法实现我的目标时把它改回接口;
  2. 我已经尝试 PathMatchingResourcePatternResolver 获取资源并将我的 URLClassLoader 作为输入参数传递,但没有成功;
  3. 我试过 ResourceFinder 由 Apache 实现,但它也找不到合适的资源;

我的问题是如何通过 URLClassLoader 从外部 jar 加载资源? SPI 可能是一个可能的解决方案吗?

简单来说,答案是肯定的。

你可能很好奇到底出了什么问题,好问题,答案是 URLClassLoader。但是怎么办? URLClassLoader 足以处理您放入的每个项目。换句话说,您通过参数 urls 放入 URLClassLoader 中的项目可能与此一样多。所以,如果你想让它工作,你需要将你的外部 jar 解压缩到一个指定的目录,并通过输入参数 urls 将提取的所有项目添加到你的 URLClassLoader as:

loader = new URLClassLoader(list.toArray(new URL[0]));

其中 list 包含所有项目。

也许还有其他好的解决方案,但这对我有用。如果有人可以 post 另一个更好的解决方案,我将不胜感激。提前致谢!

顺便说一下,此解决方案基于 Hadoop 项目。感谢Apache Hadoop Work Team.

的优秀项目