Каков разумный рабочий процесс разработки OSGi? - PullRequest
7 голосов
/ 05 мая 2010

Я использую OSGi для своего последнего проекта на работе, и это довольно красиво с точки зрения модульности и функциональности.

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

Пример: у вас есть пакеты A и B. B зависит от пакетов, определенных в A. Каждый пакет разрабатывается как отдельный проект Java.

Чтобы скомпилировать B, A должен быть в пути к классу javac.

Вы:

  1. Ссылка на местоположение файловой системы проекта A в скрипте сборки B?
  2. Построить A и выбросить банку в каталог lib библиотеки B?
  3. Положитесь на функцию "ссылочных проектов" Eclipse и всегда используйте Eclipse classpath для сборки (тьфу)
  4. Использовать общий каталог "lib" для всех проектов и выкидывать туда файлы jar-пакетов после компиляции?
  5. Настроить хранилище комплектов, проанализировать манифест из скрипта сборки и вытащить необходимые комплекты из хранилища?

Нет. 5 звучит самым чистым, но также очень много накладных расходов.

Ответы [ 4 ]

7 голосов
/ 05 мая 2010

У моей компании более 100 проектов в комплекте, и мы используем Eclipse для управления зависимостями. Однако я не рекомендую подход "Требуемые плагины" для управления зависимостями. Лучше всего создавать плагин-проекты. Экспортируйте только пакеты из каждого проекта, который вы хотите видеть. Затем на стороне импорта сделайте следующее:

Откройте редактор манифеста

Перейти на вкладку зависимостей В левом нижнем углу находится раздел «Автоматизированное управление зависимостями»

Добавить любые плагины, от которых зависит текущий плагин

После написания кода вы можете щелкнуть ссылку «Добавить зависимости» на этой вкладке, чтобы автоматически вычислить импортированные пакеты.

Если вы запускаете из Eclipse, это выполняется автоматически для вас при запуске.

Преимущества этого подхода в том, что ваши встроенные пакеты используют только определенный OSGi механизм импорта / экспорта пакетов, а не что-то из Eclipse.

Если вы хотите узнать больше, я рекомендую зайти на этот сайт и заказать книгу. Это отлично.

http://equinoxosgi.org/

5 голосов
/ 05 мая 2010

Что ж, делайте то, что у вас должно было быть долгое время раньше, раздельно реализуйте и API ... хорошо, это не всегда так просто в существующих системах, но эта модель имеет огромный успех. Когда ваш API находится в отдельном (гораздо более стабильном) пакете / jar, вы можете скомпилировать клиенты и реализации для этого пакета / jar.

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

К сожалению, большая часть кода написана в виде библиотек с довольно широким интерфейсом, потому что они содержат много функциональных возможностей, предоставляемых сервисами из коробки, таких как Factories и Listeners. Этот код имеет тесную связь между реализацией и API, поэтому вы должны иметь то же самое в пути к классам во время компиляции и в OSGi. Одним из решений этой проблемы является включение такого рода кода в комплект с его использованием (но убедитесь, что объекты этой библиотеки не просочились в другие комплекты). Небольшое дополнительное потребление памяти, но оно избавляет вас от головной боли.

Так что с OSGi попытайтесь создавать системы, основанные на сервисах, и компилировать их API сервисов, а не пакет реализации.

2 голосов
/ 05 мая 2010

Существует 6-й вариант, который я использовал для нескольких проектов, который заключается в том, чтобы использовать один проект Eclipse (не проект плагина, а обычный проект Java) и поместить туда весь исходный код. Файл компоновки, связанный с проектом, просто скомпилирует весь код за один проход и впоследствии создаст пакеты из скомпилированных классов (используя Bnd из Ant или из скоро выпускаемого BndTools).

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

2 голосов
/ 05 мая 2010

В основном вы можете использовать:

  • исходная зависимость (с "ссылочными проектами" Eclipse)
  • бинарная зависимость (с использованием jar пакета A)

Но поскольку бинарная зависимость намного чище, она также является той зависимостью, которой лучше всего управлять с помощью инфраструктуры управления выпусками, такой как maven.
И вы можете интегрировать maven в ваш проект Eclipse через m2eclipse .

Плагин Maven для использования будет: maven-bundle-plugin , который вы можете увидеть в действии:

Рассмотрим этот более реальный пример с использованием реализации Felix 'Log Service.
Проект Log Service состоит из одного пакета: org.apache.felix.log.impl.
Он зависит от основных интерфейсов OSGi, а также от интерфейсов OSGi компендиума для конкретных интерфейсов службы журналов. Вот его файл POM:

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.apache.felix</groupId>
  <artifactId>org.apache.felix.log</artifactId>
  <packaging>bundle</packaging>
  <name>Apache Felix Log Service</name>
  <version>0.8.0-SNAPSHOT</version>
  <description>
    This bundle provides an implementation of the OSGi R4 Log service.
  </description>
  <dependencies>
    <dependency>
      <groupId>${pom.groupId}</groupId>
      <artifactId>org.osgi.core</artifactId>
      <version>0.8.0-incubator</version>
    </dependency>
    <dependency>
      <groupId>${pom.groupId}</groupId>
      <artifactId>org.osgi.compendium</artifactId>
      <version>0.9.0-incubator-SNAPSHOT</version>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.felix</groupId>
        <artifactId>maven-bundle-plugin</artifactId>
        <extensions>true</extensions>
        <configuration>
          <instructions>
            <Export-Package>org.osgi.service.log</Export-Package>
            <Private-Package>org.apache.felix.log.impl</Private-Package>
            <Bundle-SymbolicName>${pom.artifactId}</Bundle-SymbolicName>
            <Bundle-Activator>${pom.artifactId}.impl.Activator</Bundle-Activator>
            <Export-Service>org.osgi.service.log.LogService,org.osgi.service.log.LogReaderService</Export-Service>
          </instructions>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>
...