由于类加载器问题导致ClassCastException

时间:2011-04-26 14:41:07

标签: java osgi classloader

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的指针帮我解决了这个问题。

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

非常感谢你们。

1 个答案:

答案 0 :(得分:4)

如果执行强制转换为A的代码加载了与定义B的捆绑包不同的A(并且在您声明时包含A),则VM中可能有两个不同的A类。一个来自定义B的束,另一个用于执行转换为A的束。

由于A是共享类型,因此您需要确保定义B的捆绑包和捆绑到A的捆绑包都使用相同的类A.它们应该从第3个捆绑包或捆绑包导入包含A的包定义B应该导出包含A的包,以便执行转换为A的包可以导入该包。