пятница, 14 мая 2010 г.

Eclipse RCP: Сборка и развертывание RCP-приложения. Понятие "Продукт"


Итак, в прошлый раз мы рассмотрели понятие RCP Application и поняли, что процесс развертывания приложения вручную достаточно трудоемок. Сегодня мы поговорим о механизме, который позволяет добавить к приложению специфичные для него параметры брендинга, такие как иконки, лицензию, экран загрузки, окно приветствия и т.д. и, самое главное, создать нужную структуру каталогов, файлы конфигурации и экспортировать все бандлы, от которых зависит приложение. Такой механизм называется продуктом (product).

Проект состоит из двух частей: файла с расширением product в котором хранятся все специфичные для приложения настройки (иконки и т.д.) и точки расширения org.eclipse.core.runtime.products с помощью которой продукт регистрируется в реестре. Рассмотрим подробно создание продукта с помощью встроенного в Eclipse PDE редактора и развертывание приложения с помощью соответствующего визарда. Все примеры приведены для Eclipse Helios, запущенного под ОС Gentoo GNU/Linux.



Создать новый продукт можно из меню New -> Product configuration. В появившемся окошке следует указать каталог, в котором будет создан .product-файл, задать имя файла и указать источник информации, по которой будет сгенерирован продукт. Доступны следующие варианты:

  • Create a configuration file with basic settings - создает пустой файл конфигурации;
  • Use an existing product - создает продукт на основе уже существующего, копируя его настройки
  • Use a launch configuration - позволяет выбрать конфигурацию запуска, на основе которой будет создан продукт. Соответственно все бандлы и настройки будут в него скопированы.




Выберем первый вариант, в результате будет создан пустой файл конфигурации продукта. На вкладке Overview необходимо задать общую для продукта информацию, такую как идентификатор продукта (ID), его версию и название. Если установить флажок The product includes native launcher artifacts, то при экспорте продукта в каталог с результатом будут скопированы специфичные для системы файлы: каталог с dll/so лаунчера и файл eclipse.exe/eclipse. В блоке Product Definition необходимо указать настраиваемый продукт (т.е. идентификатор расширения, использующего точку расширения org.eclipse.core.runtime.products) и приложение, для которого продукт создается.



Если нужный продукт не существует, то можно нажать кнопку New... и указать его параметры: плагин, в котором он определен и идентификатор. Так же нужно выбрать приложение, для которого будет создан продукт. После нажатия кнопки Finish в файл plugin.xml будет добавлено расширение org.eclipse.core.runtime.products. В дальнейшем при редактировании product-файла будут автоматически вноситься изменения и в расширение.



Последнее, что нужно сделать на вкладке Overview - выбрать на чем будет базироваться конфигурация продукта: на отдельных плагинах или на фичах. Фичи (features) - специальные проекты, содержащие XML-файл в котором перечислены бандлы, их версии и указаны какие-то общие параметры, например лицензия. Семантически фича - это набор логически связанных бандлов, выступающий как единое целое. Примером фичи является org.eclipse.pde, инкапсулирующая бандлы, составляющие Eclipse Plugin Development Environment. Для простоты укажем, что наш продукт основан на отдельных плагинах.

Теперь необходимо указать эти плагины. Для этого нужно перейти на вкладку Dependencies. По-умолчанию блок Plug-ins and Fragments пуст. Заполнить его проще всего следующим образом: сначала выбираем бандлы, непосредственно составляющие наше приложение, например, бандл name.samolisov.rcp.demo:



Бандл, соответственно добавится в список:



После этого нажимаем кнопку Add Required Plug-ins. В список будут добавлены все бандлы, от которых зависят выбранные. При этом зависимости будут полностью разрешены: если наш бандл A зависит от бандла B, а бандл B - от бандла C, то добавлены будут и бандл B, и бандл C.



На вкладке Configuration настраивается конфигурация запуска. В блоке Plugi-in можно указать какой бандл должен автоматически стартовать и с каким уровнем. Для примера укажем, что бандл name.samolisov.rcp.demo будет стартовать автоматически. Так же на данной вкладке можно указать генерировать ли файл config.ini автоматически или использовать уже существующий. Причем, существующий можно задать для каждой поддерживаемой операционной системы отдельно.



