2013-09-25 3 views
0

Я пытаюсь сделать упорство в среде OSGi (Karaf running Felix) с максимально возможной модулярностью. Я выбрал JDO для его добавленных функций (в основном групп извлечения) вместо JPA. Реализация - Datanucleus. Я использую Maven для создания всего проекта.Стойкость в среде OSGi с использованием Datanucleus JDO и чертежей

Поскольку у меня не было опыта работы с JDO или OSGi, было довольно сложно заставить любого из них работать. В настоящее время я могу выполнять JDO-сохранение в среде Java SE (модульные тесты работают без проблем), и я знаю, как предоставлять службы в среде OSGi с использованием контейнера планшета. Но я не могу заставить эти две вещи работать вместе. У меня проблемы с загрузкой.

Я не смог создать даже простое приложение, которое могло бы выполнять JDO-постоянство на Karaf (я пробовал следовать this tutorial, но использует Spring DM, и я не смог переписать его, чтобы использовать схему OSGi).

Что я больше всего путаются является:

  • Какое значение следует установить свойство datanucleus.primaryClassLoader к?
  • Какой класс загрузчик должен пройти в качестве аргумента для JDOHelper.getPersistenceManagerFactory метод?
  • Какие пакеты явно импортировать с помощью maven-bundle-plugin? (Выглядит как по крайней мере javax.jdo, org.datanucleus.api.jdo и org.osgi.framework может потребоваться)
  • Что другие связки нужно кроме ссылки на PersistenceManagerFactory?

Дополнительно:

  • Можно ли отделить информацию от постоянства классов стоимости? Если я правильно понял, это было бы возможно только при использовании повышения времени исполнения, которое было бы очень сложным, если это вообще возможно.
  • Можно ли определить взаимозависимые классы, совместимые с постоянством, в нескольких пакетах? Например, если пользователи определены в одном комплекте и их адреса в другом?

Я был бы чрезвычайно признателен за пример простого проекта с несколькими связями, который заботится о сохранении, используя только Datanucleus, JDO API и OSGi.

Спасибо

ответ

0

Я могу лишь дать некоторые основные советы о том, JDO/DataNucleus работать поверх Karaf.

Как указано в учебнике, вам необходимо расширить LocalPersistenceManagerFactoryBean, реализуя также интерфейс BundleContextAware.

Ключевым моментом здесь является загрузка классов: LocalPersistenceManagerFactoryBean ожидает, что все классы будут загружены одним загрузчиком классов, чего нет в среде выполнения OSGi.

Для того, чтобы получить его работы вам понадобится:

  1. Явное импортировать org.datanucleus.api.jdo в вашем файле манифеста.
  2. Свойство datanucleus.primaryClassLoader может быть настроено с тем же загрузчиком классов, что и для метода JDOHelper.getPersistenceManagerFactory. Классный загрузчик - тот, который используется комплектом org.datanucleus.api.jdo (см. Пример ниже).
  3. Вам необходимо установить datanucleus.plugin.pluginRegistryClassName на org.datanucleus.plugin.OSGiPluginRegistry.
  4. При остановке/удалить свой пакет, вам придется обновить javax.jdo пакет для избежания ошибок при повторном создании менеджера живучести завода (проверьте this question на эту тему)

Примера пользовательского LocalPersistenceManagerFactoryBean:

public class OSGiLocalPersistenceManagerFactoryBean 
    extends LocalPersistenceManagerFactoryBean implements BundleContextAware { 

    public static final String JDO_BUNDLE_NAME = "org.datanucleus.api.jdo"; 
    public static final String JDO_PMF_CLASS_NAME = "org.datanucleus.api.jdo.JDOPersistenceManagerFactory"; 

    private BundleContext bundleContext; 

    @Override 
    protected PersistenceManagerFactory newPersistenceManagerFactory(String name) { 
     return JDOHelper.getPersistenceManagerFactory(name, getClassLoader()); 
    } 

    @Override 
    protected PersistenceManagerFactory newPersistenceManagerFactory(Map props) { 
     ClassLoader classLoader = getClassLoader(); 

     props.put("datanucleus.primaryClassLoader", classLoader); 

     if (FrameworkUtil.getBundle(this.getClass()) != null) { // running in OSGi 
      props.put("datanucleus.plugin.pluginRegistryClassName", "org.datanucleus.plugin.OSGiPluginRegistry"); 
     } 

     PersistenceManagerFactory pmf = JDOHelper.getPersistenceManagerFactory(props, classLoader); 

     return pmf; 
    } 

    private ClassLoader getClassLoader() { 
     ClassLoader classLoader = null; 
     Bundle thisBundle = FrameworkUtil.getBundle(this.getClass()); 

     if (thisBundle != null) { // on OSGi runtime 
      Bundle[] bundles = bundleContext.getBundles(); 

      for (Bundle bundle : bundles) { 
       if (JDO_BUNDLE_NAME.equals(bundle.getSymbolicName())) { 
        try { 
         classLoader = bundle.loadClass(JDO_PMF_CLASS_NAME).getClassLoader(); 
        } catch (ClassNotFoundException e) { 
         // do something fancy here ... 
        } 
        break; 
       } 
      } 
     } else { // on Java runtime 
      classLoader = this.getClass().getClassLoader(); 
     } 
     return classLoader; 
    } 

    @Override 
    public void setBundleContext(BundleContext bundleContext) { 
     this.bundleContext = bundleContext; 
    } 
} 
+0

Спасибо. Я это проверю. – binarek

+0

Также обратите внимание, что все пучки пакетов данных должны запускаться при запуске вашего пакета. Если это не так, вы получите ошибку (NullPointerException) в OSGIPluginRegistry. –

Смежные вопросы