Наши партнеры

UnixForum





Библиотека сайта rus-linux.net

Среда разработки Eclipse

Глава 6 из книги "Архитектура приложений с открытым исходным кодом", том 1.

Оригинал: Eclipse, глава из книги "The Architecture of Open Source Applications" том 1.
Автор: Kim Moir
Перевод: Н.Ромоданов

6.2. Eclipse 3.0: Среда времени выполнения, RCP и роботы

6.2.1. Среда времени выполнения

Eclipse 3.0 был, вероятно, одним из самых важных релизов проекта Eclipse благодаря ряду существенных изменений, которые произошли в течение этого цикла выпуска. В архитектуре Eclipse, которая предваряла версию 3.0, компонентная модель Eclipse состояла из плагинов, которые могли взаимодействовать друг с другом двумя способами. Во-первых, зависимости между ними могли быть выражены при помощи инструкции requires в файлах plugin.xml. Если плагину A требуется плагин B, то плагин A может видеть все Java классы и ресурсы из B, учитывая, конечно, соглашения о видимости классов языка Java. Каждый плагин имел версию, так что также можно было указывать версии зависимостей. Во-вторых, компонентная модель предлагала использовать расширения и точки расширения. Исторически сложилось, что разработчики, использующие Eclipse, написали свою собственную среду выполнения для Eclipse SDK, которая управлялае загрузкой классов, зависимостями плагинов и расширениями и точками расширений.

Проект Equinox был создан как новый инкубационный проект в рамках Eclipse. Целью проекта Equinox была замена компонентной модели Eclipse тем, что уже существовало, а также возможность обеспечить поддержку динамических плагинов. Среди рассматриваемых решений были JMX, Jakarta Avalon и OSGi. JMX не была полностью разработанной компонентной моделью и поэтому было решено, что ее использовать нецелесообразно. Jakarta Avalon не был выбран потому, что, как оказалось, он уже перестал существовать как проект. В дополнение к техническим требованиям, также было важно учитывать сообщество, которое поддерживает конкретную технологию. Будет ли сообщество готооы принять изменения, связанные с Eclipse? Готовы ли оно активно развиваться и расширяться в новых условиях? Команда разработчиков Equinox понимала, что сообщество, сгруппировавшееся вокруг технологии, которую они в конце концов выберут, столь же важно, как и технические соображения.

После исследования и оценки имеющихся альтернатив, разработчики выбрали проект OSGi. Почему проект OSGi? В нем была семантическая схема именования версий, используемая для управления зависимостями. Это позволяло воспользоваться модульным фреймворком, которого не хватало в самом JDK. Пакеты, которые предоставлялись для других сборок, должны были явно экспортироваться, а все остальные пакеты были скрыты. В OSGi был свой собственный загрузчик классов, поэтому команде разработчиков Equinox не требовалось продолжать поддерживать свои собственные загрузчики. Благодаря тому, что была стандартизирована компонентная модель, распространение которой не ограничивалось только экосистемой Eclipse, было понятно, что можно было обращаться к более широкой аудитории, и шире распространять проект Eclipse.

Команда разработчиков Equinox чувствовала себя уверенно, т. к. у проекта OSGi уже было энергичное сообщество; и они могли работать с этим сообществом, что помогло добавить функциональные возможности компонентной модели, необходимые проекту Eclipse. Например, на тот момент в OSGi поддерживались требования делать перечисления свойств на уровне пакетов, а не на уровне плагинов, как это требовалось в Eclipse. Кроме того, в OSGi на тот момент еще не использовалась концепция фрагментов, которая в Eclipse являлясь предпочтительным механизмом добавления кода, специфического для конкретной платформы или среды окружения, в существующий плагин. Например, фрагменты кода, предоставляемые для работы в файловых системах Linux и Windows, а также фрагменты, предназначенные для трансляции на другие языки. Как только было принято решение в качестве новой среды выполнения начать использовать OSGi, разработчикам потребовалась реализация фреймворка с открытым исходным кодом. Был проанализирован проект Oscar, который был предшественником проекта Apache Felix, а также фреймворк управления сервисами Service Management Framework (SMF), разработанный фирмой IBM. На тот момент Оскар был исследовательским проектом с ограниченными возможностями внедрения. В конечном итоге был выбран проект SMF, т.к. он уже использовался в поставляемых изделиях и, таким образом, был признан в качестве используемого в среде уровня предприятиями. За эталонную реализацию спецификации OSGi была взята реализация Equinox.

Был также реализован слой совместимости, так что в версии 3.0 по-прежнему должны работать уже существующие плагины. Просить разработчиков переписать их плагины согласно изменениями в базовой инфраструктуре Eclipse 3.0 было бы для проекта Eclipse, как инструментальной платформы, импульсом в направлении тупика. По ожиданиям разработчиков, использующих Eclipse, платформа должна просто продолжать работать.