На вкладке Launching задаются настройки среды исполнения и системного лаунчера. Можно выбрать среду исполнения, например CDC-1.0/Foundation-1.0. Если отметить галочку Bundle JRE for this environment with the product, то при экспорте в каталог с продуктом будет помещена и выбранная JRE. В блоке Program Launcher можно задать имя ланчера и иконки для каждой поддерживаемой платформы. Например, для Linux:



... или Windows:



В блоке Launching Arguments указываются аргументы командной строки приложения и аргументы JVM. При этом можно указывать как общие аргументы, так и специфичные для каждой операционной системы.

Вкладка Splash служит для настройки небольшого окошка без рамки, которое появляется в момент запуска приложения. Можно выбрать плагин, в котором определено данное окошко и задать источник шаблона для данного окошка. В блоке Specify the geometry and color of the progress bar and messages задается расположение прогресс-бара внутри окошка, а также сообщение, выводимое в нем.



На вкладке Branding задаются настройки главного окна приложения. Прежде всего в блоке Window Images указываются пути к иконкам разного размера, которые будут использоваться в качестве иконок главного окна. Именно их можно будет видеть, например, при переключении окон по Alt-Tab. В блоке About Dialog задается текст и путь к отображаемому в диалоге "О программе" изображению. Изображение не может иметь размер больший 500x330 пикселей, причем, если размер изображения больше 250x330 пикселей, то заданный текст выводиться не будет. Напоследок, на данной вкладке можно определить страницу приветствия, указав идентификатор соответствующего расширения. При необходимости, страницу приветствия можно создать, нажав кнопку New....



Последняя вкладка - вкладка Licensing служит для указания лицензии, под которой распространяется приложение. Можно указать как путь к файлу с лицензией, так и непосредственно ее текст. Например, текст лицензии EPL:




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



Все эти действия продублированы на вкладке Overview (см. ее скриншот выше). Замечу, что начиная с Eclipse 3.6 можно запускать приложение не только как обычное Eclipse приложение, т.е. программу для платформы RCP, но и как приложение платформы Rich Ajax Platform (RAP). С запуском приложения в RCP и валидацией бандлов все понятно, о RAP мы поговорим как-нибудь потом, а сейчас рассмотрим визард экспорта.



Данный визард состоит из нескольких блоков: Product Configuration позволяет указать файл с конфигурацией экспортируемого продукта (при необходимости его можно выбрать, нажав кнопку Browse...) и наименование корневого каталога, в который и будет осуществлен экспорт.

Блок Synchronization содержит единственную галочку Synchronize before exporting. Если она отмечена, то перед экспортом будет осуществлена синхронизация - добавление отсутствующих данных в plugin.xml, валидация бандлов и обнаружение неразрешенных зависимостей.

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

Блок Export Options содержит дополнительные настройки экспорта. Если отметить галочку Export source то будут экспортированы и исходники приложения (в зависимости от выбранного варианта - или в отдельных source-бандлах или просто добавлены в экспортируемые бандлы). Галочка Generate metadata repository указывает нужно ли генерировать метаданные для подсистемы обновления бандлов p2 и, соответственно, update-сайт для приложения. Для простоты ее можно снять. Последняя галочка - Allow for binary cycles in target platform разрешает или запрещает циклические зависимости в целевой платформе.

После нажатия на кнопку Finish начнется непосредственно экспорт, который может занимать довольно длительное время (в зависимости от количества экспортируемых бандлов). Если экспорт завершен корректно, то окошко просто закроется.


В результате будет сгенерирована стандартная для Eclipse RCP-приложений структура каталогов. В каталог configuration будет добавлен файл config.ini вот такого содержания:

#Product Runtime Configuration File

eclipse.application=name.samolisov.rcp.demo.application

osgi.bundles.defaultStartLevel=4

eclipse.product=name.samolisov.rcp.demo.product

osgi.splashPath=platform:/base/plugins/name.samolisov.rcp.demo

