Статьи

Пример использования OSGi: модульный vert.x

OSGi позволяет аккуратно разделить код Java на модули, известные как пакеты, с доступом к коду и ресурсам, контролируемым загрузчиком классов для каждого пакета. Сервисы OSGi предоставляют дополнительный механизм разделения: пользователи интерфейса не должны зависеть от классов реализации, фабрик и т. Д.

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

Отказ от ответственности: я не предлагаю заменять контейнер vert.x или его систему модулей. Это в первую очередь пример использования OSGi, хотя некоторые из выводов должны мотивировать улучшения в vert.x, особенно когда он встроен в приложения с пользовательскими загрузчиками классов.

vert.x

Проект с открытым исходным кодом vert.x предоставляет альтернативу JVM для node.js : модель асинхронного, управляемого событиями программирования для написания веб-приложений на нескольких языках, включая Java, Groovy, JavaScript и Ruby.

vert.x поддерживает HTTP, а также современные протоколы, такие как WebSockets и sockjs (которые работают в большем количестве браузеров, чем WebSockets и могут легче проходить брандмауэры).
vert.x имеет распределенную шину событий, которая позволяет распространять сообщения JSON между приложениями vert.x, известными как verstitutions, и библиотеками общего кода, известными как busmods . BusMod — это особый тип veriment, который обрабатывает события из шины событий. vert.x поставляет некоторые busmods, такие как «persistor» MongoDB , и пользователи могут писать свои собственные.

Модель многопоточности vert.x интересна тем, что каждая вертикаль (или busmod) связана с конкретным потоком на весь срок его службы, поэтому код вертикали не должен беспокоиться о безопасности потока. Пул потоков используется для распределения работы над вертиками, и каждая вертикаль должна избегать блокирующих или длительных операций, чтобы не влиять на пропускную способность сервера (vert.x предоставляет отдельные механизмы для эффективной реализации длительных операций). Это похоже на модель квазиреентрантных потоков в процессоре транзакций CICS. 1

Особый интерес здесь представляет система модулей vert.x, в которой имеется загрузчик классов для каждой статьи и библиотеки кодов, известные как модули , которые загружаются в загрузчик классов каждой версии, которая их использует. Таким образом, нет никакого способа поделиться кодом между статьями, кроме как через шину событий.

В vert.x имеется отличная документация, включая основное руководство , руководство по java (а также руководства для других языков), учебные пособия и примеры исполняемого кода .

OSGi

Если вы еще не знакомы с OSGi, прочитайте мой вводный пост OSGi , но не беспокойтесь о ссылках в этом посте прямо сейчас — вы всегда можете вернуться и сделать это позже.

Встраивание vert.x в OSGi

Я сделал это в несколько небольших шагов, которые представлены по очереди ниже: преобразование файлов JAR vert.x в пакеты OSGi, а затем модульная вертикаль, busmods и клиенты шины событий.

Преобразование файлов JAR vert.x в пакеты OSGi

Руководство vert.x рекомендует пользователям встраивать vert.x в свои собственные приложения, используя основной JAR-файл vert.x, поэтому первым шагом при внедрении vert.x в OSGi было преобразование основного JAR-файла vert.x в комплект OSGi, чтобы это может быть загружено во время выполнения OSGi.

Я использовал инструмент bundlor , хотя другие инструменты, такие как bnd, будут работать одинаково хорошо. Bundlor берет шаблон, а затем анализирует байт-код JAR, чтобы создать новый JAR с соответствующими заголовками манифеста OSGi. Пожалуйста, обратитесь к документации SpringSource Bundlor для получения дополнительной информации о компоновщике на данный момент, поскольку документация по Eclipse Virgo Bundlor не публикуется на момент написания, даже если проект компоновщика перенесен на Eclipse.org.

