Внедряем OSGI на платформе Karaf

    OSGI это не сложно


    Я много раз встречал мнение, что OSGI это сложно. И более того, у самого когда-то такое мнение было. Году в 2009, если быть точным. На тот момент мы собирали проекты при помощи Maven Tycho, и деплоили их в Equinox. И это действительно было сложнее, чем разрабатывать и собирать проекты под JavaEE (в тот момент как раз появилась версия EJB 3, на которую мы и переходили). Equinox был намного менее удобен по сравнению с Weblogic, например, а преимущества OSGI тогда мне были не очевидны.

    Зато потом, через много лет, мне пришлось на новой работе взяться за проект, который был задуман на основе Apache Camel и Apache Karaf. Это была не моя идея, я давно знал к тому моменту про Camel, и решил почитать про Karaf, даже еще не имея оффера. Почитал один вечер, и понял — вот же оно, простое и готовое, практически то же самое решение некоторых проблем типового JavaEE, аналогичное которому я когда-то делал на коленке при помощи Weblogic WLST, Jython, и Maven Aether.

    Итак, допустим вы решили попробовать OSGI на платформе Karaf. С чего начнем?

    Если хочется более глубокого понимания


    Можно конечно начать с чтения документации. А можно и с Хабра — тут были весьма неплохие статьи, скажем вот совсем уже давно такая. Но в целом karaf получил пока незаслуженно мало внимания. Была еще пара обзоров этот или этот. Вот это упоминание karaf лучше пропустить. Как говорится, не читайте на ночь советских газет… ибо вам там скажут, что karaf это OSGI фреймворк — так вы не верьте. OSGI фреймворки — это Apache Felix или Eclipse Equinox, на базе которых karaf как раз и работает. Можно при этом выбрать любой из них.

    Надо заметить, что когда упоминается Jboss Fuse, или Apache ServiceMix, то следует это читать как «Karaf, с предустановленными компонентами», т.е. по сути — тоже самое, только собранное вендором. Я бы не советовал начинать с этого на практике, но почитать вполне можно и обзорные статьи про ServiceMix, например.

    Для начала, я попробую тут определить совсем кратко, что из себя представляет OSGI, и для чего можно это применять.

    По большому счету OSGI это средство для создания Java-приложений из модулей. Близким аналогом можно считать, например JavaEE, и в какой-то степени OSGI контейнеры могут выполнять JavaEE модули (скажем, web-приложения в виде War), а с другой стороны, многие JavaEE контейнеры содержат OSGI внутри, как средство реализации модульности «для себя». То есть, JavaEE и OSGI — это вещи похожие до совместимости, и удачно взаимодополняющие.

    Важная часть любой модульной системы — это определение самого модуля. В случае OSGI модуль называется бандлом (bundle), и является хорошо известным всем разработчикам jar архивом с некоторыми дополнениями (то есть, и тут очень похож например на war или ear). По аналогии с JavaEE бандлы могут экспортировать и импортировать сервисы, являющиеся, по сути, методами классов (то есть, сервис — это интерфейс, или все публичные методы класса).

    Метаданные бандла — это знакомый всем META-INF/MANIFEST.MF. Заголовки манифеста OSGI не пересекаются с заголовками для JRE, соответственно, вне OSGI контейнера бандл — это обычный jar. Существенно, что среди метаданных обязательно есть:

    Bundle-SymbolicName: com.example.myosgi
    Bundle-Version: 1.0.0
    

    Это «координаты» бандла, и тут важен тот факт, что мы можете иметь в одном контейнере две и более одновременно установленных и работающих версии одного бандла.

    По аналогии с JavaEE бандлы имеют жизненный цикл, который выглядит так: image Кроме сервисов бандлы могут импортировать и экспортировать также пакеты (packages, в обычном для java смысле этого термина). Экспортируемые пакеты определены внутри бандла, и делаются доступными другим компонентам, когда бандл устанавливается в систему. Импортируемые определены где-то извне, должны быть кем-то экспортированы, и предоставлены бандлу контейнером, прежде чем он сможет начать работать.

    Импорты пакетов могут быть объявлены необязательными, также как и импорты сервисов. И еще довольно существенно, что импорт и экспорт содержат указание на версию (или диапазон версий).

    Отличия от JavaEE


    Ну хорошо, что они похожи — мы поняли. А чем они отличаются?

    На мой взгляд, основное отличие состоит в том, что OSGI дает нам намного большую гибкость. Как только бандл перешел в состояние STARTED, возможности ограничены только вашей фантазией. Скажем, вы можете спокойно создавать потоки (да, да, я знаю про ManagedExecutorService), пулы коннектов к базам, и т.п. Контейнер не берет на себя управление всеми ресурсами в той же мере, что JavaEE.

    Вы можете в процессе работы экспортировать новые сервисы. Попробуйте скажем в JavaEE динамически создать новый сервлет? А тут это вполне возможно, более того, сервлетный контейнер karaf, созданный на базе jetty, ваш созданный сервлет тут же обнаружит, и он будет доступен клиентам по определенному URL.

    Хотя это и является небольшим упрощением, но если JavaEE приложение в его классическом виде состоит в основном из компонентов:

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

    С другой стороны, приложение на базе OSGI может содержать:

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

    Да, на JavaEE многое из этого тоже частично возможно (например, через JNDI), но в случае OSGI на практике делается проще. Хотя и рисков тут, наверное, несколько больше.

    Отличия karaf от чистого OSGI


    Помимо фреймворка karaf включает много чего полезного. В сущности, karaf есть средство для удобного управления OSGI фреймворком — установки туда бандлов (в том числе группами), их конфигурирования, мониторинга, описания ролевой модели и обеспечения безопасности, и тому подобного.

    А давайте уже практиковаться?


    Ну чтож, начнем сразу с установки. Тут писать особо нечего — идем на сайт karaf.apache.org, скачиваем дистрибутив, распаковываем. Версии karaf отличаются между собой поддержкой разных спецификаций OSGI (4, 5 или 6), и версий Java. Семейство 2.x я не советую, а вот и 3 (если у вас Java 8, как у меня), и 4 вполне можно пользоваться, хотя развивается на сегодня только семейство 4.x (текущая версия 4.2.2, она поддерживает OSGI 6 и Java вплоть до 10).

    Karaf вполне нормально работает под Windows и Linux, все что нужно для создания сервиса и автозапуска, имеется. Поддержка MacOS и многих других видов Unix тоже декларируется.

    Обычно можно запустить karaf сразу, если вы в интернете. Если нет, то как правило стоит подправить файл конфигурации, указав, где у вас репозиторий(-ии) maven. Обычно это будет корпоративный Nexus, или скажем Artifactory, кому что нравится. Конфигурация karaf располагается в папке etc дистрибутива. Названия файлов конфигурации не слишком очевидны, но в этом случае вам нужен файл org.ops4j.pax.url.mvn.cfg. Формат этого файла — java properties.

    Задать репозиторий(и) можно как в самом файле конфигурации, перечислив список URL в настройках, так и просто показав, где лежит ваш settings.xml. Там же караф возьмет расположение вашего proxy, что в интранете как правило знать обязательно.

    Kafar нужны несколько портов, это порты HTTP, HTTPS (если web настроен, по умолчанию нет), SSH, RMI, JMX. Если они у вас заняты, или вы хотите запустить на одном хосте несколько копий, то придется изменить и их. Всего этих портов примерно пять.

    Порты типа jmx и rmi — вот тут: org.apache.karaf.management.cfg, ssh — org.apache.karaf.shell.cfg, чтобы поменять порты http/https, нужно будет создать (его скорее всего нет) файл etc/org.ops4j.pax.web.cfg, и записать в него значение org.osgi.service.http.port=нужный-вам-порт.

    Дальше точно можно запускать, и как правило все заведется. Для промышленного использования очевидно придется внести изменения в файл bin/setenv, или bin/setenv.bat, чтобы например выделить нужный объем памяти, но для начала, чтобы посмотреть, это не нужно.

    Можно запустить Karaf сразу с консолью, командой karaf, а можно в фоновом режиме, командой start server, и потом подключиться к нему по SSH. Это вполне стандартный SSH, с поддержкой SCP, и SFTP. Вы можете выполнять команды, и копировать туда-сюда файлы. Вполне можно подключиться любым клиентом, например моим любимым инструментом является Far NetBox. Доступен вход по логину и паролю, а также и по ключам. В потрохах jsch, со всеми вытекающими последствиями.

    Рекомендую иметь сразу дополнительное окно консоли, для просмотра логов, которые размещаются в data/log/karaf.log (и другие файлы обычно там же, хотя это настраивается). Логи вам пригодятся, из кратких сообщений в консоли не все бывает понятно.

    Я бы посоветовал сразу установить web, и hawtio web-консоль. Эти две вещи позволят вам намного проще ориентироваться в том, что происходит в контейнере, и в значительной степени рулить процессом оттуда (как бонус, вы получите jolokia и возможность мониторинга по http). Установка hawtio выполняется двумя командами из консоли karaf (как описано тут), и увы, на сегодня версия karaf 3.x уже не поддерживается (вам придется поискать более старые версии hawtio).

    Из коробки https сразу не будет, для этого нужно предпринять некоторые усилия типа генерации сертификатов и пр. Реализация основана на jetty, поэтому все эти усилия по большей части делаются так же.

    Хорошо, оно запустилось, что дальше?




    Собственно, а вы чего ожидали? Я же говорил, будет ssh. Tab работает, если что.

    Самое время установить какое-нибудь приложение. Приложение для OSGI либо является бандлом (bundle), или состоит из нескольких бандлов. Караф умеет деплоить приложения в нескольких форматах:

    • Бандл в виде jar, как с манифестом OSGI, так и без него
    • xml, содержащий Spring DM или Blueprint
    • xml, содержащий так называемую feature, которая представляет собой набор из бандлов, других features, и ресурсов (файлов конфигурации)
    • архив .kar, содержащий несколько features и репозиторий maven с зависимостями
    • JavaEE приложения (при некоторых дополнительный условиях), например .war

    Это можно сделать несколькими способами:

    • положить приложение в папку deploy
    • установить из консоли командой install
    • установить feature командой из консоли feature:install
    • kar:install

    Ну в общем, это вполне похоже на то, что умеет типовой JavaEE контейнер, но несколько удобнее (я бы сказал — сильно удобнее).

    Простой jar


    Самый простой вариант — это установить обычный jar. Если он у вас лежит в maven репозитории, то для установки достаточно команды:

    install mvn:groupId/artifactId/version

    При этом Karaf понимает, что перед ним обычный jar, и обрабатывает его, создавая на лету бандл-обертку, т.н. wrapper, генерируя манифест по умолчанию, с импортами и экспортами пакетов.

    Смысла от установки просто jar как правило немного, так как этот бандл будет пассивным — из него только экспортируются классы, которые будут доступны другим бандлам.

    Этот способ применяется для установки компонентов типа Apache Commons Lang, для примера:

    install mvn:org.apache.commons.lang3/commons-lang/3.8.1

    А вот и не получилось :) Вот верные координаты:

    install mvn:org.apache.commons/commons-lang3/3.8.1

    Посмотрим, что вышло: list -u покажет нам бандлы и их источники:

    karaf@root()> list -u
    START LEVEL 100 , List Threshold: 50
    ID | State     | Lvl | Version | Name                | Update location
    -------------------------------------------------------------------------------------------------
    87 | Installed |  80 | 3.8.1   | Apache Commons Lang | mvn:org.apache.commons/commons-lang3/3.8.1
    88 | Installed |  80 | 3.6.0   | Apache Commons Lang | mvn:org.apache.commons/commons-lang3/3.6

    Как видите, вполне можно установить две версии одного компонента. Update location — это то место, где мы взяли бандл, и откуда его можно при необходимости обновить.

    Jar и Spring context


    Если внутри вашего jar имеется Spring Context, все становится интереснее. Karaf Deployer автоматически ищет xml-контексты в папке META-INF/spring, и создает их, если успешно нашлись все нужные бандлу внешние пакеты.

    Таким образом, все сервисы, которые были внутри контекстов, уже запустятся. Если у вас там были например Camel Spring, то Camel routes запустятся тоже. Это означает, что скажем REST сервис, или сервис, слушающий TCP-порт, вы уже можете запустить. Разумеется, запустить несколько сервисов, слушающих один порт, так просто не выйдет.

    Просто Spring XML context


    Если у вас внутри Spring Context были например определения JDBC DataSources, то вы вполне можете установить их в Karaf отдельно. Т.е. взять xml файл, содержащий только DataSource в виде <bean>, или любой другой набор компонентов, вы можете положить его в папку deploy. Context будет запущен стандартным способом. Единственная проблема в том, что созданные таким образом DataSources не будут видны другим бандлам. Их нужно экспортировать в OSGI в виде сервисов. Об этом — чуть позже.

    Spring DM


    Чем в сущности отличается Spring DM (версия с поддержкой OSGI) от классического Spring? Тем что в классическом случае у вас все бины в контексте создаются на этапе инициализации контекста. Новых появиться не может, старые никуда не денутся. В случае OSGI новые бандлы могут быть установлены, а старые удалены. Среда становится более динамичной, на это нужно как-то реагировать.

    Способ реагирования называется сервисами. Сервис — это как правило некий интерфейс, со своими методами, который опубликован каким-либо бандлом. Сервис имеет метаданные, позволяющие его искать и отличать от другого сервиса, реализующего аналогичный интерфейс (от другого DataSource, очевидно). Метаданные — это простой набор свойств key-value.

    Так как сервисы могут появляться и пропадать, те, кому они нужны, могут либо подписаться на сервисы при старте, либо слушать события, чтобы узнать об их появлении или пропадании. На уровне Spring DM, в XML, это реализовано как два элемента, service и reference, базовое назначение которых достаточно простое: опубликовать имеющийся бин из контекста как сервис, и подписаться на внешний сервис, опубликовав его в текущий spring-контекст.

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

    На самом деле, все немножко сложнее, потому что бандл может пользоваться списком похожих сервисов, и подписаться сразу на список. Т.е. у сервиса, в общем случае, есть такое свойство, как cardinality, принимающее значение 0..N. При этом подписка, где указано 0..1, описывает необязательный сервис, и в этом случае бандл успешно стартует, даже если такого сервиса в системе нет (а вместо ссылки на него получит заглушку).

    Замечу, что сервис — это именно любой интерфейс (а можно публиковать и просто классы), поэтому вы вполне можете в качестве сервиса опубликовать java.util.Map с данными.

    Кроме всего прочего, service позволяет указать метаданные, а reference — искать сервис по этим метаданным.

    Blueprint


    Blueprint — это более новая инкарнация Spring DM, которая немного попроще. А именно, если в Spring у вас есть custom XML элементы, то тут их нет, за ненадобностью. Иногда это все же доставляет неудобства, но прямо скажем — нечасто. Если вы не мигрируете проект из Spring, то можно начать сразу с Blueprint.

    Суть тут таже самая — это XML, где описаны компоненты, из которых собирается контекст бандла. Для знающих Spring тут нет вообще ничего незнакомого.

    Вот пример, как описать DataSource, и экспортировать в виде сервиса:

    <?xml version="1.0" encoding="UTF-8"?>
    <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
       <bean id="dataSource" class="oracle.jdbc.pool.OracleDataSource">
            <property name="URL" value="URL"/>
            <property name="user" value="USER"/>
            <property name="password" value="PASSWORD"/>
        </bean>
      <service interface="javax.sql.DataSource" ref="dataSource" id="ds">
        <service-properties>
                <entry key="osgi.jndi.service.name" value="jdbc/ds"/>
        </service-properties>
      </service>
    </blueprint>

    Ну вот, мы задеплоили этот файл в папку deployment, и посмотрели результаты команды list. Увидели, что бандл не запустился — в статусе Indtalled. Пробуем start , и получаем сообщение об ошибке.

    Теперь в списке бандл в статусе Failed. В чем дело? Очевидно, в том, что ему тоже нужны зависимости, в данном случае — Jar с классами Oracle JDBC, а еще точнее — пакет oracle.jdbc.pool.
    Находим нужный jar в репозитории, или скачиваем с сайта Oracle, и устанавливаем, как было описано раньше. Наш DataSource запустился.

    Как этим всем воспользоваться? Ссылка на сервис называется в Blueprint reference (где-то, в контексте другого бандла):

    <reference id="dataSource" interface="javax.sql.DataSource"/>

    Затем данный бин становится, как обычно, зависимостью для других бинов (в примере camel-sql):

    <bean id="sql" class="org.apache.camel.component.sql.SqlComponent">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    Jar и Activator


    Канонический способ инициализации бандлов — это класс, реализующий интерфейс Activator. Это типичный интерфейс жизненого цикла, содержащий методы start и stop, которым передается контекст. Внутри них бандл как правило запускает свои потоки, если нужно, начинает слушать порты, подписывается на внешние сервисы при помощи OSGI API, и так далее. Это самый пожалуй сложный, самый базовый, и самый гибкий способ. Мне он за три года не понадобился ни разу.

    Настройки и конфигурирование


    Понятно, что такая конфигурация DataSource, как приведена в примере, мало кому нужна. Логин, пароль, и прочее, все хардкодится внутри XML. Нужно вынести эти параметры наружу.

    <property name="url" value="${oracle.ds.url}"/>
    <property name="user" value="${oracle.ds.user}"/>
    <property name="password" value="${oracle.ds.password}"/>

    Решение достаточно простое, и похожее на то, что применяется в классическом Spring: в определенный момент жизненного цикла контекста происходит подстановка значений свойств из разного рода источников.

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

    Комментарии 50

      0
      Итак, допустим вы решили попробовать OSGI на платформе Karaf

      А зачем уж я это решил в 2019 году, напомните мне? :)


      В век-то выстреливших микросервисов и такого прочего..

        +1
        Там написано «допустим». Это вполне может означать, что вы и не решили. Не вижу в этом никаких проблем.

        >В век-то выстреливших микросервисов
        Вообще-то, karaf как раз и есть отличная среда для этих самых микросервисов. Которая обеспечивает им определенный уровень изоляции, с одной стороны, и в тоже время, определенный уровень централизованного управления, развертывания, мониторинга и прочего. Я вполне себе разворачивал проект, содержащий десятки своих бандлов, силами одного человека, то есть меня. И силами небольшой команды — шину на сотни сервисов.

        То есть, говоря по-простому, имея под рукой karaf, мне вообще микросервисы как таковые и не нужны — потому что бандл это и есть микросервис. Ну, с некоторыми понятными ограничениями на платформу, т.е. все микросервисы будут под JVM, а не написаны на условном Go или питоне.

        А если у вас скажем есть микросервисы, то вам все эти проблемы (управления, развертывания, мониторинга) так или иначе все равно придется решать. И для меня скажем далеко не факт, что будет лучше. У разных вариантов есть свои преимущества и недостатки.

        >такого прочего.
        Вот тут можно поподробнее, какого «такого прочего»?
          –1
          Да и в самой JVM сейчас есть решение части задач OSGI в виде JPMS.
            0
            Вообще-то, их области применимости даже почти не пересекаются.
              0

              А какая область применимости OSGI и какая область применимости JPMS?

                0
                Реальная область применимости OSGI — это куча JavaEE и ESB, которые на нем основаны. А еще к примеру OpenHAB, то есть разного рода IoT и умные дома.

                Можете себе представить разработку скажем ESB на основе JPMS? Т.е. контейнер, куда в runtime добавляются модули, запускаются, останавливаются, каждому из них нужны зависимости, которые тоже динамически устанавливаются и разрешаются (в случае карафа — например из maven репозитория). Я не вижу вообще, каким боком сюда JPMS.
                  0
                  Реальная область применимости OSGI — это куча JavaEE и ESB, которые на нем основаны.

                  А у JPMS какая?


                  Можете себе представить разработку скажем ESB на основе JPMS?

                  Вообще не очень, но может это из-за того, что я с JPMS толком не работал.

                    0
                    Ну, я для себя не нашел области применения JPMS, что впрочем не значит, что ее нет. Но она очевидно ближе к времени компиляции и сборки, т.е. направлена скорее на сборку кастомного приложения (в том числе JDK). То есть, на выходе мы получаем некий кастомный runtime+приложение.

                    Например маленький, что было бы неплохо для мобильных железок или embedded.

                    Очевидно, что к очень многим областям, которые покрывает OSGI (например, условный JNDI и вообще Java EE), и ко всей части DI (blueprint в том числе) это просто никакого отношения не имеет.
                      0
                      Очевидно, что к очень многим областям, которые покрывает OSGI, например, ко всей части DI, JPMS отношения не имеет.

                      Я тут подумал, получается, что имеет. Один из механизмов DI — java.util.ServiceLoader и он связан с модулями напрямую.

                        0
                        Ну как бы это маленькая часть всей картины. Дело в том, что скажем Pax-Web в контейнере работает так — он слушает контейнер, и ждет появления реализации интерфейса сервлета. И когда такая реализация деплоится, он ее сразу подключает, и сервлет начинает работать. Ну и где это все?
                          0
                          Связан, только нет динамизма в рантайме «из коробки». Все таки JPMS больше про модуляризацию JVM, чем про микросервисы и динамическую загрузку/выгрузку сервисов
              0
              У меня на проекте как раз микросервисная архитектура на базе jboss fuse(karaf) с хранением зависимостей фичеров в артифактори, компоненты системы на разных серваках, кластеризация и вот это все.
              Есть правда неудобство с конфигурированием профилей, не очень удобно делать это через консоль. Веб морда лагучая, hawtio тож тормозит при работе через jms. Проблему решили написав и установив бандл на корневой инстанс, работающий с сервисами фьюза напрямую.
                0
                Ну, консоль — это все-таки для ручных работ. Автоматизация — это скорее либо JMX, либо ssh. Я делал и так и эдак, в целом оба варианта рабочие.
                  0
                  Ну, я из тестирования, в итоге мы наружу ресты вывели бандлом и радуемся :)
                    +1
                    Я даже rest не стал выводить, хотя сначала тоже думал: jolokia, туда-сюда :)

                    Но поскольку все бандлы уже есть в JMX в виде MBeans, а JMX доступен по сети небольшими усилиями (ну, скажем, чтобы совсем кто попало не лазал, нужно кое-какую авторизацию и ролевую модель), то дальше берем groovy в руки, GroovyMbean, и за 15 минут прикрутил внешний мониторинг, например, с выходом на Nagios.
                +3
                Кстати, вопрос: а почему вы думаете, что микросервисы выстрелили?

                Вот пример мнения от 2016 года, тогда это не выглядело как свершившийся триумф, и мое мнение тогда практически совпадало с мнением автора.

                Понятно что условные докер или kubernetes развивались, не стояли на месте. Что-то изменилось принципиально? Какие-то из описанных тогда проблем кардинально решены?
                  0
                  я лучше отвечу, почему osgi не выстрелил. он остался нишевым продуктом.

                  что-то кроме карафа, эквинокса? spring dm примкнувший к эклипс фаундейшн там и почил, например.

                  технология не популяризуется, не обрастает удобствами в отличие от микросервисов.
                  я тыкал osgi, когда оно было только в эквиноксе, когда спрингсорс это начинание подхватил, но потом почему-то в стороночку отложил и аккуратненько забыл. Я наблюдал со стороны за этим и не видел достаточно стабильно нарастающей популярности данной технологии.
                    0
                    >что-то кроме карафа, эквинокса?
                    Полно. Умный дом, к примеру. На совсем мелких железках.

                    >spring dm примкнувший к эклипс фаундейшн там и почил, например.
                    Во-первых, вместо него Blueprint, вы просто пост не очень внимательно прочитали.

                    А сам spring dm просто живет и здравствует, потому что его работоспособность не нарушилась, и он решает все задачи, какие должен — то есть, мы берем приложение на спринге, обычное, а не DM, деплоим в караф, и о чудо — оно работает! Добавляем чуточку DM, в виде пары таглибов, и оно уже понимает сервисы карафа, или публикует свои.

                    >аккуратненько забыл.
                    Об этом и речь, что многие думают как вы. Посмотрели на технологию 10 лет назад (да, она тогда уже была), и решили, что ничего не меняется. Однако менялось. С тех пор разрабатывать под OSGI стало просто и удобно. Месяц на вход. Потом двадцать интеграций разного рода за пару лет, на куче разных механизмов.

                    Нишевая технология? Ну, с тем же успехом можно считать, что и JavaEE сегодня нишевая. По сравнению с андроид, и его масштабами по числу установок приложений — просто небо и земля. Просто мало кто пишет свои ESB-шины.
                      0
                      spring dm исчез из портфеля спрингсорса просто так, например? я не говорю, что технология сдохла. энтерпрайз (конкретно сейчас, в лице спрингсорса) от неё отвернулся. есть повод задуматься…

                      про блюпринт, не переживайте, в курсе. ему уже лет десять как… блюпринту этому…
                        0
                        >spring dm исчез из портфеля спрингсорса просто так, например?
                        Gemini Blueprint является непосредственным развитием кода spring dm, и официально рекомендуется вместо него. Он не исчез — на его основе написали другой продукт, более современный. Но при этом старый код версии аж 1.2.1, все еще успешно работает. Spring DM конечно легаси, но он никуда не делся.

                        >про блюпринт, не переживайте, в курсе.
                        Вот не похоже, чтобы вы знали его историю.

                        Так что ваши выводы в части spring неверные, и непонятно на чем основаны.
                          –1
                          Гражданин, пройдемте! Вот это список проектов, развиваемых, на данный момент, компанией спрингсорс (зачеркнуто) пивотал. Блюбёрд, гемини, принг дм? Ихтамнет!

                          А были. И ушли ровно тогда, когда они это всё отдали в эклипс. После этого проект живет на «энтузиастах опенсорса».

                          Своими комментариями я совершенно не пытаюсь предать osgi анафеме, сказать, что микросервисы — серебряная пуля, рулят и педалят и т.д.

                          Но на данный момент osgi — маргинальщина. За сим разрешите откланяться. Дальше я это усугублять не буду :)

                          P.S.: Кстати, как там r-osgi? не загнулся? :)
                            0
                            >энтерпрайз (конкретно сейчас, в лице спрингсорса) от неё отвернулся
                            Хм. Вот интересно, спрингсорс значит энтерпрайз, а я тогда кто? Мой проект был сделан по заказу FI Desk одного довольно крупного инвестиционного банка. Я и есть самый что ни на есть энтерпрайз, во всей его кровавости, разве нет? :)
                              0
                              > а я тогда кто?

                              до того, как начал размахивать — простой регистрант с хабра. а теперь надо nda перечитать на предмет разглашения названия конторы :-D
                                0
                                Не смешите. Я почти на все банки из первой десятки РФ поработал, никогда такого в NDA не было, нет, и не будет.
                          0
                          > энтерпрайз (конкретно сейчас, в лице спрингсорса) от неё отвернулся. есть повод задуматься…

                          Задумался в свое время. И пришел для себя к выводу, что произошло это потому — что всеми так разлюбимый спринг — один большой пучок рантайм-магии с кодогенерацией и рефлексией, а OSGi такие выкрутасы не любит. И вот ИМХО это — спринговый слив, а не OSGiшный.
                            0
                            надо просто у, хотя бы, одного энтерпрайза osgi в портфеле найти… Тогда можно будет начать менять это мнение :)

                            ESB — есть, микросервисы — есть. А вот osgi я что-то ни у кого не видел в портфеле.
                              0
                              Ну вот он я. Причем заметьте — ESB у меня была два раза, один раз — в виде Websphere, а второй уже караф, camel и всякие разные вариации типа Fuse. И что я могу про это сказать — что второй вариант значительно, нет ЗНАЧИТЕЛЬНО удобнее в работе. Ну то есть, я за три с половиной года примерно ни разу не пожалел о выборе именно этих технологий.
                                0
                                То что OSGi и тот же Karaf/ServiceMix — основа кучи EE-шных же контейнеров и ESB-шных же шин — не считается?
                                  0
                                  И еще, на минуточку, на OSGI работает Nexus. А значит (вероятно) и maven central. В прочем, это не точно.
                                0
                                Да дело не в этом даже. Берем свежий караф. Берем spring-dm 1.2.1. Деплоим. Работает. Скажем так — я бы не стал поднимать одновременно два контекста spring-dm и блюпринт в одном бандле. Но в целом вполне живое.

                                Ну и кого волнует тот факт, что авторы этот продукт забросили, если его функциональность как была написана много лет назад, так и остается в том же виде? Меня? Ни в малейшей степени.
                      0
                      По большому счету OSGI это средство для создания Java-приложений из модулей. Близким аналогом можно считать, например JavaEE, и в какой-то степени OSGI контейнеры могут выполнять JavaEE модули (скажем, web-приложения в виде War), а с другой стороны, многие JavaEE контейнеры содержат OSGI внутри, как средство реализации модульности «для себя». То есть, JavaEE и OSGI — это вещи похожие до совместимости, и удачно взаимодополняющие.

                      Я б поостерегся проводить такие жирные аналогии между OSGi и JavaEE. Две совершенно разные вещи что по принципам работы, что по решаемым задачам. Karaf/ServiceMix еще куда ни шло. И то они один пень они не сертифицированные EE контейнеры, никогда ими не были, и никогда оными не планировались, что тоже к проведению аналогий не располагает.


                      OSGi лежит в основе кучи EEшных контейнеров — да. Некоторый набор EEшных спек-имплементаций упакован в бандлы и доступен как фичи в Карафе — да. Но не более того.


                      А вообще, спасибо за пост. Люблю OSGi.

                        0
                        >Я б поостерегся проводить такие жирные аналогии между OSGi и JavaEE.
                        Вообще, имелась в виду в основном простая вещь — и то, и другое есть средство организации программ. Из модулей. Разные принципы и задачи? Ну так на то есть раздел про различия.

                        >Но не более того
                        Ну, я вроде и не обещал. Цель была в том, чтобы показать, что на верхнем уровне есть некоторое сходство. Насчет того, что сравнивать с JavaEE нужно например Karaf, а не OSGI — то да, тут вы вероятно правы.
                          0
                          > И то, и другое есть средство организации программ. Из модулей

                          Ну вот это я бы как раз поостерегся утверждать. По крайней мере в вводном посту к OSGi такие сравнения точно ни к чему. Эдак все подходы и парадигмы в истории на модульность можно натянуть — мол, мы класс придумали чтоб бить приложение на такие вот реюзабельные модули… А потом приходят люди и говорят «зачем мне это в 2019, когда я на микросервисах слабать тожсамое могу». А потому что нифига это не тожсамое :)
                            0
                            >Эдак все подходы и парадигмы в истории
                            Ну, по большей части вся история развития программирования — это борьба со сложностью. В том числе — в виде разбиения ее на мелкие части, и поедания слона по кусочкам.

                            И конечно они нифига не тоже самое, но это не значит, что общих целей у них совсем-совсем нет.
                        0
                        del
                          0

                          Берём OSGi, Karaf и используем это во вроде готовом пакете ServiceMix без наличия бекграунда у всей команды… огребаем от странного треша по резолву зависимостей (нигде в интернете решения проблемы найти не удалось, доки и исходники не помогли понять, как с этим бороться) и больше в сторону OSGi не смотрим. Спасибо проходили. Ни документации толковой, ни статей — найти не удалось. Дело было 3 года назад, может что и изменилось, но не верю © сами-знаете-кто.

                            0
                            Я не знаю, какой ответ вы хотели получить… проблемы ресолва зависимостей? Вы думаете, я их не видел? Да так примерно раз в неделю возникали постоянно. Ничего страшного.

                            Хотите сказать, что это я такой умный? Это лестно, разумеется (шаркает ножкой и раскланивается :), но я думаю дело все-таки не в этом. Вот скажем простой способ — форум карафа. Там вполне дружелюбный народ, который вполне себе помогает с подобными и более сложными проблемами. Так что не верю (с) — это скорее моя реплика :)
                              0

                              Просто интересно, вы сталкивались с ситуацией, когда при резолве зависимостей для модуля SM уходит в StackOverflowException? Тупо потому, что ищет среди модулей устанавливаемый модуль? Т.е. в бесконечном цикле ищет в списках установленных модулей — не находит, ещё в каких-то списках — исключая текущий устанавливаемый модуль (там он, кстати, был), потом рекурсивно вызывает эту же функцию резолва зависимостей… И так до попадания в SOE? Времени тогда разбираться особо не было, имеющеяся документация и инфа в интернете за неделю с проблемой разобраться не позволили… в итоге эксперимент выпилили и не стали с ним дальше заморачиваться.

                                0
                                Не — такого я за 3.5 года не видел. Догадываюсь, что это была бы неприятная штука. А на какой версии карафа это происходило?
                                  0
                                  Строго говоря, я ServiceMix видел только в теории — у нас либо чистый karaf (3.х), либо Fuse 6.х (тот что на карафе 2.х).
                              0
                              Очень интересно, пишем эклипс плагины, но о таком гораздо широком использовании OSGi не задумывался.
                              «OSGI это сложно» — можно ли как-то резюмировать, за счет чего сложность и что изменилось, что можно использовать чтобы с этой сложностью справиться?
                                0
                                Я бы сказал, что когда я впервые видел эквинокс, не было в первую очередь bnd плагина, который позволил построить манифест из pom, таким образом, что разработка вообще перестала отличаться от обычной.

                                Ну и во-вторую (но не по важности) собственно не было карафа. Что эквинокс, что felix, сами по себе, значительно менее удобны в работе, чем karaf.
                                0
                                sshikov, спасибо за статью!
                                Помимо прочего, Gemini Blueprint используется в Jira (Apache Felix). Хотя, очевидно, что Jira в целом использует довольно устаревший стек технологий, но разработчикам плагинов ничего не остается, кроме как разбираться в перипетиях OSGi. А данная статья весьма полезна для ознакомления с ним.
                                  0
                                  На здоровье. Только я хочу вас предупредить, что этот текст — он про караф. Это далеко не тоже самое, что феликс сам по себе. Многие вещи делаются карафом, и что у вас будет в JIRA — точно сказать могут только авторы.
                                  0

                                  sshikov, спасибо за статью, очень в нужное время.
                                  А если конфиг спринга написан на аннотациях, а не в xml?
                                  И как обстоят дела с использованием спринговых бинов из контекста одного бандла, в другом?

                                    0
                                    Насколько я помню, аннотации поддерживаются — там же внутри обычный спринг, а не что-то еще. А вот чтобы из одного бандла в другой было видно — этого нет. Экспортировать нужно явно, это как раз случай сервисов.
                                      0

                                      Явно экспортировать, это, к примеру, при помощи felix-maven-plugin?
                                      По поводу аннотаций, везде в документации карафа, да и у вас в статье тоже, фигурирует xml контекст спринга. Для меня до конца не понятно, каким образом и в какой последовательности караф деплоит бандл, какие условия должны быть осуществлены для того, что бы были удовлетворены внешние зависимости и внутренние (между бандлами) и какую роль в этом играет, например, блюпринт. Толкового материала найти не удается, про osgi вообще не слышал до предыдущего месяца. Поэтому был бы благодарен вам за информацию или полезную ссылку.

                                        0
                                        >Явно экспортировать, это, к примеру, при помощи felix-maven-plugin?
                                        Ну в том числе и так.

                                        В spring-dm есть соответствующие средства, аналогичные приведенному выше примеру для блюпринта. Ну т.е., в контексте есть бин, вы его можете экспортировать как сервис, указав, что именно экспортируется — какой-то из интерфейсов, либо класс. И задав атрибуты для последующего поиска, если нужно.

                                        >Для меня до конца не понятно, каким образом и в какой последовательности караф деплоит бандл
                                        У бандла просто есть зависимости — сервисы и пакеты. В процессе деплоя караф пытается их разрешить. На момент деплоя они либо есть, либо их нет. В зависимости от этого бандл оказывается в разном статусе. Если все обязательные зависимости разрешились — бандл можно запустить.

                                        > и какую роль в этом играет, например, блюпринт.
                                        По сути, блюпринт (и spring-dm) играет роль описания структуры бандла. Т.е. что за классы (экземпляры) в него входят, как они создаются, что импортируется и экспортируется.

                                        >Поэтому был бы благодарен вам за информацию или полезную ссылку.
                                        Есть же книжка по карафу. Вроде вполне вменяемая была.

                                        А еще я бы посоветовал посмотреть примеры в самом карафе и в camel — там тоже были проекты, где camel деплоится в караф. Они вполне несложные для начала.
                                          0

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

                                            0
                                            Вот этот туториал мне помнится довольно неплохо помог в свое время.

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

                                  Самое читаемое