osgi.bundles=com.ibm.icu,name.samolisov.rcp.demo@start,org.eclipse.core.commands,org.eclipse.core.contenttype,org.eclipse.core.databinding,org.eclipse.core.databinding.observable,org.eclipse.core.databinding.property,org.eclipse.core.expressions,org.eclipse.core.jobs,org.eclipse.core.runtime,org.eclipse.core.runtime.compatibility.registry,org.eclipse.equinox.app,org.eclipse.equinox.common,org.eclipse.equinox.preferences,org.eclipse.equinox.registry,org.eclipse.help,org.eclipse.jface,org.eclipse.jface.databinding,org.eclipse.swt,org.eclipse.swt.gtk.linux.x86,org.eclipse.ui,org.eclipse.ui.workbench


Следует обратить внимание, что добавился параметр eclipse.product, указывающий идентификатор экспортируемого продукта. В корневой каталог (в нашем примере - eclipse) добавлены файлы .eclipseproduct, содержащий информацию о продукте - версию, название и идентификатор, eclipse.ini - файл, содержащий заданные параметры командной строки и ява-машины, бинарный файл eclipse, с помощью которого запускается приложение и иконка icon.xpm, которая будет использоваться некоторыми линуксовыми DE/WM для отображения ярлычков.

После запуска на исполнение файла eclipse можно наблюдать главное окно демонстрационного приложения:



Данное окошко возвещает нам, что экспорт прошел успешно и мы получили работоспособное приложение. Разработчики Eclipse создали очень простой в использовании механизм для разработки приложений на этой замечательной платформе. Некоторым может не нравиться предлагаемый подход, который я бы назвал "положись на визарды", однако при активном использовании его удобство довольно ощутимо. А как к данному подходу относитесь вы?

Понравилось сообщение - подпишитесь на блог или читайте меня в twitter

18 комментариев:

Anton комментирует...

Очень интересно, спасибо за статью. Не знал о таких удобных фичах Eclipse. Недавно сдавали проект основанный на OSGi, так по незнанию, пришлось вручную весь экспорт делать.

Bura комментирует...

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

sk комментирует...

Подход хороший, но тем ни менее у меня есть планы попытаться организовать сборку и deploy через ant скрипты, для того можно было собирать продукт и external jars, в него входящие, автоматически и из командной строки.

samurai_ комментирует...

Что же я пропустил если вижу вот такое сообщение

!SESSION 2010-07-08 14:11:44.666 -----------------------------------------------
eclipse.buildId=unknown
java.version=1.6.0_18
java.vendor=Sun Microsystems Inc.
BootLoader constants: OS=win32, ARCH=x86, WS=win32, NL=en_US
Command-line arguments: -os win32 -ws win32 -arch x86

!ENTRY org.eclipse.osgi 4 0 2010-07-08 14:11:46.479
!MESSAGE Application error
!STACK 1
java.lang.IllegalStateException: Unable to acquire application service. Ensure that the org.eclipse.core.runtime bundle is resolved and started (see config.ini).
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:74)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:369)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:619)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:574)
at org.eclipse.equinox.launcher.Main.run(Main.java:1407)

samurai_ комментирует...

А пропустил я вот что, оказывается нужно добавить во вкладке конфигурация забыл установить старт вить все те плагин которые были добавить автостарт

kirill комментирует...

Что же у меня не так?..

!SESSION 2010-07-28 21:32:53.967 -----------------------------------------------
eclipse.buildId=unknown
java.version=1.6.0_21
java.vendor=Sun Microsystems Inc.
BootLoader constants: OS=${target.os}, ARCH=${target.arch}, WS=${target.ws}, NL=${target.nl}
Command-line arguments: -os ${target.os} -ws ${target.ws} -arch ${target.arch} -consoleLog



