2013-10-07 4 views
1

У меня есть пакет P (rovider = который реализует интерфейс, определенный в Bundle I (интерфейс) Bundle U (ser) должен использовать эту услугу. После того, как я запустил приложение, все работает нормально, все мой сервис может быть использован Но когда я обновляю Bundle P, не его службы может быть решенOSGI: Сервис недоступен после обновления пакета

метод обновления выглядит следующим образом:..

this._bundle.stop(); 
this._bundle.update(new FileInputStream(updateFile)); 
this._bundle.start(); 

Это мой BundleActivator для всех моих пакетов, которые также должны обращаться с сервисными службами и службами:

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 

По крайней мере, интерфейс для Bundle 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 

ответ

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

+0

My Package P импортирует и экспортирует пакет, в котором находится интерфейс. – vralfy

+0

Вы имеете в виду, что ваш пакет P импортирует и экспортирует пакет. Возможно, вы можете поделиться манифестом? Вы должны убедиться, что после обновления Bundle P и Bundle U подключены к одному и тому же пакету для интерфейса службы. –

+0

Я обновил 3 файла MANIFEST.MF. Я ошибся в своем предыдущем посте. Bundle P - -NOT - импортирует пакет, в котором находится интерфейс. Я добавил его как зависимость и сказал maven экспортировать каждый пакет, который называется org.company.example.data. * (Который на самом деле включает org.company.example.data.api). Может ли это быть моей ошибкой? – vralfy

0

вы, скорее всего, нужно "освежить" свои потребителями БМ связки (U), так как, как правило, потребительский комплект сохраняет ссылку на исходный комплект P, и поэтому он не увидит ваши новые Услуги. Таким образом, вам нужно вернуть свой пакет U в состояние «разрешения». В оболочке GOGO обычно выдается команда обновления.

+0

Вызов команды обновления не помогает. Я также попытался остановить и запустить U, который также не работает. – vralfy