С переходом на OSGi, плагины Eclipse стали еще называться сборками. Плагин и сборка являются одним и тем же: они оба обеспечивают модульное подмножество функциональных возможностей, которое описывается с помощью метаданных в манифесте. Раньше зависимости, экспортируемые пакеты и расширения, а также точки расширения описывались в файле plugin.xml. С переходом на сборки OSGi, описания расширений и точек расширений продолжали указываться в файле plugin.xml, поскольку они относятся к понятиям проекта Eclipse. Остальная информация описывалась в файле META-INF/MANIFEST.MF, т. е. в манифесте сборки версии OSGi. Чтобы поддержать такое изменение, в PDE был предоложен новый редактор манифестов для использования внутри Eclipse. Каждая сборка имеет имя и версию. Манифест для сборки org.eclipse.ui выглядит следующим образом:

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %Plugin.name
Bundle-SymbolicName: org.eclipse.ui; singleton:=true
Bundle-Version: 3.3.0.qualifier
Bundle-ClassPath: .
Bundle-Activator: org.eclipse.ui.internal.UIPlugin
Bundle-Vendor: %Plugin.providerName
Bundle-Localization: plugin
Export-Package: org.eclipse.ui.internal;x-internal:=true
Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.2.0,4.0.0)",
 org.eclipse.swt;bundle-version="[3.3.0,4.0.0)";visibility:=reexport,
 org.eclipse.jface;bundle-version="[3.3.0,4.0.0)";visibility:=reexport,
 org.eclipse.ui.workbench;bundle-version="[3.3.0,4.0.0)";visibility:=reexport,
 org.eclipse.core.expressions;bundle-version="[3.3.0,4.0.0)"
Eclipse-LazyStart: true
Bundle-RequiredExecutionEnvironment: CDC-1.0/Foundation-1.0, J2SE-1.3

Начиная с Eclipse 3.1, в манифесте также можно определять среду выполнения, необходимую для работы сборки (bundle required execution environment - BREE). Среда выполнения указывалась как минимальная среда Java, необходимая для работы сборки. Компилятор Java не умеет разбираться в сборках и манифестах OSGi. В PDE есть инструментальные средства для разработки сборок OSGi. Поэтому PDE выполняет анализ манифеста сборки и создает для этой сборки путь classpath. Если вы в своем манифесте указали в качестве среды исполнения среду J2SE-1.4, а затем написали код, в котором есть обобщенные типы generic, то вам будет предложено исправить ошибки кода. Тем самым гарантируется, что ваш код соответствует контракту, указанному в манифесте.

В OSGi предоставляется модульный фреймворк для языка Java. Фреймворк OSGi осуществляет управление коллекциями самодокументированных сборок и загрузкой их классов. В каждом пакете есть свой собственный загрузчик классов. Путь classpath, используемый в сборке, строится путем проверки зависимостей, указанных в манифесте, и собственно генерации пути classpath. Приложения OSGi являются коллекциями сборок. Для того, чтобы в полной мере воспользоваться модульностью, вы должны уметь выразить зависимости вашего приложения в виде, понятном для потребителей. Поэтому в манифесте описываются экспортируемые пакеты, доступные для клиентов этой сборки, которые представляют собой общедоступный интерфейс API, предоставляемый для использования. В сборке, в которой используется этот интерфейс API, должен быть соответствующий импорт используемых пакетов. Манифест также позволяет вам указать диапазоны версий ваших зависимостей. Взгляните на инструкцию Require-Bundle, которая имеется в приведенном выше манифесте, и обратите внимание на то, что сборка org.eclipse.core.runtime, от которой зависит org.eclipse.ui, должна иметь версию не меньше, чем 3.2.0 и не больше, чем 4.0.0.

Рис.6.4: Жизненный цикл сборки OSGi

OSGi является динамическим фреймворком, который поддерживает установку, запуск, остановку и удаление сборок. Как упоминалось ранее, одним из основных преимуществ Eclipse является ленивая или отложенная активация, когда классы плагинов не загружаются до тех, пока они не становятся необходимыми. Жизненный цикл сборок OSGi также позволяет использовать этот подход. Когда вы запускаете приложение OSGi, сборки находятся в состоянии installed или «установлено». Если зависимости сборки разрешены, то сборка переходит в состоянии resolved или «зависимости разрешены». Как только зависимости будут разрешены, классы, находящиеся внутри этой сборки, могут загружаться и выполняться. Состояние starting или «запуск» означает, что сборка активизируется в соответствии с ее политикой активации. После того, как сборка активирована (т. е. находится в состоянии activate), она находится в состоянии active или «активном» состоянии и может запрашивать необходимые ресурсы и взаимодействовать с другими сборками. Сборка находится в состоянии stopping или «остановлено», когда выполняется метод stop ее активатора с тем, чтобы освободить все ресурсы, которые были открыты, когда сборка была активной. Наконец, сборка может быть «удалена» (т. е. находиться в состоянии uninstalled), а это значит, что она будет недоступна для использования.

