我有一个Bundle P(rovider =实现了Bundle I中定义的接口)(接口)Bundle U(ser)应该使用这个服务。启动应用程序后一切正常,我的所有服务都可以使用。但是当我更新了Bundle P,非服务可以解析。
更新方法如下所示:
this._bundle.stop();
this._bundle.update(new FileInputStream(updateFile));
this._bundle.start();
这是我的所有Package的BundleActivator,它们也应该处理ServiceRegistrations和ServiceReferences:
public abstract class BundleActivator implements org.osgi.framework.BundleActivator, BundleListener, ServiceListener
{
/**
* Bundle Context.
*/
protected BundleContext context;
/**
* Services which are registered by this bundle.
*/
protected HashSet<ServiceRegistration> serviceRegistrations = new HashSet<ServiceRegistration>();
/**
* Service references used by this bundle.
*/
protected HashMap<String, ServiceReference> serviceReferences = new HashMap<String, ServiceReference>();
/**
* Perform this method after Bundle has started.
*
* @param bc BundleContext.
*/
protected abstract void afterStart(BundleContext bc);
/**
* Perform this method before Bundle is going to be stoped.
*
* @param bc BundleContext.
*/
protected abstract void beforeStop(BundleContext bc);
/**
* Perform this method after Bundle has changed.
*
* @param be BundleEvent
*/
protected abstract void afterBundleChanged(BundleEvent be);
/**
* Returns the bundle context for this bundle.
*
* @return bundle context
*/
public BundleContext getContext() {
return this.context;
}
/**
* Registeres a service.
*
* @param clazz interface
* @param service service
* @param properties properties
*
* @return service registration
*/
public ServiceRegistration registerService(Class clazz, Object service, Dictionary<String, ?> properties) {
return this.registerService(clazz.getCanonicalName(), service, properties);
}
/**
* Registeres a service.
*
* @param clazz interface
* @param service service
* @param properties properties
*
* @return service registration
*/
public ServiceRegistration registerService(String clazz, Object service, Dictionary<String, ?> properties) {
ServiceRegistration retval = this.context.registerService(clazz, service, properties);
System.out.println("registered service: " + retval.toString() + " for " + clazz);
this.serviceRegistrations.add(retval);
return retval;
}
/**
* Returns a registered service.
*
* @param clazz interface
*
* @return service instance
*/
public Object getService(Class clazz) {
if (clazz == null) {
return null;
}
return this.getService(clazz.getCanonicalName());
}
/**
* Returns a registered service.
*
* @param clazz interface
*
* @return service instance
*/
public Object getService(String clazz) {
if (clazz == null) {
return null;
}
System.out.println("Class: " + clazz);
ServiceReference sr = this.context.getServiceReference(clazz);
System.out.println("SR: " + sr);
if (sr == null) {
if (this.serviceReferences.containsKey(clazz)) {
System.out.println("Unget service");
this.context.ungetService(this.serviceReferences.get(clazz));
this.serviceReferences.remove(clazz);
}
sr = this.context.getServiceReference(clazz);
System.out.println("SR: " + sr);
if (sr == null) {
return null;
}
}
try {
this.context.addServiceListener(this, "(objectClass=" + clazz + ")");
} catch (InvalidSyntaxException ex) {
Logger.getLogger(BundleActivator.class.getName()).log(Level.SEVERE, null, ex);
}
this.serviceReferences.put(clazz, sr);
return this.context.getService(sr);
}
@Override
public void start(BundleContext bc) throws Exception {
ContextRegistry.getInstance().add(bc);
this.context = bc;
this.context.addBundleListener(this);
this.afterStart(bc);
System.out.println("Balindoo bundle activated: " + this.getClass().getPackage().getName());
}
@Override
public void stop(BundleContext bc) throws Exception {
this.beforeStop(bc);
for (ServiceRegistration sr : this.serviceRegistrations) {
this.context.ungetService(sr.getReference());
sr.unregister();
}
this.serviceRegistrations.clear();
for (ServiceReference sr : this.serviceReferences.values()) {
this.context.ungetService(sr);
}
this.serviceReferences.clear();
ContextRegistry.getInstance().remove(bc);
this.context.removeBundleListener(this);
this.context = null;
System.out.println("Balindoo bundle deactivated: " + this.getClass().getPackage().getName());
}
@Override
public void bundleChanged(BundleEvent be) {
String name = be.getBundle().getSymbolicName();
if (name.startsWith("com.vaadin")) {
if (be.getType() == BundleEvent.STARTED && !ResourceProvider.getInstance().hasBundle(be.getBundle())) {
ResourceProvider.getInstance().add(be.getBundle());
} else if (be.getType() == BundleEvent.STOPPED && ResourceProvider.getInstance().hasBundle(be.getBundle())) {
ResourceProvider.getInstance().remove(be.getBundle());
}
}
for (ServiceReference sr : this.serviceReferences.values()) {
this.context.ungetService(sr);
}
this.serviceReferences.clear();
HashSet<Bundle> thisBundle = new HashSet<>();
thisBundle.add(this.context.getBundle());
thisBundle.add(be.getBundle());
FrameworkWiring wiring = this.context.getBundle().adapt(FrameworkWiring.class);
if (wiring != null) {
System.out.println("FrameworkWiring:\n\tthis:\t" + this.context.getBundle().getSymbolicName() + "\n\tto :\t" + be.getBundle().getSymbolicName());
wiring.refreshBundles(thisBundle);
}
this.afterBundleChanged(be);
}
@Override
public void serviceChanged(ServiceEvent event) {
switch (event.getType()) {
case ServiceEvent.UNREGISTERING:
System.out.println("unregister service");
if (this.serviceReferences.containsValue(event.getServiceReference())) {
//Remove
}
this.context.ungetService(event.getServiceReference());
break;
}
}
正如你所看到的,我尝试了很多来解决这个问题,但没有任何效果。 我做错了什么?
这是包P(org.company.example.data)的清单。该接口位于org.company.example.data.api中,该组件位于单独的包中。
Manifest-Version: 1.0
Bnd-LastModified: 1381157007428
Build-Jdk: 1.7.0_21
Built-By: nspecht
Bundle-Activator: org.company.example.data.impl.BundleActivator
Bundle-Description: Example Bundle org.company.example.data 1.0.0
Bundle-ManifestVersion: 2
Bundle-Name: org.company.example.data
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Bundle-SymbolicName: org.company.org.company.example.data
Bundle-Vendor: Company Inc.
Bundle-Version: 1.0.0
Created-By: Apache Maven Bundle Plugin
Eclipse-BuddyPolicy: registered
Eclipse-RegisterBuddy: org.company.wrapper.hibernate
Export-Package: org.company.example.data.api;uses:="org.company.example.data.api.model";version="1.0.0",org.company.example.data.impl;uses:="org.company.example.data.api,org.company.utils.data.database,org.osgi.framework,org.company.example.data.api.model,org.company.utils.modulemanager.generic,org.hibernate,org.hibernate.criterion";version="1.0.0",org.company.example.data;version="1.0.0",org.company.example.data.api.impl;uses:="org.osgi.framework,org.company.utils.modulemanager.generic";version="1.0.0",org.company.example.data.api.model;uses:="org.company.utils.data.api";version="1.0.0",org.company.example.data.i18n;version="1.0.0"
Import-Package: org.company.utils.data.api;version="[1.0,2)",org.company.utils.data.database;version="[1.0,2)",org.company.utils.modulemanager.generic;version="[1.0,2)",org.hibernate;version="4.2,5)",org.hibernate.criterion;version="4.2,5)",org.osgi.framework;version="[1.6,2)"
Tool: Bnd-1.50.0
接口捆绑包的清单:
Manifest-Version: 1.0
Bnd-LastModified: 1381156992131
Build-Jdk: 1.7.0_21
Built-By: nspecht
Bundle-Activator: org.company.example.data.api.impl.BundleActivator
Bundle-Description: Example Bundle org.company.example.data.api 1.0.0
Bundle-ManifestVersion: 2
Bundle-Name: org.company.example.data.api
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Bundle-SymbolicName: org.company.org.company.example.data.api
Bundle-Vendor: Company Inc.
Bundle-Version: 1.0.0
Created-By: Apache Maven Bundle Plugin
Eclipse-BuddyPolicy: registered
Export-Package: org.company.example.data.api;uses:="org.company.example.data.api.model";version="1.0.0",org.company.example.data.api.impl;uses:="org.osgi.framework,org.company.utils.modulemanager.generic";version="1.0.0",org.company.example.data.api.model;uses:="org.company.utils.data.api";version="1.0.0"
Import-Package: org.company.utils.data.api;version="[1.0,2)",org.company.utils.modulemanager.generic;version="[1.0,2)",org.osgi.framework;version="[1.6,2)"
Tool: Bnd-1.50.0
至少捆绑U的界面:
Manifest-Version: 1.0
Bnd-LastModified: 1381157008373
Build-Jdk: 1.7.0_21
Built-By: nspecht
Bundle-Activator: org.company.example.webui.impl.BundleActivator
Bundle-Description: Example Bundle org.company.example.webui 1.0.0
Bundle-ManifestVersion: 2
Bundle-Name: org.company.example.webui
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Bundle-SymbolicName: org.company.org.company.example.webui
Bundle-Vendor: Company Inc.
Bundle-Version: 1.0.0
Created-By: Apache Maven Bundle Plugin
Eclipse-BuddyPolicy: registered
Export-Package: org.company.example.webui.impl;uses:="org.company.utils.webui,org.company.example.data.api,org.company.example.webui.menu,org.osgi.framework,org.company.utils.webui.menu,org.company.example.webui.view,org.company.utils.modulemanager.generic,org.company.utils.modulemanager.exception";version="1.0.0",org.company.example.webui.menu;uses:="org.company.utils.webui,org.company.utils.webui.generics,org.company.utils.modulemanager.translation,org.company.example.webui.view,org.company.utils.webui.menu";version="1.0.0",org.company.example.webui.i18n;version="1.0.0",org.company.example.webui.view;uses:="org.company.example.data.api,com.vaadin.server,org.company.utils.modulemanager.translation,org.company.example.data.api.model,com.vaadin.ui,org.company.example.webui.impl,com.vaadin.event,org.company.utils.webui.exception,com.vaadin.data,com.vaadin.data.util,com.vaadin.navigator,org.company.utils.modulemanager.exception";version="1.0.0"
Import-Package: com.vaadin.data;version="[7.1,8)",com.vaadin.data.util;version="[7.1,8)",com.vaadin.event;version="[7.1,8)",com.vaadin.navigator;version="[7.1,8)",com.vaadin.server;version="[7.1,8)",com.vaadin.ui;version="[7.1,8)",org.company.example.data.api;version="[1.0,2)",org.company.example.data.api.model;version="[1.0,2)",org.company.utils.modulemanager.exception;version="[1.0,2)",org.company.utils.modulemanager.generic;version="[1.0,2)",org.company.utils.modulemanager.translation;version="[1.0,2)",org.company.utils.webui;version="[1.0,2)",org.company.utils.webui.exception;version="[1.0,2)",org.company.utils.webui.generics;version="[1.0,2)",org.company.utils.webui.menu;version="[1.0,2)",org.osgi.framework;version="[1.6,2)"
Tool: Bnd-1.50.0
答案 0 :(得分:1)
检查谁正在导出包含服务接口I的软件包.P和U都必须连接到同一个软件包。为了确保U可以使用服务对象,框架验证U是否连接到与P相同的包。
似乎在更新P之后,新的P'连接到包的不同版本而不是U.所以当P'注册服务时,它来自包的不同版本。
如果包中包含P并由P导出而不使用P也导入相同的包,则会发生这种情况。服务提供者应该导出和导入服务接口包。见http://blog.osgi.org/2007/04/importance-of-exporting-nd-importing.html
答案 1 :(得分:0)
你也很可能需要“刷新”你的消费包(U),因为通常消费包会保留对原始包P的引用,因此它不会看到你的新服务。因此,您需要将捆绑U带回“解决”状态。在GOGO shell中,您通常只发出refresh命令。