JBOSS OSGI 7.1上的ClassCastException
我在我的项目中使用了JBossOSGi7.1。 我有两包:JBOSS OSGI 7.1上的ClassCastException,jboss,osgi,Jboss,Osgi,我在我的项目中使用了JBossOSGi7.1。 我有两包: usermanagement (service provider) jerseyBundle (service consumer) 当我部署并启动usermanagementbundle时, 然后部署并启动jersey捆绑包 jerseyBundle getServiceReference() successful. 那么。 我尝试重新部署并重新启动usermanagement。然后刷新所有包 JerseyBundle getSe
usermanagement (service provider)
jerseyBundle (service consumer)
当我部署并启动usermanagement
bundle时,
然后部署并启动jersey捆绑包
jerseyBundle getServiceReference() successful.
那么。
我尝试重新部署并重新启动usermanagement
。然后刷新所有包
JerseyBundle getServiceReference() with Exception: "ClassCastException"
这是我用来获取服务的代码:
public <T> T getService(Class<T> type,List<ServiceReference> _sref) {
try {
ServiceReference sref = bundleContext.getServiceReference(type.getName());
if(sref != null)
{
_sref.add(sref);
}
return type.cast(bundleContext.getService(sref));
} catch (Exception ex) {
ex.printStackTrace();
return null;
}
}
public T getService(类类型,列表){
试一试{
ServiceReference sref=bundleContext.getServiceReference(type.getName());
如果(sref!=null)
{
_补充(sref);
}
返回类型.cast(bundleContext.getService(sref));
}捕获(例外情况除外){
例如printStackTrace();
返回null;
}
}
我使用blueprint注册服务
我试图取消此服务,但它没有解决此问题
public void unGetService(List<ServiceReference> _sref) {
try{
while(_sref != null && _sref.size() >0 )
{
System.err.println("==============" + bundleContext.ungetService(_sref.remove(0)));
}
}catch(Exception ex){
ex.printStackTrace();
}
}
public void unGetService(列表_sref){
试试{
while(_sref!=null&&u sref.size()>0)
{
System.err.println(“===================”+bundleContext.ungetService(_sref.remove(0));
}
}捕获(例外情况除外){
例如printStackTrace();
}
}
是否有任何方法可以重新部署服务提供者捆绑包,而不需要重新部署服务使用者捆绑包?观察到这种行为的原因可能是OSGi按捆绑包缓存服务对象。因此,如果您执行bundleContext.getService(sref),那么OSGI将在内部存储此对象,并始终返回相同的对象,直到您执行ungetService 因此,当您更新还包含接口的服务包并刷新客户端时,您将拥有一个新的接口类。如果现在将旧服务对象强制转换到新接口,则将发生ClassCastException 解决这个问题的一种方法是只在短时间内使用服务对象,然后将其取消设置。像这样:
ServiceReference sref = bundleContext.getServiceReference(type.getName());
myO = type.cast(bundleContext.getService(sref));
doStuff(myO);
bundleContext.ungetService(sref)
当然,这只适用于不频繁的呼叫,因为您有一些开销
另一种方法是使用ServiceTracker并对服务的添加和删除做出反应。例如,您可以将一个服务注入到您的类中,该类执行“doStuff”,并在发生更改时删除/替换该服务。这是很难做到的,但你自己
事实上,这就是为什么会有声明性服务(DS)或blueprint这样的框架。这些可以确保在服务出现和消失时重新注入服务并重新启动组件。
由于您已经在提供者端使用blueprint,您也可以尝试在客户端使用它。blueprint客户端不应该有您观察到的问题
顺便说一句,blueprint和DS处理服务动态的方式非常不同。Blueprint注入一次代理,然后只替换代理中的服务对象,而DS将真正重新启动用户组件。当然,这是首先使用OSGi的原因之一。你需要给我们更多的信息(代码)来帮助你。谢谢Arie van Wijngaarden,我只是更新了我的问题。请告诉我我错过了什么。我使用blueprint为普通捆绑包注入服务(使用标记属性和标记引用)。但万一jersey捆绑包是restful捆绑包。我使用了getServicereference()和ungetService()。但这并不能解决问题。也许我需要更改我的源代码以使用服务跟踪器。谢谢你的回答,它帮助我更多地了解osgi服务。