Архитектура контейнера программных компонент Jaxion
А.В. Адаманский
Опубликовано: Вестник Новосибирского государственного университета, серия Информационные технологии, т.2, вып. 1., 2005 г.
Архитектура контейнера программных компонент Jaxion
Введение
В данной краткой обзорной статье, автор постарался описать некоторые архитектурные особенности контейнера программных компонентов Jaxion. А перед тем как приступить к дальнейшему описанию данной системы, уточним само понятие: «программный компонент». В дальнейшем по данным определением будет пониматься следующее:
«Компонент – это часть программного обеспечения которая может быть (пере)использована другой частью программного обеспечения в одном и том же приложении, без изменения исходного программного кода компонента.» Martin Fowler (ThoughtWorks)
Первая версия контейнера программных компонент Jaxion (http://www.jaxion.org) была разработана в рамках реализации проекта УИС (Университетская Информационная Система) – информационной системы управления высшим учебным заведением. Система УИС в настоящее время развивается и разрабатывается в Новосибирском государственном университете на базе платформы Jaxion.
В ходе работы на задачей автоматизации университета как крупного государственного предприятия, создателями проекта УИС было принято решение выделить контейнер программных приложений системы УИС как отдельный и открытый программный проект под названием Jaxion исходный код которого распространяется под лицензией Apache License 2.0.
-
Jaxion предоставляет разработчику набор слабо связанных программных Java™/Java™ EE сервисов – многократно используемых (reusable) компоновочных блоков на основе которых строятся модульные программные приложения, а также высокоуровневую среду для выполнения произвольных программных компонент.
-
Декларативное задание зависимостей между компонентами и автоматическое их удовлетворение контейнером, реализация принципа Dependency Injection в отношении развертываемых программных компонент, дает возможность разработчику соединить в одну целостную систему совершенно разнородные программные модули и библиотеки.
-
Архитектура Jaxion позволяет организовать распределенное и в тоже время прозрачное взаимодействие программных компонент в контексте географически разнесенных экземпляров контейнера компонент.
-
Данная система не обязывает привязывать код развертываемых компонент к среде выполнения Jaxion, иными словами, на развертываемые компоненты не накладывается никаких строгих ограничений на интерфейсы и методы которые они должны реализовать для работы в Jaxion. Большинство программных компонент развертываемых в Jaxion является простыми POJO (Plain Old Java Object) объектами.
-
Набор Java™ EE компонент предоставляющих готовые сервисы, в том числе:
-
-
Менеджер транзакций уровня приложения, согласно JTA (Java™ Transaction API)
-
-
-
Встроенный контейнер сервлетов: Jakarta Tomcat 5.5
-
Встроенный программный уровень для сохранения Java объектов: Hibernate (2.1, 3.1)
-
Встроенная система для управления бизнес процессами: JBPM (2.0)
-
Механизм развертывания программных компонент
Под развертыванием компонента понимается процесс внедрения/введения некоторого программного компонента (экземпляра Java класса/классов) в работающую программную систему на платформе Jaxion, при этом, в системе анонсируются интерфейсы развертываемого программного компонента и выполняются все программные зависимости относительно развертываемого компонента.
Jaxion позволяет развертывать в качестве программного компонента любой POJO объект, т.е. имеется возможность развертывать компоненты (java объекты) которые могут быть вообще не связаны никакими программными контрактами (интерфейсами) с сервером Jaxion.
Однако в контексте контейнера Jaxion на каждый программный компонент все же наложены некоторые контрактные обязательства, как например возможность перехода компонента в одно из следующих пяти базовых состояний (схема 2):
-
Компонент не активен, выключен (состояние NOT_ACTIVE)
-
Компонент готовится стать активным, инициализируется (состояние PRE_ACTIVE)
-
Компонент является активным и может принимать и обрабатывать программные вызовы (состояние ACTIVE)
-
Компонент готовится стать неактивным, и производит освобождение своих внутренних ресурсов (состояние PRE_NOT_ACTIVE)
-
Компонент находится в состоянии сбоя (состояние FAILED)
и в произвольный набор подсостояний. Как же в таком случае мы достигаем возможности развертывать произвольные POJO объекты в системе где от них все же требуются базовые контрактные связи/обязательства с контейнером Jaxion ? Проблема решается применением методов аспектно-ориентированного программирования при развертывании компонента которые расширяют его функциональность для того чтобы он стал удовлетворять контрактным обязательствам которые на него налагаются.

Схема 1: Расширение функциональности развертываемых компонент
при помощи AOP сервисов
Как это достигается показано на схеме 1, где слева на право представлена последовательность следующих действий на компонентом:
-
Программный компонент описан в его дескрипторе развертывания – файле где задается java класс компонента, параметры его развертывания, программный интерфейс который будет анонсирован при развертывании компонента.
-
Далее загрузчик компонента проверяет реализует ли компонент явно те программные интерфейсы которые определяют его системный контракт с контейнером Jaxion (в том числе и интерфейс жизненного цикла компонента: LifeCycleComponent). Если компонент является POJO объектом, т.е. не реализует контрактные интерфейсы, то системой производится модификация байт кода java класса компонента – внедрение AOP перехватчиков (AOP interceptors). AOP перехватчики необходимы для того чтобы снабдить развертываемый компонент программной логикой по умолчанию, которая выполняет требуемые от компонента контрактные обязательства.
-
Далее компонент развертывается в контейнере и при необходимости меняет свое состояние на активное (ACTIVE), становясь доступным для вызовов извне методов его интерфейса.
При этом разработчик программного компонента имеет возможность как явно реализовать контрактные интерфейсы Jaxion переопределив их поведение по умолчанию, так и использовать произвольные POJO объекты, в т.ч. и программные компоненты из третьих источников не предназначенных явно для системы Jaxion.
Зависимости компонент относительно их состояний и событий
Каждый компонент развертываемый в Jaxion характеризуется видимым извне собственным состоянием, состояние компонента является композитным и состоит из базового состояния (набор базовых состояний четко определен в системе), произвольного подсостояния и текстового описания состояния. Как уже бало упомянуто выше компонент может находится в пяти базовых состояниях, возможные переходы между базовыми состояниями показаны на схеме 2. Разработчик компонента имеет возможность переопределять поведение компонента в зависимости от его текущего состояния, вводить новые производные подсостояния, организовывать зависимости между компонентами относительно их состояний. И это позволяет строить достаточно нетривиальные зависимости между компонентами, привязывать компоненты друг к другу по времени жизни, транзитивно/каскадно изменять состояния зависимых компонентов.

Схема 2: Диаграмма переходов между базовыми состояниями программного компонента
Зависимости между компонентами задаются декларативно в их дескрипторах развертывания, рассмотрим небольшой пример на листинге 1 для того чтобы наглядно это продемонстрировать.
Заметим что на листинге применяется следующая нотация для задания шаблона состояния: {состояние, подсостояние, комментарии}, с помощью которой можно представить базовое состояние и подсостояния компонента в виде строки.
1 <deployment-descriptor> 2 ... 3 <component name="name=SlaveDepBean1" ...> 4 ... 5 <depends-on jmxName="test:name=Master1DepBean" 6 alias="MasterDepBean"> 7 <state name="{ACTIVE, *, *}"> 8 <call-method name="changeJXState"> 9 <param value="{ACTIVE, *, *}" type="state"/> 10 </call-method> 11 </state> 12 </depends-on> 13 ... 14 <depends-on ...> 15 ... 16 </depends-on> 17 </component> 18 </deployment-descriptor>
Листинг 1: Пример зависимостей компонентов по состоянию
Зависимость представленная выше, определяет следующее.: При переходе компонента с именем test:name=Master1DepBean в базовое состояние ACTIVE из любого другого отличного от ACTIVE
базового состояния, контейнер Jaxion должен вызвать метод changeJXState() у зависимого компонента с именем test:name=SlaveDepBean1 передав ему в качестве параметра объект характеризующий состояние (и тем самым изменив состояние зависимого компонента) В данном случае подсостояния и описание подсостояний игнорируются при помощи символа * в шаблонах состояний.
Как показала практика, описанный выше декларативный способ задания зависимостей по состоянию между программными компонентами, а также принятая модель состояний является достаточно удобным способом синхронизации программных компонентов.
Аспектно – ориентированные сервисы
Контейнер программных компонентов Jaxion дает возможность программисту избирательно настроить AOP перехватчики на методы определенных программных компонент, тем самым позволяя динамически переопределить или дополнить поведение компонент. В частности, в системе УИС, перехватчики AOP используются для проведения транзакций уровня приложения во время вызовов методов программных компонент.
Перспективы и дальнейшее развитие проекта Jaxion
В дальнейшем, при работе над Jaxion, было бы любопытно более подробно исследовать особенности поведения системы программных компонент в рамках принятой модели базовых состояний и подсостояний вводимых для компонент, применив для этого формальные математические методы исследования поведения дискретных систем.
Что же касается развития функциональности представленного контейнера Jaxion, то данный проект в настоящее время развивается в сторону большей поддержки основных JavaEE стандартов, как например, ведется работа по внедрению поддержки JCA (Java ™EE Connector Architecture) архитектуры что позволит стандартным образом включать в него целый спектр библиотек для доступа к разнообразным типам информационных ресурсов.
Статьи
Требуются сотрудники
География клиентов