Шаблон для ядра JAR vert.x выглядит следующим образом:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
Bundle-ManifestVersion: 2
Bundle-SymbolicName: org.vertx.core
Bundle-Version: 1.0.0.final
Bundle-Name: vert.x Core
Import-Template:
 org.jboss.netty.*;version="[3.4.2.Final,4.0)",
 org.codehaus.jackson.*;version="[1.9.4,2.0)",
 com.hazelcast.*;version="[2.0.2,3.0)";resolution:=optional,
 groovy.*;resolution:=optional;version=0,
 org.codehaus.groovy.*;resolution:=optional;version=0,
 javax.net.ssl;resolution:=optional;version=0,
 org.apache.log4j;resolution:=optional;version=0,
 org.slf4j;resolution:=optional;version=0
Export-Template: *;version="1.0.0.final"

( Шаблон и все остальные части этого примера доступны на github .)

Это определяет действительный диапазон версий для пакетов, от которых зависит JAR (диапазон «0» представляет диапазон версий от 0 или более), являются ли эти пакеты необязательными или обязательными, и какой версией должны быть собственные пакеты JAR. экспортируется в. Он также дает пакету символическое имя (используется для идентификации пакета), версию и (описательное) имя. Вооружившись этой информацией, OSGi затем связывает воедино зависимости пакетов, делегируя загрузки классов и поиск ресурсов между загрузчиками классов пакетов.

К счастью, JAR-файлы netty network и JSON Джексона, от которых зависит JAR-ядро vert.x, поставляются с действительными OSGi-манифестами.

Для проверки правильности манифеста я попытался развернуть пакет ядра vert.x в ядре Virgo . Это было просто вопрос размещения основного пакета vert.x в каталоге раскладки и его зависимостей в каталоге репозитория / usr, а затем запуска ядра. Следующие сообщения консоли показывают, что основной пакет vert.x был установлен и успешно разрешен:

1
2
3
4
5
<hd0001i> Hot deployer processing 'INITIAL' event for file 'vert.x-core-1.0.0.final.jar'.
<de0000i> Installing bundle 'org.vertx.core' version '1.0.0.final'.
<de0001i> Installed bundle 'org.vertx.core' version '1.0.0.final'.
<de0004i> Starting bundle 'org.vertx.core' version '1.0.0.final'.
<de0005i> Started bundle 'org.vertx.core' version '1.0.0.final'.

Используя оболочку Virgo, я проверил проводку пучков:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
osgi> ss
"Framework is launched."
 
id      State       Bundle
0       ACTIVE      org.eclipse.osgi_3.7.1.R37x_v20110808-1106
...
89      ACTIVE      org.vertx.core_1.0.0.final
90      ACTIVE      jackson-core-asl_1.9.4
91      ACTIVE      jackson-mapper-asl_1.9.4
92      ACTIVE      org.jboss.netty_3.4.2.Final
 
osgi> bundle 89
org.vertx.core_1.0.0.final [89]
  ...
  Exported packages
    ...
    org.vertx.java.core; version="1.0.0.final"[exported]
    org.vertx.java.core.buffer; version="1.0.0.final"[exported]
    ...
  Imported packages
    org.jboss.netty.util; version="3.4.2.Final"<org.jboss.netty_3.4.2.final [92]>
    ...
    org.codehaus.jackson.map; version="1.9.4"<jackson-mapper-asl_1.9.4 [91]>
    ...

Я также преобразовал JAR платформы vert.x в комплект OSGi аналогичным образом, как это было необходимо позже.

Модульные статьи

Типичная вертикаль выглядит так:

01
02
03
04
05
06
07
08
09
10
public class ServerExample extends Verticle {
 
  public void start() {
    vertx.createHttpServer().requestHandler(new Handler<httpserverrequest>() {
      public void handle(HttpServerRequest req) {
        ...
      }
    }).listen(8080);
  }
}

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

Давайте посмотрим на модульную вертикальную связку. Его код состоит из одного класса HttpServerRequestHandler : 2

1
2
3
4
5
6
7
public final class HttpServerRequestHandler implements Handler<httpserverrequest> {
 
    public void handle(HttpServerRequest req) {
        ...
    }
 
}

