Проблемы и особенности разработки модульных приложений на Java
Программное обеспечение Программное обеспечение

Если необходимо разработать модульную архитектуру на языке Java, поможет OSGi (Open Services Gateway Initiative

Главная>Программное обеспечение>Разработка модульных приложений на Java
Программное обеспечение Тема номера

Разработка модульных приложений на Java

Дата публикации:
14.09.2016
Посетителей:
1168
Просмотров:
1017
Время просмотра:
2.3

Авторы

Автор
Роман Кичасов В прошлом - архитектор отдела разработки Центра программных решений компании «Инфосистемы Джет»
Общеизвестно, что в языке программирования Java отсутствует поддержка модульности. Эта проблема была замечена давно, предпринимались неоднократные попытки исправить ситуацию. Речь в первую очередь идет о проекте Jigsaw.

 

 

Jigsaw puzzle – составная картинка-загадка (головоломка, в которой нужно сложить отдельные кусочки, чтобы получилась картинка). Каждый кусочек (модуль) соединяется с другими (посредством интерфейсов), чтобы получилась законченная картинка (программное обеспечение).

 

Сначала планировалось добавить поддержку модульности в Java 7 (2011 год), потом в Java 8 (2014 год), наконец, было анонсировано, что Jigsaw станет частью Java 9 (2017 год). На момент подготовки статьи 3 последние заметки в персональном блоге главного архитектора Java Марка Рейнхолда были посвящены как раз внесению модульности в Java.

 

Так что же такое модульность, какие преимущества дает модульная архитектура ПО и что делать до появления Java 9? Модульная архитектура программного обеспечения – это подход к разработке, при котором программа разбивается на независимые компоненты, которые могут взаимодействовать между собой посредством четко описанных контрактов. Эти компоненты – модули – должны обладать несколькими признаками. Первый – инкапсуляция (они должны скрывать свою реализацию от внешнего окружения), второй – слабая связность (модули взаимодействуют только с помощью заранее оговоренных контрактов), третий – динамичность (возможность замещаться «на лету», без необходимости остановки всего приложения).

OSGi

 

Что делать, когда стоит задача разработать по-настоящему модульную архитектуру на языке Java? На помощь приходит OSGi (Open Services Gateway Initiative) – спецификация динамической модульной системы и сервисной платформы для Java-приложений, разрабатываемая OSGi Alliance. Спецификация описывает такую модель разработки ПО, при которой компоненты обладают всеми тремя описанными выше признаками. Основой концепции OSGi являются 2 сущности: наборы (Bundles) и сервисы (Services).

 

Наборы OSGi

При разработке ПО на Java, как правило, используются сторонние библиотеки. В мире Java библиотеки упаковываются в специальные файлы с расширением JAR (Java ARchive). Это обычный ZIP-архив, в котором находятся Java-классы (файлы с расширением .class). При этом использование библиотек может быть сопряжено с определенными сложностями.

 

Как только вы начинаете использовать какую-либо библиотеку в своем приложении, вам, как правило, становятся доступны все классы в этой библиотеке. Дело в том, что разработчики библиотек не имеют возможности спрятать классы, которые используются для реализации их внутренней логики. Таким образом, если вы используете код, который не предполагался для применения вне библиотеки, вы можете столкнуться с несовместимостью при использовании новой версии библиотеки или нарушить ее корректное функционирование.

 

Еще одной проблемой является так называемый JAR Hell. Многие разработчики сломали об него немало копий. Суть состоит в том, что как только у вас в проекте начинают использоваться разные версии одной и той же библиотеки (как правило, это большие проекты, которые эволюционируют со временем), вы можете столкнуться с ситуацией, когда один и тот же класс имеет разные методы в разных версиях библиотеки. Java же устроена так, что будет использована первая версия библиотеки, которую найдет загрузчик классов. Тем самым, обратившись в коде к какому-либо классу во время выполнения программы, вы получите ошибку, что метод, к которому вы обращаетесь, не существует. Связано это с тем, что на этапе выполнения Java ничего не знает о версии библиотеки, которая должна использоваться в том или ином случае.

 

Стоит отметить, что разработчики OSGi решили не изменять структуру JAR-файлов для обеспечения модульности, а просто добавили в них дополнительную информацию, которая используется средой OSGi. Более того, эта дополнительная информация никак не влияет на использование JAR-файлов в обычных Java-приложениях. Итак, чтобы JAR-файл стал OSGi-набором, в него добавляются данные, которые определяют, какие пакеты данного набора доступны для использования вне его (Export-Package) и какие пакеты других наборов требуются для работы этого набора (Import-Package). При этом возможно задать как версию API, которую набор предоставляет для других наборов, так и версию или диапазон версий API, которые набор требует для своей работы от них же. Все классы набора, которые не находятся в его экспортируемой секции, не доступны вне набора (Private). Таким способом OSGi-набор выполняет требование слабой связности.

 

Сейчас большинство Java-библиотек уже являются OSGi ready, т.е. содержат информацию для возможности выполнения в OSGi-контейнере. Также существует множество инструментов и утилит, которые позволяют создать из обычных JAR-файлов модули для OSGi.

 

Рис. 1. Импорт/экспорт пакетов в OSGi-наборах


 

 

Так как зависимости между наборами и интерфейсы, предоставляемые этими наборами, имеют четкие версии, среда выполнения OSGi позволяет легко избегать ситуаций JAR Hell, которые мы описали выше.

 

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

 

Сервисы OSGi

Итак, имея OSGi-наборы, мы можем разрабатывать модульные приложения, которые взаимодействуют посредством интерфейсов (API). Возникает вопрос: где взять класс, который реализует требуемый интерфейс? Добавить такой класс в API набора – плохое решение, т.к. в рамках модульной архитектуры мы договорились не использовать внутренние классы наборов вне этих наборов. Можно было бы использовать шаблон «фабрика» для реализации интерфейса и добавить его в API набора, но разрабатывать каждый раз новый класс для сокрытия реализации интерфейса тоже кажется не лучшей идеей.

 

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

 

Рис. 2. Публикация OSGi-сервиса в реестр сервисов. Получение опубликованного OSGI-сервиса из реестра сервисов


 

 

Микросервисная архитектура в виртуальной машине Java

 

Некоторое время назад микросервисная архитектура наделала много шума в ИТ-сообществе. Особенно бурно ее стали обсуждать после того, как признанный гуру Мартин Фаулер в соавторстве с Джеймсом Льюисом опубликовал статью «Microservices», в которой подробно рассмотрел преимущества разбиения монолитной архитектуры на набор независимых модулей. Каждый из таких модулей представляет собой отдельное приложение. Каждое приложение разрабатывается и развертывается независимо от других. Взаимодействие же между модулями происходит посредством четко определенных интерфейсов с использованием легковесных протоколов (REST, Protocol Buffers, MQ и т.д.). По факту каждый модуль – это микросервис, который выполняет одну определенную задачу и, как правило, содержит минимальное количество кода. Преимуществами такого подхода к разработке ПО являются:

 

  • Легкость (при разработке микросервиса выполняется реализация всего лишь одной конкретной части функциональности. При этом нет нужды беспокоиться о других частях программы).
  • Простота замены (если вы решите, что в текущей реализации сервис не справляется со своей задачей, вы легко можете переписать его и заменить на новую версию без какого-либо влияния на другие части программы. Более того, без остановки текущего ПО).
  • Повторное использование (т.к. микросервис выполняет одну маленькую задачу, он может многократно использоваться там, где это необходимо).

 

Как видно из описания выше, разработчики модульных приложений с применением OSGi давно пользуются всеми преимуществами микросервисной архитектуры, но только в рамках виртуальной машины Java. Каждый набор с OSGi, который публикует сервис в реестр, является микросервисом внутри Java Virtual Machine, JVM (в мире OSGi такие микросервисы называются µServices).

 

Red Hat JBoss Fuse

Мы в Центре программных решений используем все преимущества OSGi при разработке ПО для телеком-операторов, страховых, процессинговых компаний. Для этого мы применяем продукт Red Hat JBoss Fuse, а конкретно его конфигурацию Fuse Fabric. Платформа JBoss Fuse предоставляет гибкую OSGi-среду для выполнения модульного приложения.

 

Сегодня к ПО предъявляются такие требования, как непрерывность работы, возможность легкого горизонтального масштабирования, простота развертывания и наличие средств управления кластером для кластерного ПО. Fuse Fabric решает эти задачи. Технология позволяет развернуть несколько экземпляров Red Hat JBoss Fuse и объединить их в кластер, а также предоставляет централизованный инструмент управления получившейся средой.

 

В рамках Fuse Fabric существуют следующие абстракции:

 

  • Фичи (features) – совокупность OSGi-наборов, которые реализуют какой-либо функционал.
  • Профили (profiles) – совокупность фич, которые должны выполняться в рамках одного контейнера, и конфигурационные настройки для наборов, которые входят в фичу.
  • Контейнеры (containers) – отдельные JVM-процессы, которые выполняются на конкретном узле кластера Fuse Fabric под управлением контейнера Red Hat JBoss Fuse.

 

Рис. 3. Иерархия сущностей в Fuse Fabric

 

 

Таким образом, любое ПО, которое строится на технологии Fuse Fabric, состоит из OSGi-наборов, которые группируются в фичи и развертываются в рамках какого-либо отдельного JVM-процесса на одном или нескольких узлах кластера в соответствии с заранее заданным профилем.

 

Среда Fuse Fabric содержит множество инструментов, которые позволяют легко управлять полученным кластером. Мы можем создавать профили, на основе профилей создавать контейнеры, создавать/удалять/запускать/останавливать контейнеры на любом хосте, который входит в кластер, подключать новые узлы кластера и т.д. И все эти действия мы можем выполнять online, т.е. без прерывания функционирования остальных узлов кластера. Среда поддерживает возможность хранения нескольких версий профилей, фич, OSGi-наборов.

 

В полученной среде OSGi-наборы могут взаимодействовать не только в рамках одного контейнера, но и вызывать друг друга в рамках разных контейнеров (даже в рамках различных хостов). Эту возможность обеспечивает технология Distributed OSGi. Дополнительно – при минимальных затратах на разработку – каждый сервис, который предоставляет OSGi-набор, можно превратить в REST/web-сервис, который можно вызывать из внешних систем.

 

Таким образом, используя Fuse Fabric, мы можем создавать микросервисную архитектуру, которая поддерживает простоту настройки и развертывания, изолированное выполнение сервисов в рамках своих JVM-процессов (со своими специфичными настройками, например, разными настройками сборщика мусора), при этом сервисы взаимодействуют между собой по сети с использованием легковесного протокола.

 

Т.к. продукт Red Hat JBoss Fuse основан на Open Source стеке технологий Apache ServiceMix, в нашем распоряжении есть такие мощные технологии, как Apache ActiveMQ (реализация спецификации JMS), Apache Camel (реализация шаблонов проектирования корпоративных приложений), Apache CXF (библиотека для разработки REST/web-сервисов), Blueprint (предоставляет возможности внедрения зависимостей), Spring и т.д. Поскольку указанные технологии бесшовно интегрируются между собой в Red Hat JBoss Fuse, это значительно снижает время разработки требуемого функционала.

Уведомления об обновлении тем – в вашей почте

Java как центр архипелага

Когда говорят и пишут о Java, самой популярной фразой является "мир сошел с ума". Действительно, и скорость, и характер распространения (так и хочется вспомнить лексикон недавнего прошлого и сказать о "победном шествии") Java не имеют аналогов. При ...

"Дозор-Джет" на операционной системе Red Hat Enterprise Linux для средних и малых предприятий

Линейка продуктов "Дозор-Джет" предназначена для защиты корпоративных сетей от рисков, связанных с доступом в Интернет.

Компонентная объектная модель JavaBeans

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

Java-технология как средство создания современных корпоративных систем

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

Коротко о главном

За последние пару лет многое в мире в целом и в сфере ИТ, в частности, претерпело значительные изменения. Сервисный центр (СЦ) компании «Инфосистемы Джет» также никогда не останавливается в своем развитии, предлагая самые востребованные на рынке решения, которые соответствуют наиболее актуальным тенденциям сферы ИТ.

На пути к управляемым информационным системам

Управление информационными системами, как термин, имеет множество определений, в зависимости от того, что считать объектом и функциями управления. Разнообразие мнений и подходов велико, поэтому управление является одной из самых «идейных» ...

Спасибо!
Вы подписались на обновления наших статей
Предложить
авторский материал





    Спасибо!
    Вы подписались на обновления наших статей
    Подписаться
    на тему







      Спасибо!
      Вы подписались на обновления наших статей
      Оформить
      подписку на журнал







        Спасибо!
        Вы подписались на обновления наших статей
        Оформить
        подписку на новости







          Спасибо!
          Вы подписались на обновления наших статей
          Задать вопрос
          редактору








            Оставить заявку

            Мы всегда рады ответить на любые Ваши вопросы

            * Обязательные поля для заполнения

            Спасибо!

            Благодарим за обращение. Ваша заявка принята

            Наш специалист свяжется с Вами в течение рабочего дня