【问题标题】:ClassCastException due to Class Loader problemClassCastException 由于类加载器问题
【发布时间】:2011-08-13 02:47:34
【问题描述】:
interface A
class B implements A

我在将 B 转换为 A 时遇到 ClassCastException。A 和 B 在同一个包中。

这可能是因为类加载器。 为什么同一个包的类加载器会发生变化? 我该如何处理这个问题?

附加信息

  • 接口A(即AdminService)和实现类B(即AdminServiceImpl)在同一个包中(fusion-core)
  • 而转换是在不同的包中进行的。 --铸造不是直接发生的。即B b = new B(); A a = (A) b; 没有发生。
  • 通过在 OSGi 服务注册表中解析服务来进行转换。即

    AdminService adminService = getService(AdminService.class.getName(), 100); 
    public T getService(String type, long timeToWait) { 
      ServiceTracker serviceTracker = serviceRegistry.get(type); 
      if (serviceTracker == null) { 
        serviceTracker = this.registerServiceTracker(type); 
      } 
      T service = null; 
      try { 
        service = (T) serviceTracker.waitForService(timeToWait); 
      } catch (InterruptedException e) { 
        logger.error("Error while fetching service", e); 
      } return service; 
    }
    

结语

谢谢 Ivan、Angelo 和 BJ。实际上 BJ 的指针帮助我解决了这个问题。

在尝试执行强制转换的包的清单中,<EXPORT-PACKAGE> 正在导出包含接口和实现的另一个包的包。因此,两个不同的类加载器可能正在加载相同的字节码。 Bundle(执行演员)可能假设包是它自己的一部分并再次加载字节码!!!

非常感谢各位。

【问题讨论】:

  • 尝试转换的捆绑代码位于哪个?与“B”和“A”在同一个包中还是不同的包?
  • 正如 Ivan 所说,我们需要更多信息。你能显示你的包的内容和它的清单吗?
  • 以后,请编辑您的问题,而不是在 cmets 中包含相关详细信息。

标签: java osgi classloader


【解决方案1】:

如果执行转换为 A 的代码加载的 A 与定义 B 的包不同(并且包含您所说的 A),则 VM 中可能有两个不同的 A 类。一个来自定义 B 的包,另一个由执行转换为 A 的包使用。

由于 A 是共享类型,您需要确保定义 B 的包和转换为 A 的包都使用同一个类 A。它们都应该从某个第三个包或包中导入包含 A 的包定义 B 应该导出包含 A 的包,以便执行强制转换为 A 的包可以导入该包。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-23
    • 2011-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-28
    相关资源
    最近更新 更多