如何在没有ClassCastException的情况下从另一个OSGi包中公开服务

时间:2017-05-26 07:28:01

标签: java osgi apache-karaf apache-servicemix

我已经使用ServiceMix开启和关闭了几年,但仍然没有成功地在我的软件包之间共享服务实现 - 由于使用了代理实现,它总是导致ClassCastException。 / p>

我有两个捆绑包和一个嵌入式jar。

  • 嵌入式jar包含我的服务类实现的接口。
  • 捆绑' A'具有服务类实现并导出impl所在的包。
  • 捆绑' B'导入捆绑包A'公开的包裹。在Bundle' B'以下代码成功获取服务;

        IScenarioService scenarioService = null;
    try
    {
        ServiceReference<?>[] servRefs = context.getServiceReferences(IScenarioService.class.getName(), null);
        if (servRefs == null || servRefs.length == 0)
        {
            LOGGER.error("Found no service references for " + IScenarioService.class.getName());
            return false;
        }
        else
        {
            LOGGER.info("Services: " + servRefs.length);
            boolean assign = servRefs[0].isAssignableTo(context.getBundle(), IScenarioService.class.getName());
            LOGGER.info("Assign: " + assign);
    
            scenarioService = (IScenarioService) context.getService(servRefs[0]);
        }
    }
    catch (InvalidSyntaxException e)
    {
        LOGGER.error(e.getMessage());
        e.printStackTrace();
        return false;
    }
    

我的日志显示找到了1项服务,并且该服务是“可分配的”,但是在scenarioService = (IScenarioService) context.getService(servRefs[0]);行上我得到了

  

java.lang.ClassCastException:Proxy511e3d1b_93b7_4de1_835f_3e5df19040b4无法强制转换为xx.x.xx.IScenarioService

我尝试通过Blueprint注入服务,访问上面的代码,更改pom的maven-bundle-plugin中的导入/导出关系以及将所有接口存储在其中捆绑&#39; A&#39;并出口相关的包......一切都无济于事。

有人可以提供一个让我摆脱痛苦的答案吗? 感谢。

1 个答案:

答案 0 :(得分:1)

我认为问题在于提供服务的bundle和使用该服务的bundle看到了类IScenarioService的不同实例。这通常是通过在两个包中嵌入接口或者有两个提供接口的包来实现的。

避免这种情况的最简单方法是将接口包放在导出包的第三个包中,并在服务提供者和服务使用者包中导入包。

使用默认设置时,maven bundle插件会自动执行此操作。

作为示例,请参阅this tutorial。模型包包含服务接口,持久性包包含服务提供者,ui包包含服务使用者。

正如您在代码中看到的那样,maven bundle插件只在父级中设置,并且几乎不需要在各个包中添加额外的OSGi。

因此,如果您正确地执行此操作,那么提供和使用服务非常简单。