【问题标题】:Different versions of a library loaded to the same ClassLoader不同版本的库加载到同一个 ClassLoader
【发布时间】:2013-07-28 18:36:28
【问题描述】:

嘿嘿,

假设我们有这样的设置:

应用程序 -> 插件 -> 模块

“插件”和“模块”依赖于“应用程序”。

Application 使用 1.0 版的库。 Module 依赖于相同的库,但版本为 2.0。类是相同的,但在 2.0 中删除了一些方法并添加了一些方法。 Plugin 使用 application 的父 ClassLoader 和 module plugin 的父 ClassLoader。

现在的问题是模块使用 1.0 版本的库,但它依赖于 2.0 -> 例如找不到方法

解决这个问题的正确方法是什么?可行的方法是重新定位 2.0 版,但在运行时可能有一种解决方法。也许可以更改类加载器来解决问题。

最大

【问题讨论】:

  • 你必须修复你的依赖。没有办法解决这个问题。假设您在 Application 中从 1.0 版加载 Class 的一个版本并将其传递给插件中的另一个 Class,然后会发生什么?
  • @BoristheSpider 是的,除了阴影/重定位:P

标签: java class classloader


【解决方案1】:

您的选择是:

  1. 将应用程序升级到 2.0
  2. 将插件降级到 1.0(希望它仍然有效)
  3. 将应用程序“核心”移动到嵌套类加载器中
  4. 更改插件/模块类加载器,使它们不是“父级优先”。请注意,这是一个非常粗略的选项,如果操作不当,可能会搞砸。

选项 3. 看起来像:

Application Base -> plugin -> module (lib 2.0)
                 -> Application Core (lib 1.0)

这实质上使插件和应用程序核心对等,因此不再存在类加载器问题。

【讨论】:

  • 我不太清楚你的 3. 选项是什么意思。据我所知,模块 1.0 和模块 2.0 仍然使用应用程序库的类加载器作为父级。
  • 应用程序基础和核心是什么意思?这不一样吗?
  • @p000ison - 是的,但是由于模块在基类加载器中不可用,它将由子类加载器加载。至于 alpplication 基础和核心,不,我是说您需要将应用程序拆分为两个单独的类加载器。基类加载器具有插件所需的“引导类”和任何“api”类。应用程序核心类加载器具有插件/模块不需要直接使用的所有“实现”类。请注意,这不会影响插件/模块的加载方式,它只是将许多应用程序类移动到单独的类加载器中。
  • 我认为这在我的情况下是不可能的,因为我无法更改应用程序基础/核心以及插件的加载方式。看来搬家是唯一的解决办法
  • 但是如果实现已经依赖于库怎么办?例如,如果库提供了一个接口
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-09-18
  • 2018-10-28
  • 1970-01-01
  • 2010-09-08
  • 1970-01-01
  • 2011-08-13
  • 1970-01-01
相关资源
最近更新 更多