Он также имеет декларативные метаданные в форме свойств службы, которые зарегистрированы вместе с обработчиком в реестре службы OSGi. Для этого я использовал сервис OSGi Blueprint, хотя мог бы использовать декларативные сервисы OSGi или даже зарегистрировать сервис программно с помощью OSGi API. Метаданные проекта — это файл blueprint.xml в комплекте, который выглядит следующим образом:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
<?xml version="1.0" encoding="UTF-8"?>
         
    <service interface="org.vertx.java.core.Handler" ref="handler">
        <service-properties>
            <entry key="type" value="HttpServerRequestHandler">
            <entry key="port" value="8090">
        </service-properties>
    </service>
         
    <bean class="org.vertx.osgi.sample.basic.HttpServerRequestHandler"
          id="handler"/>
 
</blueprint>

Эти метаданные объявляют, что должен быть создан HTTP-сервер (через свойство службы типа), зарегистрированный в нем обработчик и сервер устанавливает прослушивание на порт 8090 (через свойство службы порта). Все это происходит благодаря шаблону доски, когда работает пакет org.vertx.osgi, как мы увидим ниже.

Обратите внимание, что модульная вертикаль зависит только от классов Handler и HttpServerRequest, тогда как исходная вертикаль также зависит от классов Vertx, HttpServer и Verticle. Это также делает вещи немного проще для тех из нас, кто любит модульное тестирование (в дополнение к тестированию в контейнере), так как требуется меньшее количество макетов или заглушек.

Так что у нас сейчас есть? Два пакета для добавления к пакетам, которые мы установили ранее: пакет org.vertx.osgi, который инкапсулирует стандартный код, и пакет приложений, представляющий модульную вертикалку. Нам также нужна реализация сервиса Blueprint — начиная с версии 3.5, реализация Blueprint встроена в ядро ​​Virgo. Следующая диаграмма взаимодействия показывает одну возможную последовательность событий:

В OSGi каждый пакет имеет свой собственный жизненный цикл, и в целом пакеты разрабатываются так, чтобы они работали правильно независимо от порядка их запуска по сравнению с другими пакетами. В приведенном выше примере предполагаемый порядок запуска: сервис blueprint, пакет org.vertx.osgi, модульный пакет veriment. Тем не менее, пакет org.vertx.osgi может запуститься после модульного набора вертикали, и конечный результат будет таким же: будет создан сервер и обработчик модульного набора вертикали зарегистрирован на сервере, а сервер прослушивает набор. Если служба blueprint запускается после org.vertx.osgi и модульных комплектов вертикал, то пакет org.vertx.osgi не будет обнаруживать сервис-обработчик модульного комплекта вертикал, появляющийся в реестре сервиса, пока не будет запущен сервис blueprint, но затем конечный результат снова будет таким же.

Проект github содержит исходные тексты для некоторых примеров модульных вершин: базовая вертикаль HTTP (которая работает на порте 8090) и вертикаль sockjs (которая работает на порте 8091). В комплекте org.vertx.osgi требовалось больше кода для поддержки sockjs и модульная вертикаль sockjs, необходимая для предоставления обработчика sockjs в дополнение к обработчику HTTP.

Модульные BusMods

Персистор MongoDB является типичным примером модуля шины, который обрабатывает сообщения от шины событий:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public class MongoPersistor extends BusModBase implements Handler<message<jsonobject>> {
 
  private String address;
  private String host;
  private int port;
  private String dbName;
 
  private Mongo mongo;
  private DB db;
 
  public void start() {
    super.start();
 
    address = getOptionalStringConfig("address", "vertx.mongopersistor");
    host = getOptionalStringConfig("host", "localhost");
    port = getOptionalIntConfig("port", 27017);
    dbName = getOptionalStringConfig("db_name", "default_db");
 
    try {
      mongo = new Mongo(host, port);
      db = mongo.getDB(dbName);
      eb.registerHandler(address, this);
    } catch (UnknownHostException e) {
      logger.error("Failed to connect to mongo server", e);
    }
  }
 
  public void stop() {
    mongo.close();
  }
 
  public void handle(Message<jsonobject> message) {
    ...
  }
 
}

Опять-таки, существует смесь стандартного кода (для регистрации обработчика шины событий), логики запуска / остановки, обработки конфигурации и самого обработчика шины событий. Я применил аналогичный подход к другим вершинам и выделил стандартный код в комплект org.vertx.osgi, оставив обработчик и метаданные (включая конфигурацию) в модульном busmod. Зависимость персистора от JAR-клиента MongoDB (mongo.jar) удобна, потому что этот JAR поставляется с действительным манифестом OSGi.