!ENTRY org.eclipse.osgi 4 0 2010-07-28 21:32:56.811
!MESSAGE An error occurred while automatically activating bundle org.eclipse.ui.workbench (36).
!STACK 0
org.osgi.framework.BundleException: The activator org.eclipse.ui.internal.WorkbenchPlugin for bundle org.eclipse.ui.workbench is invalid
at org.eclipse.osgi.framework.internal.core.AbstractBundle.loadBundleActivator(AbstractBundle.java:156)
...
Root exception:
java.lang.NoClassDefFoundError: org/eclipse/swt/SWTError
...
!ENTRY org.eclipse.osgi 2 0 2010-07-28 21:32:57.498
!MESSAGE The following is a complete list of bundles which are not resolved, see the prior log entry for the root cause if it exists:
!SUBENTRY 1 org.eclipse.osgi 2 0 2010-07-28 21:32:57.514
!MESSAGE Bundle org.eclipse.swt.win32.win32.x86_3.6.0.v3650b [34] was not resolved.
!SUBENTRY 2 org.eclipse.swt.win32.win32.x86 2 0 2010-07-28 21:32:57.514
!MESSAGE Platform filter did not match: (& (osgi.ws=win32) (osgi.os=win32) (osgi.arch=x86))

...

Pavel Samolisov комментирует...

Судя по логу - не найден класс org.eclipse.swt.SWTError Скорее всего не подключен org.eclipse.swt (или swt-реализация под конкретную ОС). Проверьте зависимости бандла org.eclipse.ui.workbench.

kirill комментирует...

К org.eclipse.ui.workbench org.eclipse.swt подключен, фрагмент есть в запуске, но у него авто-старт фолс, я так понимаю так и должно быть, потому что не экспортированное работает.

Pavel Samolisov комментирует...

Неэкспортированное может работать, если Default-Auto-Start установлен в true.

kirill комментирует...

отключен я так понимаю для нейтральности к ос.
я перекачал (проверил мд5) и переставил еклипс.
интересует экспортированное. а обязательно добавлять в конфигурацию продукта автостарт моего плугина? ведь по дефолту его там нет.

Pavel Samolisov комментирует...

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

kirill комментирует...

помогли здесь: http://www.eclipse.org/forums/index.php?t=msg&goto=550266.

Pavel Samolisov комментирует...

Кирилл, спасибо, что поделились с нами решением. Странно, что у вас параметры командной строки не разресолвились для конкретной ОС.

Сейчас попробовал создать файл описания продукта с нуля и разресолвить зависимости. У меня специфичные для ОС параметры командной строки вообще не добавились в конфигурацию запуска.

kirill комментирует...

я добавил вручную только те параметры.
оставил при этом в all platforms как было.

а разве они должны сами добавляться ;-)?

Pavel Samolisov комментирует...

Данные параметры автоматически добавляются в конфигурацию запуска (Run AS -> Run Configurations, два раза на Eclipse Application, вкладка Arguments). Затем, если вы создаете описание продукта и в качестве значения параметра Initialize the file content укажете Use a launch configuration и вашу конфигурацию запуска, то в поле Launching arguments/Program arguments будет следующее:
-os ${target.os} -ws ${target.ws} -arch ${target.arch} -nl ${target.nl} -consoleLog

Так вот, я был не прав. Не "у вас" параметры командной строки не разресолвились, а они в принципе не ресолвятся при экспорте и записываются в eclipse.ini как есть. Можно предположить, что при запуске проекта из PDE данные параметры командной строки все же ресолвятся.

В принципе, можно зарегистрировать багу и если PDE-team сочтет, что это действительно бага - ее исправят.

adhoc комментирует...

Хотелось бы спросить у автора, знает ли он способ такого же простого экспорта для OSGi приложения. В основном интересует, как проще можно создать config.ini.

Pavel Samolisov комментирует...

Развертывание приложения, не являющегося RCP-приложением, осуществляется точно так же. Можно создать пустой класс, реализующий IApplication, "натравить" на такое "приложение" продукт и поступать так, как написано в данной статье.

adhoc комментирует...

Спасибо за интересный вариант. Также, оказывается, можно создавать product не основанный на приложении. Т.е. в поле Application выбрать пустую опцию. Правда в этом случае PDE создает plugin.xml в definine plug-in, который мне вообще не нужен.

Отправить комментарий

Любой Ваш комментарий важен для меня, однако, помните, что действует предмодерация. Давайте уважать друг друга!