【问题标题】:OSGI classcast exception on felixfelix 上的 OSGI 类广播异常
【发布时间】:2011-02-13 08:57:34
【问题描述】:

我对 osgi 还很陌生,正在尝试一起获得功能性的概念证明。

设置是我的通用 api 是在一个创造性地命名为 common-api.jar 的包中创建的,没有包激活器,但它导出了它的所有接口。对这种情况感兴趣的是 DatabaseService.java。

然后我有一个名为 systemx-database-service 的第二个捆绑包。这实现了数据库服务接口。这工作得很好,因为在实现包的激活器中我测试了与数据库的连接并选择了一些任意值。我还注册了我希望其他捆绑包可用的服务,如下所示:

   context.registerService(DatabaseService.class.getName(), new SystemDatabaseServiceImpl(context), new Properties());

基本思想是,当您查找数据库服务的服务参考时,您将获得 SystemDatabaseService 实现。

当我进行检查服务时,输出如下:

-> inspect s c 69
System Database Service (69) provides services:
----------------------------------------------
objectClass = za.co.xxx.xxx.common.api.DatabaseService
service.id = 39

这会让我相信,如果我在测试包中这样做:

context.getService(context.getServiceReference(DatabaseService.class));

我应该取回 DatabaseService.class 的一个实例,但可惜没有这样的运气。它似乎无法找到该服务。在这里坚持我,我的故事变得陌生。

想着无处可去,但我写了这个怪物:

 for (Bundle bundle : bundles) {
        if (bundle.getSymbolicName().equals("za.co.xxx.xxx.database-service")) {
            ServiceReference[] registeredServices = bundle.getRegisteredServices();
            for (ServiceReference ref : registeredServices) {
                DatabaseService service = (DatabaseService) context.getService(ref);
               // use service here. 
               }
            }
        }
    }

现在我实际上可以看到服务引用,但我得到了这个错误

java.lang.ClassCastException: za.co.xxx.xxx.database.service.impl.SystemDatabaseServiceImpl cannot be cast to za.co.xxx.xx.common.api.DatabaseService

这很疯狂,因为实现清楚地实现了接口!

任何帮助将不胜感激。请记住,我对 osgi 的思维方式非常陌生,所以我的整个方法可能存在缺陷。

哦。如果有人想要清单,我可以发布它们。我正在使用 maven-bnd-plugin 在 felix 上构建和执行。

谢谢

妮可

【问题讨论】:

    标签: java osgi apache-felix


    【解决方案1】:

    测试包必须解析为与 SystemDatabaseServiceImpl 相同的 DatabaseService 接口导入。如果这没有发生,那么 getServiceReference 记录它会返回 null,即使找到了服务。通过手动定位捆绑包并尝试定位服务和转换,您可以说明为什么 getServiceReference 会以这种方式运行:如果它返回任意服务,Java 转换就会失败。

    我建议在 impl 包和测试包中打印 DatabaseService.class.getClassLoader() 以证明它们是否是同一个包。如果不是,那么您需要调整您的 OSGi MANIFEST.MF 元数据以确保它们具有一致的接口类视图。

    例如,DatabaseService 接口是否包含在 test 和 impl 包中?如果是,您需要将该接口移动到 impl 包(和 Export-Package)或第三个接口包和 Export-Package。然后,将其他捆绑包调整为 Import-Package。

    【讨论】:

    • 当涉及多个类加载器并且 OSGi 每个包都有一个类加载器时,获取“A 类不能转换为 A 类”是一个经典的 Java 问题。
    • 现货。当我在类加载器上运行 sysout 时,我得到 [69.0 = 目标服务的类加载器 74.0 = 此类的类加载器]。 common-api 在一个单独的包中。这是否意味着我需要将它从我为实现和测试包创建的 jar 中排除?
    • 谢谢。从一切和 BAM 中排除了通用 api。像魅力一样工作
    猜你喜欢
    • 2014-02-18
    • 2014-05-22
    • 2019-09-07
    • 2018-05-14
    • 2012-07-14
    • 2021-04-12
    • 2012-04-20
    • 2013-02-17
    • 2012-03-23
    相关资源
    最近更新 更多