Вот blueprint.xml :

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
<?xml version="1.0" encoding="UTF-8"?>
         
    <service ref="handler" interface="org.vertx.java.core.Handler">
        <service-properties>
            <entry key="type" value="EventBusHandler"/>
            <entry key="address" value="vertx.mongopersistor"/>
        </service-properties>
    </service>
         
    <bean id="handler" class="org.vertx.osgi.mod.mongo.MongoPersistor"
          destroy-method="stop">
        <argument type="java.lang.String"><value>localhost</value></argument>
        <argument type="int"><value>27017</value></argument>
        <argument type="java.lang.String"><value>default_db</value></argument>
    </bean>
       
</blueprint>

Обратите внимание, что шаблонная конфигурация состоит из типа обработчика и адреса шины событий. Другая конфигурация (хост, порт и имя базы данных) зависит от персистора MongoDB.

Вот модульный код MongoDB busmod :

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public class MongoPersistor extends BusModBase
                            implements Handler<Message<JsonObject>> {
 
    private final String host;
 
    private final int port;
 
    private final String dbName;
 
    private final Mongo mongo;
 
    private final DB db;
 
    public MongoPersistor(String host, int port, String dbName)
           throws UnknownHostException, MongoException {
        this.host = host;
        this.port = port;
        this.dbName = dbName;
 
        this.mongo = new Mongo(host, port);
        this.db = this.mongo.getDB(dbName);
    }
 
    public void stop() {
        mongo.close();
    }
 
    public void handle(Message<JsonObject> message) {
        ...
    }
 
}

Код все еще расширяет BusModBase просто потому, что BusModBase предоставляет несколько удобных вспомогательных методов. Опять же, результирующий код проще и проще для модульного тестирования, чем немодульный эквивалент.

Модульные клиенты Event Bus

Наконец, мне понадобилась модульная вертикалка для проверки модульного персистора MongoDB. Все, что нужно сделать этой статье, — это отправить соответствующее сообщение на шину событий. Обычные vert.x verты получают шину событий, используя класс Vertx, но я снова использовал сервис Blueprint, на этот раз, чтобы найти сервис шины событий в реестре сервисов и внедрить его в модульную вертикалку. Я также расширил пакет org.vertx.osgi для публикации службы шины событий в реестре служб.

Blueprint.xml для клиента модульной шины событий выглядит следующим образом:

01
02
03
04
05
06
07
08
09
10
11
12
13
<?xml version="1.0" encoding="UTF-8"?>
 
    <reference id="eventBus" interface="org.vertx.java.core.eventbus.EventBus"/>
 
    <bean class="org.vertx.osgi.sample.mongo.MongoClient">
        <argument ref="eventBus"/>
        <argument type="java.lang.String">
            <value>vertx.mongopersistor</value>
        </argument>
    </bean>
       
</blueprint>

Тогда клиентский код модульной шины событий прост:

1
2
3
4
5
6
7
8
9
public final class MongoClient {
 
    public MongoClient(EventBus eventBus, String address) {
        JsonObject msg = ...
        eventBus.send(address, msg,
                      new Handler<Message<JsonObject>>(){...});
    }
 
}

Принимая это за спин

1. Я сделал все необходимые OSGi-пакеты доступными в каталоге bundles в git. Вы можете получить их, либо клонировав репозиторий git:

git clone git://github.com/glyn/vert.x.osgi.git

или загрузив почтовый индекс git-репо .

2. vert.x требует Java 7 , поэтому настройте оболочку терминала для использования Java 7. Убедитесь, что переменная среды JAVA_HOME установлена ​​правильно. (Если вы не можете получить Java 7 прямо сейчас, вы увидите некоторые ошибки при развертывании пакетов в OSGi, и вы не сможете запустить примеры в шагах 8 и 9.)

3. Если вы являетесь пользователем OSGi, просто установите и запустите комплекты в вашей любимой платформе или контейнере OSGi и перейдите к шагу 8. Если нет, то используйте копию ядра Virgo в репозитории git следующим образом.