Т.к. интерфейс API развивается, то нужен способ сообщать потребителям вашего API об изменениях. Один подходов состоит в использовании семантической схемы именования версий ваших сборок и указания в манифестах диапазонов версий для вашей зависимости. В OSGi используется схема именования версий, имеющая четыре части и показанная на рис.6.5.

Рис.6.5: Схема именования версий

В схеме нумерации версий OSGi, каждая сборка имеет уникальный идентификатор, состоящий из имени и четырех частей номера версии. Идентификатор и версия являются вместе для потребителя уникальным набором байтов. Согласно правилам Eclipse, если вы делаете изменения в сборке, то каждая часть номера версии будет указывать потребителям вид сделанных изменений. Таким образом, если вы хотите указать, что вы намереваетесь изменить API, вы на единицу увеличиваете первую (major) часть номера версии. Если вы просто расширили API, вы увеличиваете на единицу вторую часть (minor) номера версии. Если вы исправили небольшую ошибку, которая не влияет на API, то на единицу увеличивается третья часть (service) номера версии. Наконец, когда на единицу увеличивается четвертая часть номера (qualifier), то он указывает на новый идентификатор собранного варианта или тег репозитория с исходным кодом.

Кроме возможности определять фиксированные зависимости между сборками, в OSGi также есть механизм, называемый сервисами, который позволяется реализовывать дополнительную развязку между сборками. Сервисами являются объекты с набором свойств, которые регистрируются в реестре сервисов OSGi. В отличие от расширений, которые регистрируются в реестре расширений в тот момент, когда Eclipse сканирует сборки при запуске, сервисы регистрируются динамически. В сборку, в которой используется сервис, нужно импортировать пакет, определяющий сервис-контракт, а фреймворк определяет реализацию сервиса, взятого из реестра сервисов.

Есть определенное приложение, предназначенное для запуска Eclipse, которое похоже на метод main в файле классов Java. Приложения Eclipse определяются с помощью расширений. Например, приложением для запуска самого Eclipse IDE является приложение org.eclipse.ui.ide.workbench, которое определено в сборке org.eclipse.ui.ide.application.

<plugin>
    <extension
         id="org.eclipse.ui.ide.workbench"
         point="org.eclipse.core.runtime.applications">
      <application>
         <run
               class="org.eclipse.ui.internal.ide.application.IDEApplication">
         </run>
      </application>
  </extension>
</plugin>

Есть много приложений, предоставляемых в Eclipse, например, приложения для автономного запуска серверов подсказки, выполнения задач Ant и тестов JUnit.

6.2.2. Платформа Rich Client Platform (RCP)

Одна из самых интересных особенностей, касающаяся работы в сообществе, использующим открытый исходный код, состоит в том, что программы могут применяться совершенно неожиданным образом. Первоначальным назначением проекта Eclipse было предоставление платформы и инструментальных средств, позволяющих создавать и расширять различные IDE. Однако к тому времени, когда был выпущен релиз 3.0, по отчетам об ошибках стало ясно, что сообщество взяло некоторое количество сборок, предназначенных для разработки платформы, и использовало их для сборки многофункциональных приложений Rich Client Platform (RCP), которые многие рассматривают как приложения на языке Java. Т.к. первоначально Eclipse был ориентирован на создание IDE, то для того, чтобы новый вариант применения мог был проще воспринят сообществом, потребовался определенный рефакторинг проекта. В приложениях RCP не требуются все функциональные возможности, которые нужны в IDE, так что некоторые сборки были разделены на более мелкие, которые могут использоваться сообществом при построении приложений RCP.

Примерами приложений RCP, используемых в реальных условиях, является применение платформы RCP для мониторинга роботов-марсоходов, разработанных НАСА в лаборатории Jet Propulsion Laboratory, использование проекта Bioclipse для визуализации данных биоинформатики и использование проекта Dutch Railway для мониторинга загруженности поездов. Общая мысль, проходящая через многие из этих приложений, заключается в том, что эти команды разработчиков решили, что могут взять утилиты, предлагаемые платформой RCP, и сконцентрироваться на создании своих специальных инструментальных средств, работающих поверх этих утилит. Они могут сэкономить время разработки и деньги благодаря тому, что могут сосредоточиться на создании своих инструментальных средств на базе платформы со стабильным интерфейсом API, что гарантирует, что технологии, выбранные ими, будут поддерживаться достаточно долго.

Рис.6.6: Архитектура Eclipse 3.0

Если вы посмотрите на архитектуру 3.0, приведенную на рис.6.6, то увидите, вы заметите, что для поддержки модели приложений и реестра расширений все еще присутствует среда времени выполнения Eclipse Runtime. Управление зависимостями между компонентами, т. е. Управление моделью плагинов, в настоящее время происходить при помощи OSGi. Кроме того, что пользователи могут продолжать расширять Eclipse с целью создания своих собственных сред разработки, они также могут на базе фреймворка приложений RCP собирать приложения более общего назначения.


Продолжение статьи: Eclipse 3.4.