В статье на прошлой неделе мы увидели, как быстро перейти с нуля к работающим OSGi-пакетам с помощью Pax Construct. Мы только коснулись поверхности Pax Construct, и мы рассмотрим это еще в следующей статье. Однако на этой неделе мы собираемся раскрыть магию, лежащую в основе скрипта Pax Construct: Pax Runner.
OSGi без Pax Runner
В классическом рождественском фильме « Это прекрасная жизнь» главный герой Джордж Бэйли получает шанс увидеть, каким был бы мир без него. Точно так же, чтобы оценить то, что предлагает Pax Runner, мы начнем с того, на что похож мир без Pax Runner.
Допустим, вы хотели запустить Equinox, а также установить и запустить наш пакет Hello World с прошлой недели. Во-первых, вам нужно скачать Equinox . Предполагая, что вы выбрали Equinox 3.4 (последний выпуск), мы запустили Equinox в командной строке следующим образом:
~/equinox% java -jar org.eclipse.osgi_3.4.0.v20080605-1900.jar
~/equinox%
К сожалению! Это ничего не сделало. Это связано с тем, что консоль Equinox по умолчанию отключена и без каких-либо других установленных пакетов, она отключается почти сразу после запуска. Нет проблем — мы просто запустим его с включенной консолью:
~/equinox% java -jar org.eclipse.osgi_3.4.0.v20080605-1900.jar -console
osgi>
Хорошо, на этот раз мы получаем приглашение osgi>, которое является консолью Equinox. Отсюда мы можем делать все что угодно, включая получение краткого статуса всех установленных пакетов:
osgi> ss
Framework is launched.
id State Bundle
0 ACTIVE org.eclipse.osgi_3.4.0.v20080605-1900
osgi>
Как видите, не так много установлено. Единственный доступный пакет — сама среда выполнения Equinox. Таким образом, это означает, что нашим следующим шагом будет установка нашего пакета Hello World. Для этого Equinox предоставляет команду установки:
osgi> install file:/Users/wallsc/Projects/sandbox/helloworld/hello-simple/target/hello-simple-1.0-SNAPSHOT.jar
Bundle id is 1
osgi>
Конечно, если вы случайно не настроили свой путь точно так же, как у меня, вам необходимо соответствующим образом настроить файл: URL. При желании вы можете установить пакет, используя http: URL:
osgi> http://www.habuma.com/osgi/bundles/hello-simple-1.0-SNAPSHOT.jar
Bundle id is 1
osgi>
Команда install принимает URL-адрес, который указывает на пакетный файл JAR для установки. URL может быть файлом: или http: URL. Если вам интересно … да, пакет доступен по этому http: URL.
Теперь пакет hello world установлен, но еще не запущен. Давайте начнем это:
osgi> start 1
Hello World!
osgi>
Там наш «Привет, мир!» приветствие, указывающее, что это сработало. Теперь давайте рассмотрим шаги, которые мы предприняли, чтобы добраться до этой точки:
- Загруженный Равноденствие
- Началось равноденствие (с включенной консолью)
- Установлен комплект
- Начал расслоение
Это было не так сложно. Но опять же, мы установили только один комплект. Представьте, на что это было похоже, чтобы установить несколько десятков пакетов. И что нужно сделать, чтобы попробовать это снова с другой версией Equinox или даже с другой реализацией OSGi, такой как Felix или Knopflerfish? Похоже, что нам придется повторить большинство или все те же шаги снова, имея дело с небольшими различиями между различными реализациями OSGi.
И вот где Pax Runner сияет.
Быстрый запуск OSGi с Pax Runner
Проще говоря, Pax Runner — это средство запуска OSGi. Но не позволяйте этому краткому описанию одурачить вас — Pax Runner гораздо больше, чем кажется на первый взгляд. На домашней странице Pax Runner Pax Runner отлично подходит, если вы хотите перейти с платформы OSGi на другую, вы новичок в OSGi и хотите потратить некоторое время на ее проверку, вы не хотите беспокоиться об установке и требования каждой платформы OSGi. Короче говоря, Pax Runner позволяет легко запускать любую платформу OSGi с любым выбором пакетов … и затем безболезненно переключаться на другую платформу и выбирать пакеты.
Чтобы начать работу с Pax Runner, сначала загрузите его (я использую версию 0.18.0) и разархивируйте его. На моем MacBook Pro это выглядит так:
pax% unzip ~/Downloads/pax-runner-assembly-0.18.0-jdk15.zip
Archive: /Users/wallsc/Downloads/pax-runner-assembly-0.18.0-jdk15.zip
creating: pax-runner-0.18.0/
creating: pax-runner-0.18.0/bin/
inflating: pax-runner-0.18.0/bin/pax-runner-0.18.0.jar
inflating: pax-runner-0.18.0/bin/pax-run.bat
inflating: pax-runner-0.18.0/bin/pax-run.sh
pax%
Как видите, Pax Runner поставляется с JAR-файлом, командным файлом MS-DOS и сценарием оболочки Unix. В этой статье я буду использовать сценарий оболочки Unix, но если вы работаете в Windows, то пакетный файл для вас. В любом случае добавьте каталог bin в системный путь, и вы готовы к работе с Pax Runner.
Начнем с детских шагов. Давайте запустим Pax Runner, чтобы посмотреть, что мы получим из коробки:
~/osgi-fun% pax-run.sh
______ ________ __ __
/ __ / / __ / / / / /
/ ___/ / __ / _\ \ _/
/ / / / / / / _\ \
/__/ /__/ /__/ /_/ /_/
Pax Runner (0.18.0) from OPS4J - http://www.ops4j.org
-----------------------------------------------------
-> Using config [classpath:META-INF/runner.properties]
-> Using only arguments from command line
-> Preparing framework [Felix 1.6.0]
-> Downloading bundles...
-> Felix 1.6.0 : 368418 bytes @ [ 601kBps ]
-> org.osgi.compendium (4.1.0) : 514214 bytes @ [ 5194kBps ]
-> org.apache.felix.shell (1.2.0) : 59114 bytes @ [ 687kBps ]
-> org.apache.felix.shell.tui.plugin (1.2.0) : 12455 bytes @ [ 1245kBps ]
-> Using execution environment [J2SE-1.6]
-> Runner has successfully finished his job!
Welcome to Felix.
=================
->
Как видите, Pax Runner запускают Felix 1.6.0. Если вы выполните команду ps, вы увидите, что это довольно простая среда выполнения Felix:
-> ps
START LEVEL 6
ID State Level Name
[ 0] [Active ] [ 0] System Bundle (1.6.0)
[ 1] [Active ] [ 1] osgi.compendium (4.1.0.build-200702212030)
[ 2] [Active ] [ 1] Apache Felix Shell Service (1.2.0)
[ 3] [Active ] [ 1] Apache Felix Shell TUI (1.2.0)
->
На этом этапе мы можем использовать команду install для установки пакета. Но это ничем не отличается от того, как мы бы это делали без Pax Runner. Итак, выйдите из Феликса (введите команду выключения) и запустите Pax Runner следующим образом:
~/osgi-fun% pax-run.sh file:/Users/wallsc/Projects/sandbox/helloworld/hello-simple/target/hello-simple-1.0-SNAPSHOT.jar
______ ________ __ __
/ __ / / __ / / / / /
/ ___/ / __ / _\ \ _/
/ / / / / / / _\ \
/__/ /__/ /__/ /_/ /_/
Pax Runner (0.18.0) from OPS4J - http://www.ops4j.org
-----------------------------------------------------
-> Using config [classpath:META-INF/runner.properties]
-> Using only arguments from command line
-> Scan bundles from [file:/Users/wallsc/Projects/sandbox/helloworld/hello-simple/target/hello-simple-1.0-SNAPSHOT.jar]
-> Scan bundles from [scan-bundle:file:/Users/wallsc/Projects/sandbox/helloworld/hello-simple/target/hello-simple-1.0-SNAPSHOT.jar]
-> Provision bundle [file:/Users/wallsc/Projects/sandbox/helloworld/hello-simple/target/hello-simple-1.0-SNAPSHOT.jar, at default start level, bundle will be started, bundle will be loaded from the cache]
-> Preparing framework [Felix 1.6.0]
-> Downloading bundles...
-> file:/Users/wallsc/Projects/sandbox/helloworld/hello-simple/target/hello-simple-1.0-SNAPSHOT.jar : 3677 bytes @ [ 1838kBps ]
-> Using execution environment [J2SE-1.6]
-> Runner has successfully finished his job!
Welcome to Felix.
=================
-> Hello World!
С помощью одной простой записи в командной строке мы смогли запустить Felix, установить наш пакет hello world и запустить этот пакет.
Теперь давайте попробуем это с Равноденствием вместо Феликса. Для этого все, что нам нужно сделать, это добавить новый параметр в командную строку:
~/osgi-fun% pax-run.sh <b>--platform=equinox</b> file:/Users/wallsc/Projects/sandbox/helloworld/hello-simple/target/hello-simple-1.0-SNAPSHOT.jar
______ ________ __ __
/ __ / / __ / / / / /
/ ___/ / __ / _\ \ _/
/ / / / / / / _\ \
/__/ /__/ /__/ /_/ /_/
Pax Runner (0.18.0) from OPS4J - http://www.ops4j.org
-----------------------------------------------------
-> Using config [classpath:META-INF/runner.properties]
-> Using only arguments from command line
-> Scan bundles from [file:/Users/wallsc/Projects/sandbox/helloworld/hello-simple/target/hello-simple-1.0-SNAPSHOT.jar]
-> Scan bundles from [scan-bundle:file:/Users/wallsc/Projects/sandbox/helloworld/hello-simple/target/hello-simple-1.0-SNAPSHOT.jar]
-> Provision bundle [file:/Users/wallsc/Projects/sandbox/helloworld/hello-simple/target/hello-simple-1.0-SNAPSHOT.jar, at default start level, bundle will be started, bundle will be loaded from the cache]
-> Preparing framework [Equinox 3.4.2]
-> Downloading bundles...
-> Equinox 3.4.2 (v20081215-1030) : 997240 bytes @ [ 493kBps ]
-> Eclipse utilities : 22755 bytes @ [ 948kBps ]
-> Eclipse compendium services : 63704 bytes @ [ 2275kBps ]
-> Using execution environment [J2SE-1.6]
-> Runner has successfully finished his job!
osgi> Hello World!
И вот так, Pax Runner запустил Equinox 3.4.2, затем установил и запустил пакет hello world.
Хотите попробовать Knopflerfish?
~/osgi-fun% pax-run.sh --platform=knopflerfish file:/Users/wallsc/Projects/sandbox/helloworld/hello-simple/target/hello-simple-1.0-SNAPSHOT.jar
______ ________ __ __
/ __ / / __ / / / / /
/ ___/ / __ / _\ \ _/
/ / / / / / / _\ \
/__/ /__/ /__/ /_/ /_/
Pax Runner (0.18.0) from OPS4J - http://www.ops4j.org
-----------------------------------------------------
-> Using config [classpath:META-INF/runner.properties]
-> Using only arguments from command line
-> Scan bundles from [file:/Users/wallsc/Projects/sandbox/helloworld/hello-simple/target/hello-simple-1.0-SNAPSHOT.jar]
-> Scan bundles from [scan-bundle:file:/Users/wallsc/Projects/sandbox/helloworld/hello-simple/target/hello-simple-1.0-SNAPSHOT.jar]
-> Provision bundle [file:/Users/wallsc/Projects/sandbox/helloworld/hello-simple/target/hello-simple-1.0-SNAPSHOT.jar, at default start level, bundle will be started, bundle will be loaded from the cache]
-> Preparing framework [Knopflerfish 2.2.0]
-> Downloading bundles...
-> Knopflerfish 2.2.0 : 335103 bytes @ [ 246kBps ]
-> org.osgi.compendium : 689150 bytes @ [ 1534kBps ]
-> org.knopflerfish.bundle.console : 36334 bytes @ [ 46kBps ]
-> org.knopflerfish.bundle.consoletty : 6170 bytes @ [ 1028kBps ]
-> org.knopflerfish.bundle.frameworkcommands : 26090 bytes @ [ 147kBps ]
-> Using execution environment [J2SE-1.6]
-> Runner has successfully finished his job!
Knopflerfish OSGi framework, version 4.0.12
Copyright 2003-2008 Knopflerfish. All Rights Reserved.
See http://www.knopflerfish.org for more information.
Loading xargs url file:knopflerfish/config.ini
Installed and started: file:bundles/osgi.compendium_4.0.1.jar (id#1)
Installed and started: file:bundles/org.knopflerfish.bundle.console_2.0.1.jar (id#2)
Installed and started: file:bundles/org.knopflerfish.bundle.consoletty-IMPL_2.0.0.jar (id#3)
Installed and started: file:bundles/org.knopflerfish.bundle.frameworkcommands-IMPL_2.0.5.jar (id#4)
Installed and started: file:bundles/com.habuma.osgi.helloworld.hello-simple_1.0.0.SNAPSHOT.jar (id#5)
> Hello World!
Framework launched
>
Как насчет консьержа?
~/osgi-fun% pax-run.sh --platform=concierge file:/Users/wallsc/Projects/sandbox/helloworld/hello-simple/target/hello-simple-1.0-SNAPSHOT.jar
______ ________ __ __
/ __ / / __ / / / / /
/ ___/ / __ / _\ \ _/
/ / / / / / / _\ \
/__/ /__/ /__/ /_/ /_/
Pax Runner (0.18.0) from OPS4J - http://www.ops4j.org
-----------------------------------------------------
-> Using config [classpath:META-INF/runner.properties]
-> Using only arguments from command line
-> Scan bundles from [file:/Users/wallsc/Projects/sandbox/helloworld/hello-simple/target/hello-simple-1.0-SNAPSHOT.jar]
-> Scan bundles from [scan-bundle:file:/Users/wallsc/Projects/sandbox/helloworld/hello-simple/target/hello-simple-1.0-SNAPSHOT.jar]
-> Provision bundle [file:/Users/wallsc/Projects/sandbox/helloworld/hello-simple/target/hello-simple-1.0-SNAPSHOT.jar, at default start level, bundle will be started, bundle will be loaded from the cache]
-> Preparing framework [Concierge 1.0.0]
-> Downloading bundles...
-> Concierge 1.0 (RC2) : 86089 bytes @ [ 87kBps ]
-> ch.ethz.iks.concierge.service.tracker : 8635 bytes @ [ 1233kBps ]
-> ch.ethz.iks.concierge.shell : 16007 bytes @ [ 1000kBps ]
-> Using execution environment [J2SE-1.6]
-> Runner has successfully finished his job!
---------------------------------------------------------
Concierge OSGi 1.0_RC1 on Mac OS X 10.5.6 starting ...
---------------------------------------------------------
INSTALLING file:bundles/1296071065_1.0.0.RC2.jar
INSTALLING file:bundles/1441349545_1.0.0.RC2.jar
INSTALLING file:bundles/com.habuma.osgi.helloworld.hello-simple_1.0.0.SNAPSHOT.jar
STARTING file:bundles/1296071065_1.0.0.RC2.jar
STARTING file:bundles/1441349545_1.0.0.RC2.jar
Concierge> STARTING file:bundles/com.habuma.osgi.helloworld.hello-simple_1.0.0.SNAPSHOT.jar
Hello World!
---------------------------------------------------------
Framework started in 0.042 seconds.
---------------------------------------------------------
Concierge>
Как вы можете видеть, переключение между платформами OSGi является простым делом с Pax Runner. Переключение между версиями платформы так же просто, используя параметр —version. Допустим, мы хотели попробовать это с более старой версией Equinox:
~/osgi-fun% pax-run.sh --platform=equinox --version=3.2.1 file:/Users/wallsc/Projects/sandbox/helloworld/hello-simple/target/hello-simple-1.0-SNAPSHOT.jar
______ ________ __ __
/ __ / / __ / / / / /
/ ___/ / __ / _\ \ _/
/ / / / / / / _\ \
/__/ /__/ /__/ /_/ /_/
Pax Runner (0.18.0) from OPS4J - http://www.ops4j.org
-----------------------------------------------------
-> Using config [classpath:META-INF/runner.properties]
-> Using only arguments from command line
-> Scan bundles from [file:/Users/wallsc/Projects/sandbox/helloworld/hello-simple/target/hello-simple-1.0-SNAPSHOT.jar]
-> Scan bundles from [scan-bundle:file:/Users/wallsc/Projects/sandbox/helloworld/hello-simple/target/hello-simple-1.0-SNAPSHOT.jar]
-> Provision bundle [file:/Users/wallsc/Projects/sandbox/helloworld/hello-simple/target/hello-simple-1.0-SNAPSHOT.jar, at default start level, bundle will be started, bundle will be loaded from the cache]
-> Preparing framework [Equinox 3.2.1]
-> Downloading bundles...
-> Equinox 3.2.1 (R32x_v20060717) : 847974 bytes @ [ 438kBps ]
-> Eclipse utilities : 15016 bytes @ [ 1001kBps ]
-> Eclipse compendium services : 51712 bytes @ [ 1149kBps ]
-> Using execution environment [J2SE-1.6]
-> Runner has successfully finished his job!
osgi> Hello World!
Предоставление пакетов из URL-адресов в командной строке — это только одна опция, которую предлагает Pax Runner. В целом, Pax Runner может быть настроен на 8 способов:
- С URL
- Из текстового файла
- Из файла Maven POM
- Из ZIP-файла
- Из файловой системы
- Из OBR (OSGi Bundle Repository)
- Из возможностей Apache ServiceMix
- Составное обеспечение
Я не буду вдаваться в подробности по всем этим параметрам обеспечения. Но давайте посмотрим на некоторые из тех, которые я использую чаще всего. Мы уже видели, как обеспечить с помощью URL-адреса, поэтому давайте посмотрим, как обеспечить с помощью файловой системы, из ZIP-файла и из текстового файла.
Предоставление из файловой системы
Вместо того, чтобы явно перечислять все пакеты, которые мы хотим предоставить в командной строке, мы можем указать Pax Runner на каталог в файловой системе и заставить его загружать все пакеты из этого каталога.
Например, давайте создадим каталог с именем mybundles и скопируем наш пакет hello world в каталог:
~/osgi-fun% mkdir mybundles
~/osgi-fun% cp ~/Projects/sandbox/helloworld/hello-simple/target/hello-simple-1.0-SNAPSHOT.jar mybundles
~/osgi-fun%
Теперь мы можем запустить Pax Runner следующим образом:
~/osgi-fun% pax-run.sh mybundles
______ ________ __ __
/ __ / / __ / / / / /
/ ___/ / __ / _\ \ _/
/ / / / / / / _\ \
/__/ /__/ /__/ /_/ /_/
Pax Runner (0.18.0) from OPS4J - http://www.ops4j.org
-----------------------------------------------------
-> Using config [classpath:META-INF/runner.properties]
-> Using only arguments from command line
-> Scan bundles from [scan-dir:mybundles]
-> Provision bundle [file:/Users/wallsc/osgi-fun/mybundles/hello-simple-1.0-SNAPSHOT.jar, at default start level, bundle will be started, bundle will be loaded from the cache]
-> Preparing framework [Felix 1.6.0]
-> Downloading bundles...
-> Using execution environment [J2SE-1.6]
-> Runner has successfully finished his job!
Welcome to Felix.
=================
-> Hello World!
->
Запуская Pax Runner таким образом, он говорит, что нужно заглянуть в каталог mybundles и установить / запустить все найденные в нем пакеты. В данном случае это только наш пакет приветствий. Но если бы этот каталог был переполнен пакетами, Pax Runner установил бы и запустил каждый из них.
Предоставление из файла ZIP
Предоставление из файла ZIP не сильно отличается от предоставления из каталога. Основное отличие заключается в том, что все пакеты упакованы в один ZIP-файл. Это позволяет удобно распределять наборы пакетов для простой установки на платформу OSGi.
To try it out, let’s create a ZIP file containing the hello world bundle:
~/osgi-fun% zip mybundles.zip hello-simple-1.0-SNAPSHOT.jar
adding: hello-simple-1.0-SNAPSHOT.jar (deflated 43%)
~/osgi-fun%
Now we can kick off Pax Runner like this:
~/osgi-fun% pax-run.sh mybundles.zip
______ ________ __ __
/ __ / / __ / / / / /
/ ___/ / __ / _\ \ _/
/ / / / / / / _\ \
/__/ /__/ /__/ /_/ /_/
Pax Runner (0.18.0) from OPS4J - http://www.ops4j.org
-----------------------------------------------------
-> Using config [classpath:META-INF/runner.properties]
-> Using only arguments from command line
-> Scan bundles from [mybundles.zip]
-> Scan bundles from [scan-dir:file:/Users/wallsc/osgi-fun/mybundles.zip]
-> Provision bundle [jar:file:/Users/wallsc/osgi-fun/mybundles.zip!/hello-simple-1.0-SNAPSHOT.jar, at default start level, bundle will be started, bundle will be loaded from the cache]
-> Preparing framework [Felix 1.6.0]
-> Downloading bundles...
-> jar:file:/Users/wallsc/osgi-fun/mybundles.zip!/hello-simple-1.0-SNAPSHOT.jar : 3677 bytes @ [ 306kBps ]
-> Using execution environment [J2SE-1.6]
-> Runner has successfully finished his job!
Welcome to Felix.
=================
-> Hello World!
->
Again, the mybundles.zip file contains only a single bundle. But like directory scanning, Pax Runner’s ZIP file scanning can pull in and start as many bundles as are contained in the ZIP file.
Provisioning from a text file
So far we’ve started Pax Runner by specifying a URL to a bundle JAR, a directory, and a ZIP file. We can also start it by giving it a flat text file containing a list of URLs to install bundles from. For example let’s create a file named mybundles.txt and put a reference to our hello world bundle in it:
file:/Users/wallsc/Projects/sandbox/helloworld/hello-simple/target/hello-simple-1.0-SNAPSHOT.jar
Then, let’s start Pax Runner, giving it this text file:
~/osgi-fun% pax-run.sh mybundles.txt
______ ________ __ __
/ __ / / __ / / / / /
/ ___/ / __ / _\ \ _/
/ / / / / / / _\ \
/__/ /__/ /__/ /_/ /_/
Pax Runner (0.18.0) from OPS4J - http://www.ops4j.org
-----------------------------------------------------
-> Using config [classpath:META-INF/runner.properties]
-> Using only arguments from command line
-> Scan bundles from [mybundles.txt]
-> Scan bundles from [scan-file:file:/Users/wallsc/osgi-fun/mybundles.txt]
-> Provision bundle [file:/Users/wallsc/Projects/sandbox/helloworld/hello-simple/target/hello-simple-1.0-SNAPSHOT.jar, at default start level, bundle will be started, bundle will be loaded from the cache]
-> Preparing framework [Felix 1.6.0]
-> Downloading bundles...
-> Using execution environment [J2SE-1.6]
-> Runner has successfully finished his job!
Welcome to Felix.
=================
-> Hello World!
->
Note that although the text file contained a file: URL, it could’ve just as easily have been an http: URL. And, thanks to Pax URL, it can also be a Maven URL, referencing an artifact ID, group ID, and version of the bundle in a Maven repository:
mvn:com.habuma.osgi.helloworld/hello-simple/1.0-SNAPSHOT
As with the other options, we can list multiple bundles in the text file to be provisioned. For example, a more interesting OSGi bundle-based application might include several bundles in its provisioning text file:
To recap, this week we saw how to use Pax Runner to fire up an OSGi platform with one or more bundles already installed and started. We’ve kept it simple so far, installing a single bundle. But as I’ve mentioned, adding more bundles to the mix is a simple matter of adding entries to a provisioning file, dropping the bundles in a directory, or packaging them in a ZIP file.
We’re just getting started with Pax Runner. I assure you that you’ll see more Pax Runner goodness in future blog entries.
In fact, next week I plan to show you how to use profiles, a Pax Runner feature that is based on composite provisioning. You’ll see how profiles makes it easy to install several dozen bundles all at once by referring to them by a single logical name. While we’re at it, we’ll also tinker with Distributed OSGi, a new feature of the upcoming OSGi R4.2 specification. See ya then!