4. Перейдите в каталог virgo-kernel-… в вашей локальной копии git repo.

5. В UNIX:

bin/startup.sh -clean

или в Windows:

bin\startup.bat -clean

6. Ядро Virgo должно запустить и развернуть различные пакеты в своем каталоге раскладки:

  • Пакет org.vertx.osgi ( org.vertx.osgi-0.0.1.jar )
  • Пример HTTP модульной вертикали ( org.vertx.osgi.sample.basic-1.0.0.jar )
  • Пример модульной вертикали SockJS ( org.vertx.osgi.sample.sockjs-1.0.0.jar )
  • Пример постоянных MongoDB модульный busmod ( org.vertx.osgi.mods.mongo-1.0.0.jar )

7. Если вы хотите увидеть, какие пакеты сейчас запущены, запустите оболочку Virgo из другого терминала:

telnet localhost 2501

и используйте команды ss или lb для суммирования установленных пакетов. Команда help перечислит другие доступные команды, а disconnect выведет вас из оболочки Virgo. Вот типичный вывод команды ss :

01
02
03
04
05
06
07
08
09
10
11
...
89      ACTIVE      org.vertx.osgi_0.0.1
90      ACTIVE      jackson-core-asl_1.9.4
91      ACTIVE      jackson-mapper-asl_1.9.4
92      ACTIVE      org.jboss.netty_3.4.2.Final
93      ACTIVE      org.vertx.core_1.0.0.final
94      ACTIVE      org.vertx.osgi.mods.mongo_1.0.0
95      ACTIVE      com.mongodb_2.7.2
96      ACTIVE      org.vertx.platform_1.0.0.final
97      ACTIVE      org.vertx.osgi.sample.basic_1.0.0
98      ACTIVE      org.vertx.osgi.sample.sockjs_1.0.0

и команды lb (которая включает в себя более описательные заголовки Bundle-Name):

01
02
03
04
05
06
07
08
09
10
11
...
   89|Active     |    4|vert.x OSGi Integration (0.0.1)
   90|Active     |    4|Jackson JSON processor (1.9.4)
   91|Active     |    4|Data mapper for Jackson JSON processor (1.9.4)
   92|Active     |    4|The Netty Project (3.4.2.Final)
   93|Active     |    4|vert.x Core (1.0.0.final)
   94|Active     |    4|MongoDB BusMod (1.0.0)
   95|Active     |    4|MongoDB (2.7.2)
   96|Active     |    4|vert.x Platform (1.0.0.final)
   97|Active     |    4|Sample Basic HTTP Verticle (1.0.0)
   98|Active     |    4|Sample SockJS Verticle (1.0.0)

8. Теперь вы можете использовать веб-браузер, чтобы опробовать базовый пример HTTP по адресу localhost: 8090, который должен ответить «привет», или пример SockJS по адресу http: // localhost: 8091, который должен отобразить окно, в которое можно ввести текст и кнопка, при нажатии которой появляется всплывающее окно:

9. Если вы хотите попробовать (безголовый) клиент шины событий MongoDB, загрузите MondoDB и запустите его локально на порте по умолчанию, а затем скопируйте org.vertx.osgi.sample.mongo-1.0.0.jar из каталога bundles в Virgo. каталог погрузки. Как только этот пакет запускается, он отправляет сообщение на шину событий и запускает постоянный MongoDB для обновления базы данных. Если вы не хотите использовать MongoDB для проверки того, что обновление было выполнено, посмотрите в журналах Virgo (в serviceability/logs/log.log ), чтобы увидеть некоторые строки System.out, подобные следующим, которые подтверждают, что что-то произошло:

1
2
3
4
5
System.out Sending message: {action=save, document={x=y}, collection=vertx.osgi}
...
System.out Message sent
...
System.out Message response {_id=95..., status=ok}

OSGi и vert.x Модульность

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

Это сильно отличается от системы модулей vert.x, в которой любой модуль (кроме busmod), от которого зависит вертикаль, загружается в тот же загрузчик классов, что и вертикал.

