OSGI Bundle Lazy Activation

Я действительно новичок в этом (OSGI), пытаюсь сделать простые примеры. Я не могу заставить ленивую работу актрисы. Я знаю, что есть несколько Blueprint для решения таких проблем, но прежде чем перейти к одному, я подумал, что было бы неплохо изучить некоторые основы.

    Bundle DataService:
    Манифест-Версия: 1.0  
    Bundle-версия: 1.0.0  
    Bundle-Name: DataService  
    Пакет-Манифест Версия: 2  
    Пакет-активатор: DataService.Activator  
    Импорт-пакет: org.osgi.framework  
    Bundle-SymbolicName: DataService  
    Export-Package: DataService; версия ="1.0.0"  
    Bundle-ActivationPolicy: ленивый  

    Bundle DataServiceClient:  
    Манифест-Версия: 1.0  
    Bundle-версия: 1.0.0  
    Имя пакета: DataServiceClient  
    Пакет-Манифест Версия: 2  
    Пакет-активатор: DataServiceClient.Activator  
    Пакет импорта: org.osgi.framework, DataService; версия ="[1.0.0,1.0.0]"  
    Bundle-SymbolicName: DataServiceClient

Хорошо, я изменил свой код, но все равно не повезло.

Внешнее приложение, устанавливает пакеты, запускает фреймворк, а затем только запускает пакет DataServiceClient. Нет доступа к любому классу комплектов.

    Файл bundleDir = новый файл ("./bundles/");  
    String[] bundleResources = bundleDir.list();  
    for(String bundleResourcePath: bundleResources) {Файл bundleResource = новый файл (bundleDir, bundleResourcePath);  
        InputStream bs =new FileInputStream(bundleResource);  
        mFramework.getBundleContext().installBundle(bundleResource.getName(), bs);  
    }  
    mFramework.start();  

    bl = mFramework.getBundleContext().getBundles();  
    for(Bundle b: bl) {  
        if (b.getBundleId()!= 0 && b.getSymbolicName().contains("DataServiceClient")) {  
            b.start();  
        }           
    } 

Вот начало DataServiceClient:

    System.out.println ("Запуск DataServiceClient");
    IDataService  service = new DummyService();
    System.out.println(service.getData());

Вот класс DummyService в комплекте "DataService".

    открытый класс DummyService реализует IDataService {

        @Override
        public String getData() {
            вернуть "DummyService Data";
        }
    }

Вот начало пакета "DataService":

    System.out.println ("Запуск DataService");

На выходе я получаю:

    DataServiceClient Start
    DummyService Data

Однако я ожидаю увидеть:

    DataServiceClient Start
    DataService Start
    DummyService Data

небольшая цитата из http://www.osgi.org/Design/LazyStart

Ленивая Активация

Ленивая активация - это политика жизненного цикла, которая обязывает активировать пакет при первом успешном запросе на загрузку класса из этого пакета.

Однако, поскольку это не работает, я полагаю, что я полностью неправильно понимаю концепцию ленивой активации или я делаю что-то не так.

Если я явно не вызываю start для пакета DataService, похоже, он не вызывает Activator.start для пакета DataService. Это то, что я не понимаю.

Спасибо за ваше время

3 ответа

Вы уверены, что ваш Активатор действительно не вызывается. У меня часто был случай, когда был вызван активатор, но был опыт и исключение, которое проглотил OSGi. Можете ли вы попробовать println в первой строке в Activator.start, чтобы проверить это. Попытка поймать с журналированием также полезна в этом случае.

Btw. Наименование пакета с заглавной буквой весьма необычно. Не уверен, что это проблема, но я бы избежал этого.

Непонятно, что происходит, когда вы вызываете DummyClient.GetData(). Вы говорите, что он вызывает класс в комплекте DataService, но как?? DataService - это обычный пакет, а ваш код - основное приложение запуска Java, и в OSGi нет никакого способа, чтобы "внешнее" приложение статически зависело от обычного пакета.

В любом случае, даже если вы могли бы сделать это, вы выполняете эту строку кода до запуска пакета. Активатор пакета, конечно, не будет вызываться до запуска пакета!! Я ожидаю, что ваш активатор будет вызван в строке 36, то есть, куда вы звоните bundle.start() на каждой пачке.

Но на самом деле... что ты пытаешься делать?? Bundle-ActivationPolicy: lazy Флаг почти полностью бесполезен. У меня восьмилетний опыт работы с OSGi, и я когда-либо использовал этот параметр только в приложениях Eclipse RCP по устаревшим причинам. Если вы не пишете плагин Eclipse или приложение Eclipse RCP, вы не должны использовать Bundle-ActivationPolicy: lazy в ОСГИ.

Правильный способ получить ленивый (или "вовремя") экземпляр в OSGi - это использовать декларативные сервисы (DS). Все сервисные объекты, публикуемые DS, создаются по требованию, когда клиент сначала пытается вызвать их, а не во время их регистрации. Вам не нужно делать ничего особенного, чтобы включить это.

Что касается измененного кода... вы никогда не запускаете пакет DataServiceClientпоэтому его активатор нельзя назвать. Вы явно исключили его по имени из цикла, в котором вы запускаете пакеты. OSGi будет называть только BundleActivator на связках, которые были начаты с bundle.start(),

Это очень широко неверно понятый момент... OSGi никогда не запускает пакеты автоматически, даже если Bundle-ActivationPolicy: lazy флаг включен.

Вероятно, вы хотели запустить пакет следующим образом:

bundle.start(Bundle.START_ACTIVATION_POLICY).

Фактически вы делаете это для всех пакетов, а не произвольно начинаете подмножество пакетов.

Но опять же, я должен повторить то, что я высказал в своем другом ответе. С помощью Bundle-ActivationPolicy: lazy это бессмысленно, за исключением случаев, когда вы разрабатываете приложения Eclipse RCP, и в этом случае вам иногда приходится использовать его по глупым унаследованным причинам.

Другие вопросы по тегам