Java 尝试跟踪部署到ApacheKaraf的捆绑包中的服务。ServiceTracker#addingService不';我没接到电话
我向ApacheKaraf添加了一个OSGI服务Java 尝试跟踪部署到ApacheKaraf的捆绑包中的服务。ServiceTracker#addingService不';我没接到电话,java,osgi,karaf,blueprint-osgi,Java,Osgi,Karaf,Blueprint Osgi,我向ApacheKaraf添加了一个OSGI服务MyService,大致如下: 创建并注释服务及其实现 公共接口MyService{//…} @OsgiServiceProvider(classes=MyService.class) @独生子女 公共类MyServiceImpl实现MyService{//…} 使用maven build和blueprint-maven-plugin以及maven-bundle-plugin处理命名。OSGi服务的声明及其实现将导致bundle.jar/OSGI
MyService
,大致如下:
公共接口MyService{//…}
@OsgiServiceProvider(classes=MyService.class)
@独生子女
公共类MyServiceImpl实现MyService{//…}
blueprint-maven-plugin
以及maven-bundle-plugin
处理命名。OSGi服务的声明及其实现将导致bundle.jar/OSGI-INF/blueprint/autowire.xml:
捆绑包知道该XML,因为它位于MANIFEST.MF中:
Bundle-Blueprint: OSGI-INF/blueprint/autowire.xml
MyServiceImpl
中实现init()
并使用ServiceTracker
来实现这一点:
@PostConstruct
公共void init(){
BundleContext=FrameworkUtil.getBundle(this.getClass()).getBundleContext();
ServiceTracker tracker=new ServiceTracker(上下文,this.getClass(),null){
@凌驾
公共对象添加服务(ServiceReference){
对象服务obj=super.addingService(参考);
试一试{
Context c=新的InitialContext();
绑定(c,“java:global/com.foo.bar.bundle/MyServiceImpl!com.foo.bar.MyService”,serviceObj);
}
catch(NamingException e){e.printStackTrace();}
返回服务对象;
}
};
tracker.open();
}
私有void绑定(上下文ctx、字符串名称、对象值){/…}
不幸的是,如果进行查找,我会得到一个javax.naming.NotContextException
:
new InitialContext().lookup("java:global/com.foo.bar.bundle/MyServiceImpl!com.foo.bar.MyService");
为了调查,我首先检查了捆绑包是否已启动,服务是否已添加到karaf控制台中:
karaf@root()>bundle:list | grep bundle
155 |活动| 80 | 0.0.1.快照|束
karaf@root()>捆绑包:服务155
捆绑包(155)提供:
----------------------
[com.foo.bar.MyService]
然后我用debug参数重新启动了karaf,并将断点设置为init()
和addedService()
。观察结果显示:init()
被调用,因此应该将ServiceTracker
正确地添加到包中。但是,addingService()
不会被调用
我遗漏了什么?在blueprint.xml中,您发布了带有接口“com.foo.bar.MyService”的服务。因此,您需要在服务跟踪器查找中使用相同的名称 顺便问一下,你为什么要使用ServiceTracker?如果从IML的@PostConstruct发布服务,则只需使用以下方式发布IML:
Context c = new InitialContext();
bind(c, "java:global/com.foo.bar.bundle/MyServiceImpl!com.foo.bar.MyService", this );
出于某种原因,我认为初始化的bean和从bundle获得的服务对象将是两个不同的对象。删除
ServiceTracker
似乎可以解决我的问题,但不能100%确定,因为现在我遇到了另一个异常。为了便于理解,您能否解释一下“服务跟踪器查找”的含义?在这一行中,您将配置ServiceTracker以查找具有特定类名“new ServiceTracker(context,this.getClass(),null)”的服务。您在那里提供的名称必须是发布服务时使用的名称。这个和服务的对象确实不同。Blueprint为服务注册代理。如果您使用JPA或事务等拦截器,则需要此代理。是的,我确实使用事务。可能这就是为什么我会收到一条错误消息“需要积极协调”。我还找到了您解释引发此异常的原因的地方:)因此,我似乎真的需要一个ServiceTracker。感谢您为我节省时间!现在我明白我的错误了。我发布服务而不是它的实现,因此我的ServiceTracker
当然只能成功地等待服务。在这种情况下,您仍然可以避免使用ServiceTracker。只需创建第二个类,并使用注释将blueprint bean注入其中。在第二个类的@PostConstruct中,您可以在jndi中安全地发布注入的bean。