简体   繁体   English

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

[英]How to expose a service from one OSGi bundle in another without ClassCastException

I have been using ServiceMix on and off for a couple of years now and still haven't managed to share a service implementation between my bundles successfully - it always results in a ClassCastException due to a proxy implementation being used. 我已经使用ServiceMix了两年了,但仍然没有成功在我的捆绑软件之间成功共享服务实现-由于使用了代理实现,因此总是会导致ClassCastException。

I have two bundles and an embedded jar. 我有两个捆绑包和一个嵌入式jar。

  • The embedded jar contains the interface(s) that my service class implements. 嵌入式jar包含我的服务类实现的接口。
  • Bundle 'A' has the service class implementation and exports the package that the impl lives within. 包“ A”具有服务类实现,并导出impl所在的包。
  • Bundle 'B' imports the package exposed by bundle 'A'. 束“ B”导入束“ A”暴露的包装。 Within Bundle 'B' the following code successfully gets the service; 在“ 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; } 

My log shows that 1 service is found and that the service 'isAssignable', but on line scenarioService = (IScenarioService) context.getService(servRefs[0]); 我的日志显示找到了1个服务,并且该服务为“ isAssignable”,但是在线上的scenarioService = (IScenarioService) context.getService(servRefs[0]); i get 我得到

java.lang.ClassCastException: Proxy511e3d1b_93b7_4de1_835f_3e5df19040b4 cannot be cast to xx.x.xx.IScenarioService java.lang.ClassCastException:Proxy511e3d1b_93b7_4de1_835f_3e5df19040b4无法转换为xx.x.xx.IScenarioService

I've tried to inject the service via Blueprint, accessing in code as above, changing the import/ export relationships in the pom's maven-bundle-plugin as well as having all of the interfaces stored within Bundle 'A' and exporting the relevant package.... All to no avail. 我试图通过Blueprint注入服务,按上述方式访问代码,更改pom的maven-bundle-plugin中的导入/导出关系,以及将所有接口存储在Bundle'A'中并导出相关包....全部无济于事。

Could someone please provide an answer to put me out of my misery? 有人可以提供答案让我摆脱困境吗? Thanks. 谢谢。

I assume that the problem is that the bundle providing the service and the bundle using the service see different instances of the class IScenarioService. 我假设问题是提供服务的捆绑包和使用该服务的捆绑包看到类IScenarioService的不同实例。 This typically is caused by embedding the interface in both bundles or having two bundles that provide the interface. 这通常是由于将接口嵌入两个包中或具有两个提供接口的包引起的。

The easiest way to avoid this is to put the interface package in a third bundle that exports the package and import the package in both service provider and service consumer bundle. 避免这种情况的最简单方法是将接口程序包放在导出程序包的第三个包中,然后将其导入服务提供者包和服务使用者包中。

The maven bundle plugin will do this automatically when you use defaults. 当您使用默认值时,maven软件包插件将自动执行此操作。

As an example see this tutorial . 作为示例,请参见本教程 The model bundle contains the service interface, the persistence bundle contains the service provider and the ui bundle contains the service consumer. 模型捆绑包包含服务接口,持久性捆绑包包含服务提供者,而ui捆绑包包含服务使用者。

As you can see in the code the maven bundle plugin is only set up in the parent and needs virtually no additinal OSGi setup in the individual bundles. 正如您在代码中看到的那样,maven捆绑软件插件仅在父代中设置,几乎不需要在单个捆绑软件中进行其他OSGi设置。

So as you see providing and using a service is very simple if you do it correctly. 因此,您可以看到,如果正确执行服务,则提供和使用服务非常简单。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM