Вопрос

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

Мои первоначальные тесты показывают, что экземпляр службы можно использовать даже после остановки пакета служб, что противоречит моему пониманию динамической природы OSGi.

Я полагаю, что это сводится к тому, что на самом деле делает получение службы (через ServiceTracker) из другого пакета в контейнере OSGi: создает ли он новый экземпляр или дает вам указатель на экземпляр, зарегистрированный в контейнере?

Существуют ли какие-либо опасности при использовании экземпляра службы после ее остановки?

Это было полезно?

Решение

Это очень хороший вопрос, поэтому я покопался в спецификации в поисках однозначного ответа.Оказывается, об этой проблеме есть целый раздел - см. раздел 5.4 Устаревшие ссылки начиная со страницы 132 Базовая спецификация сервисной платформы OSGi, выпуск 4, версия 4.2.

Чтобы ответить на ваш вопрос в соответствии со спецификацией:

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

И чтобы предотвратить потенциальные проблемы:

Связки должны слушать события, сгенерированные рамками для очистки и удаления устаревших ссылок.

Спецификация также дает несколько советов, как минимизировать последствия устаревших ссылок.

Другие советы

Вы правы в том, что это противоречит динамической природе OSGi.Я считаю, что нет никакой гарантии, что сервис будет доступен, хотя разные реализации OSGi-контейнеров и самих сервисов могут вести себя по-разному.

Например, если служба была создана и зарегистрирована в Spring DM, то полученная служба на самом деле является прокси-сервером на основе Spring для базовой реализации, и реализация все равно может исчезнуть.Таким образом, ссылка на службу, которая ссылается непосредственно на реализацию, может предотвратить удаление этого объекта, тогда как ссылка на основе прокси-сервера этого не сделает.

Спецификация OSGi гласит:

Связки - это объекты, которые видны в обычном прикладном программировании.Например, когда пакет будет остановлен, все его услуги будут незарегистрированы.

Таким образом, вы не сможете получить услугу из остановленного пакета.Но технически его можно использовать, по крайней мере, пока у вас есть ссылка на объект службы (никто не сможет его у вас отобрать, и он не будет GC'd).Но я не думаю, что пользоваться сервисом безопасно.Это может зависеть от других ресурсов пакета, которые недоступны после остановки пакета.

Как только экземпляр службы OSGI будет извлечен из контекста пакета, становится ли он недействительным, когда служба остановлен?

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

Однако будет ли он по-прежнему полезен, зависит только от самой реализации сервиса, а не от контейнера.

Мои первоначальные тесты показывают, что экземпляр службы можно использовать даже после остановки пакета служб, что противоречит моему пониманию динамической природы OSGi.

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

Я полагаю, что это сводится к тому, что на самом деле делает услуга (через ServiceTracker) из другого пакета в контейнере OSGI, создает ли он новый экземпляр или дает вам указатель на экземпляр, который зарегистрирован в контейнере?

Контейнер не создает новые экземпляры сервисов, за исключением случаев, когда задействована ServiceFactory (см. спецификации).Поиск службы всегда должен давать вам указатель на зарегистрированный экземпляр в контейнере.

Существуют ли какие-либо опасности при использовании экземпляра службы после ее остановки?

Это зависит только от реализации сервиса;однако, делая это в пакете, вы автоматически создаете пакет, который не соответствует спецификациям.

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

Что касается вашего вопроса, опасно ли использовать экземпляр службы после ее остановки.Цитируем из базовой спецификации 4.2 (5.4 Stale References):

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

Я не хочу цитировать здесь весь раздел спецификации, но следующие предложения являются хорошим обсуждением опасности использования устаревших ссылок:

Уверяющая ссылка - это ссылка на объект Java, который принадлежит к классу загрузчика пакета, который останавливается или связан с обслуживающим объектом, который незарегистрирован.Стандартная Java не предоставляет никаких общих средств для очистки устаревших ссылок, и разработчики пакета должны тщательно проанализировать свой код, чтобы гарантировать, что устаревшие ссылки удаляются.

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

Ссылку на службу никогда не следует хранить как ссылку.Вы всегда должны искать сервис во время выполнения.Однако это привязывает вас к API OSGI, что не всегда требуется.

Посмотрите на - Osgi ServiceTracker - Declarative Services Osgi - Blueprint Osgi - Spring DM - Peaberry - Ipojo

все они заботятся о динамизме за вас, большинство из них не имеют API OSGI.

С уважением,

Лин Тулен

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top