Установка двух бандлов с одним и тем же файлом

Я использую декларативные службы OSGI.

В моем java-приложении я запускаю Apache Felix, устанавливаю и запускаю некоторые пакеты.

Установлено два пакета, использующих один и тот же путь к файлу. После запуска пакета он должен отображать сообщение «Привет».

Когда я устанавливаю и запускаю первый пакет:

Bundle bundle1 = context.installBundle("file:C://Users//bundles//myBundle.jar");
bundle1.start();

Это показывает «Hello» в консоли.

Однако, когда я устанавливаю второй пакет (с тем же путем к файлу, что и первый пакет)

Bundle bundle2= context.installBundle("file:C://Users//bundles//myBundle.jar");
bundle2.start();

Я не вижу выхода. Это означает, что установка и/или запуск второго пакета были проигнорированы.

Мне нужен способ установить и запустить два разных пакета с одним и тем же путем к файлу, и когда я останавливаю один из этих пакетов, другой должен оставаться АКТИВНЫМ. Как я могу достичь этого? Спасибо.

Вариант использования, о котором я думаю: допустим, у меня есть два пользователя, и оба хотели бы использовать одну и ту же функцию (пакет). Что, если один из них решит отключить функцию пакета, а другой захочет ее сохранить?

Есть ли лучший способ добиться этого? Спасибо.


person Traveling Salesman    schedule 27.01.2014    source источник


Ответы (3)


Изменяется ли содержимое файла между двумя установками? Если нет, то вы не можете этого сделать. По сути, вы пытаетесь создать экземпляр пакета дважды, а OSGi позволяет установить каждый пакет только один раз.

На самом деле у вас может быть несколько версий пакета одновременно, но пара Bundle-SymbolicName и Bundle-Version должна быть уникальной в рамках фреймворка.

Сопоставление пользовательских функций с установленными пакетами на самом деле не очень хорошая идея. Почему пользователи должны заботиться о модулях, установленных в вашем приложении?? Вместо этого вы хотите, чтобы функциональность пакета поддерживала нескольких пользователей.

person Neil Bartlett    schedule 27.01.2014
comment
спасибо, Нил, я понял это сейчас. Но мне нужно знать, как вы реализуете эту множественную функциональность в одном пакете в Declarative Service. Какие-нибудь документы, объясняющие идею, с кодом? Как обычно, пытаюсь выучить osgi с нуля. Ищем API и теряемся там. - person Traveling Salesman; 28.01.2014
comment
Я думаю, что ссылки, которые Балаш предоставил в комментариях к своему ответу, довольно хороши. - person Neil Bartlett; 28.01.2014

Вы можете вызвать функцию

context.installBundle (местоположение, inputStream)

и передайте InputStream этой функции. В этом случае вы можете указать два разных местоположения (например, то, которое имеет какое-то значение, но не является реальным местоположением).

Ваша следующая проблема будет заключаться в том, что два пакета с одним и тем же SymbolicName и одной и той же версией не могут существовать дважды.

Я не могу представить себе вариант использования, когда один и тот же пакет должен быть установлен дважды. Это может быть результатом плохой концепции.

person Balazs Zsoldos    schedule 27.01.2014
comment
Допустим, у меня есть два пользователя. Оба выбрали одну и ту же функцию, но позже один решил отключить эту функцию. (Функция здесь - комплект). Разве это не вариант использования? - person Traveling Salesman; 27.01.2014
comment
Зависит от смысла характеристики. Я думаю, что пакет содержит реализацию функции. Выбор этой функции несколько раз означает, что классы в пакете создаются несколько раз. Например. Вы можете создать компонент DS на основе фабрики конфигураций. Если пользователь создает новую конфигурацию, компонент будет создан с этой конфигурацией. - person Balazs Zsoldos; 27.01.2014
comment
Вы говорите о ComponentFactory? Не могли бы вы привести пример, надеюсь, небольшой код? - person Traveling Salesman; 27.01.2014
comment
Это первое, что возвращает Google при поиске декларативных сервисов. Я говорил о коде. - person Traveling Salesman; 28.01.2014
comment
Как насчет этого: github.com/everit-org/osgi-liquibase-component/blob/master/ Это компонент DataSource, экземпляр которого создается столько раз, сколько доступно конфигураций. . Цель этого аналогична, но с другими инструментами: github.com/osgi/bundles/blob/master/osgi.jdbc/src/osgi/jdbc/ - person Balazs Zsoldos; 28.01.2014

Есть две вещи, которые вам нужно учитывать: местоположение пакета должно быть уникальным, и платформа должна быть настроена на прием нескольких пакетов с одним и тем же символическим именем пакета. Вы должны использовать bundleContext.install(location, inputStream) для установки пакета. Может быть так:

byte[] byteArray byteArray = IOUtils.toByteArray(new FileInputStream(new File(filePath);
Bundle bundle = bc.installBundle(jobID, new ByteArrayInputStream(byteArray));

И чтобы фреймворк мог принимать несколько пакетов с одним и тем же символическим именем пакета, вам нужно запустить фреймворк со следующей опцией:

-Dorg.osgi.framework.bsnversion=multiple

Обратите внимание, что команда обновления по-прежнему будет пытаться обновить пакет из заданного местоположения, которое в моем случае (jobID) не было реальным путем к файлу. Это не имело значения для моего варианта использования, поэтому я никогда не удосужился решить эту проблему.

person Malek Ben Salem    schedule 22.06.2016
comment
Не могли бы вы поделиться готовым примером для этой реализации? - person Zach Pham; 23.03.2020