Преимущества модульной системы OSGi состоят в том, что в системе установлена ​​одна копия каждого модуля, которая видна и может управляться такими инструментами, как оболочка Virgo. Это также минимизирует след.

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

Заменить контейнер?

Когда я поднял тему встраивания vert.x в OSGi , лидер vert.x Тим Фокс спросил меня, пишу ли я замену для текущего контейнера, на что я ответил «не совсем». Я сказал это, потому что мне понравилась управляемая событиями модель программирования vert.x и ее модель потоков, которая, кажется, является частью «контейнера». Но я пытался заменить пару аспектов контейнера vert.x: систему модулей и способ регистрации обработчиков ver баксов.

Позже меня поразило, что, возможно, понятие «контейнер» как монолитного объекта немного странно в модульной системе, и, возможно, было бы лучше подумать о множественных, отдельных понятиях сдерживания, которые затем можно было бы комбинировать по-разному, чтобы удовлетворить разные пользователи. Тем не менее, тонкое взаимодействие между моделями загрузки классов и потоковой обработки, показанное выше, показывает, что различные понятия содержания могут зависеть друг от друга. Интересно, что другие думают о понятии «контейнер»?

Выводы

Утверждение vert.x о том, что оно может быть встроено в другие приложения, по существу подтверждено, поскольку платформа OSGi является довольно требовательным приложением.

Модульная система vert.x, хотя и не обеспечивает изоляцию между модулями, обеспечивает аккуратную изоляцию между приложениями (включающими в себя версии и их модули) и позволяет писать модули, не обращая внимания на безопасность потоков.

Была поднята одна проблема vert.x2, которая должна облегчить внедрение vert.x в других средах с помощью пользовательских загрузчиков классов.

vert.x может последовать примеру JAR-файлов netty, jackson и MongoDB и включать манифесты OSGi в свои JAR-файлы ядра и платформы, чтобы пользователи OSGi не могли конвертировать эти JAR-файлы в пакеты OSGi. Я оставлю это кому-то другому, чтобы предложить, поскольку я не могу измерить спрос на использование vert.x внутри OSGi.

Запуск vert.x в OSGi отвечает некоторым выдающимся требованиям vert.x, таким как автоматизация тестов в контейнере (у OSGi есть ряд решений, включая Pax Exam, в то время как у Virgo есть интегрированная среда тестирования тестирования), и как разрабатывать версии и развертывать их в vert .x под управлением IDE (см. руководство по инструментам Virgo IDE ). Дева также предоставляет множество дополнительных преимуществ, включая оболочку администратора для проверки и управления пакетами и статьями, сложную диагностику и многое другое (подробности см. В официальном документе Дева ).

В этом упражнении также были хорошие побочные эффекты для Девы. Ошибка 370253 была исправлена, что было единственной известной проблемой при запуске Virgo под Java 7. Virgo 3.5 зависит от Bluemini Blueprint, который сломался в этой среде, поэтому ошибка 379384 была поднята и исправлена. Я использовал новый инструмент Virgo, основанный на Eclipse, для разработки различных пакетов и запуска их в Virgo. Как следствие, я обнаружил несколько небольших проблем в инструментальной оснастке, которые будут рассмотрены в должное время.

Наконец, запуск vert.x на ядре Virgo является дополнительной проверкой того, что ядро ​​подходит для создания пользовательских сред выполнения серверов, поскольку теперь у нас есть vert.x в дополнение к Tomcat, Jetty и один или два пользовательских сервера, работающих на ядре.

Примечания:

  1. Я работал в команде разработчиков CICS в мои дни в IBM. Коллега из SpringSource дал мне «CICS делает это!» Футболка вскоре после того, как мы начали работать вместе. Старые привычки умирают с трудом.
  2. Модульная вертикаль в настоящее время должна перехватывать логику поиска ресурсов vert.x, чтобы файлы в пакете можно было легко обслуживать. Было бы гораздо лучше, если бы этот общий код был перенесен в пакет org.vertx.osgi, но для этого необходимо, чтобы сначала был реализован выпуск 161 vert.x.

Ссылка: пример OSGi: модульный файл vert.x от нашего партнера по JCG Глина Нормингтона из блога Mind the Gap .