Управление зависимым от OSGi

ОБНОВЛЕНИЕ 2. Поскольку мой блог немного мертв, ссылки ухудшились, поэтому вы можете просмотреть статьи здесь:

https://www.dropbox.com/s/xvobgzqnl43kcda/Managing_OSGi_Transitive_Dependencies__Part_1____CitizenRandom.pdf?dl=0

https://www.dropbox.com/s/0bdooux4yhrf8lf/Managing%20OSGi%20Transitive%20Dependencies%20%28...pdf?dl=0

https://www.dropbox.com/s/km3mxqah6oy23iq/Why%20using%20Require-Bundle%20is%20a%20bad%20pract...pdf?dl=0

https://www.dropbox.com/s/mtenchtjopcrmr8/How%20many%20ways%20can%20we%20import%20bundles%20in%20OSGi_%20_%20CitizenRandom.pdf?dl=0

https://www.dropbox.com/s/sldxynx3fl8vn61/Managing%20OSGi%20Transitive%20Dependencies%20%282...pdf?dl=0

У меня есть проект maven, используя очень известный плагин felix maven bundle, настроенный в моем POM.XML следующим образом:

<packaging>bundle</packaging>

(...)

<plugin>
            <groupId>org.apache.felix</groupId>
            <artifactId>maven-bundle-plugin</artifactId>
            <extensions>true</extensions>
            <configuration>
                <instructions>
                    <Bundle-SymbolicName>${project.artifactId};singleton:=true</Bundle-SymbolicName>
                    <Bundle-Version>${project.version}</Bundle-Version>
                    <Export-Package>jlifx.*</Export-Package>
                    <!-- <Embed-Dependency>*</Embed-Dependency> -->
                </instructions>
            </configuration>
        </plugin>

А потом у меня есть зависимости 1-го уровня/уровня, включенные в мой POM:

<dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.11</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-lang3</artifactId>
        <version>3.1</version>
    </dependency>
    <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>2.4</version>
    </dependency>
    <dependency>
        <groupId>commons-logging</groupId>
        <artifactId>commons-logging</artifactId>
        <version>1.1</version>
    </dependency>
    <dependency>
        <groupId>io.netty</groupId>
        <artifactId>netty-all</artifactId>
        <version>5.0.0.Alpha1</version>
    </dependency>
</dependencies>

И теперь моя проблема начинается... Если я делаю mvn install, я получу свой пакет, хорошо сложенный с его очень большим MANIFEST.MF и всеми, но я не буду получать другие зависимости что если я возьму свой файл пакета и отброшу его на свой экземпляр среды OSGi, я получу что-то вроде "Невозможно решить 1.0: missing required [1.0] osgi.wiring.package; (& (osgi.wiring.package) = etc..."

Таким образом, один из способов, с помощью которого я создал свои пакеты зависимостей 1-го уровня, - создать профиль в моем POM, как это:

<profiles>
    <!-- http://www.lucamasini.net/Home/osgi-with-felix/creating-osgi-bundles-of-your-maven-dependencies -->
    <!-- -Pcreate-osgi-bundles-from-dependencies bundle:wrap -->
    <profile>
        <id>create-osgi-bundles-from-dependencies</id>
        <build>
            <directory>${basedir}/bundles</directory>
            <plugins>
                <plugin>
                    <groupId>org.apache.felix</groupId>
                    <artifactId>maven-bundle-plugin</artifactId>
                    <version>2.0.1</version>
                    <extensions>true</extensions>
                    <executions>
                        <execution>
                            <id>wrap-my-dependency</id>
                            <goals>
                                <goal>wrap</goal>
                            </goals>
                            <configuration>
                                <wrapImportPackage>;</wrapImportPackage>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
    </profile>
</profiles>

И таким образом, когда я выполняю пакет mvn -Pcreate-osgi-bundles-from-dependencies: wrap, я получу пакеты, хорошо сконструированные и работающие. Но здесь приходит реальная сделка. Эти пучки также имеют собственные зависимости, поэтому они должны будут иметь свои зависимости, обернутые в виде пакетов. Согласно многочисленным веб-страницам, давным-давно у нас была цель mvn org.apache.felix: maven-bundle-plugin: bundleall сделать это для нас, но я пробовал, это ошибка и возврат исключений, и он отмечен как устаревший, согласно Stuart, он будет удален в maven 2.4.1 и более поздних версиях (ref: https://issues.apache.org/jira/browse/FELIX-4145).

Итак, теперь мое единственное решение - вручную, проверить каждый манифест моих зависимостей 1-го уровня и пойти google для баннеров, содержащих необходимые пакеты, добавить их в мои POM.XML в качестве зависимостей maven, а затем запустите пакет mvn -Pcreate-osgi-bundles-from-dependencies: wrap, чтобы обернуть их в виде пакетов.

Это то, что известно как аддон зависимости...

Есть ли способ автоматизировать эту задачу для решения n-го уровня зависимости для проекта osgi maven-bundle? То есть сделайте maven изучите каждый файл манифеста зависимостей 1-го уровня, прочитайте пакеты импорта, посмотрите в центральном репо на банке, которые предоставляют такие пакеты, загружают их и завершают их как пакеты?

Примечание. Просьба предоставить подробные инструкции о том, как этого достичь, не просто ссылаться на этот инструмент или тот инструмент, который может решить эту проблему. Основная проблема с этими инструментами заключается в отсутствии примеров и документации. Например, bundleall устарел, но, похоже, нет инструмента для его замены, по крайней мере, в их официальной документации плагина maven bundle, который до сих пор устарел... Я уверен, что я, возможно, перешел с инструментами, способными это сделать, но отсутствие документации запрещает новичку знать, что...

Спасибо!





РЕДАКТИРОВАТЬ-1:

Спасибо за ваши ответы до сих пор:) Я думаю, что я не объяснил свою ситуацию самым правильным образом, и я чувствую некоторые трудности, делая это просто с помощью простого текста. Или, может быть, я не понимаю вашего ответа. Я полностью "свежий" в OSGi, и единственное знание, которое я получаю, - это книги (OSGi в действии и т.д.) И Google.

Представьте, что мой пакет импортирует пакеты A и B. Однако пакет A импортирует пакет C, а пакет B также импортирует C. Но теперь C импортирует пакеты D, E, F и G. С другой стороны, пакет D импортирует тонну других пакетов, а также E, F и G.

Единственными пакетами, которые у меня есть на моем компьютере, являются мои собственные пакеты и пакеты, которые предоставляют пакеты A и B, потому что они являются моими зависимостями 1-го уровня. Однако у меня нет других необходимых пакетов, даже если они установлены в качестве jars в моей установочной папке JDK, у меня их нет в виде пакетов, и даже я не знаю, где я могу собрать банки (например, на самом деле я знаю, но представьте себе, что нет).

Я бы ожидал, что инструмент построения должен был выполнить алгоритм, аналогичный следующему:

1) Перейдите в мой пакет MANIFEST.MF и прочитайте поле Import-Package. Перечислите все необходимые пакеты и их соответствующие. версии.

2)Найдите где-нибудь в Интернете для банок или пакетов моих необходимых библиотек.

3) Загрузите каждый из них и проверьте, являются ли они просто ясными банками или имеют действительный файл манифеста osgi (т.е. они являются пакетом)

3.1) , если они представляют собой набор, скопируйте их в мои папки/папку.

3.2) else заверните банку в пакет, используя любой инструмент для этого, и скопируйте пакет в мою папку/папку.

4) Теперь, для каждого загруженного/созданного нового пакета повторите шаги 1), 2), 3) и 4).

Что я хочу в качестве конечного результата: Пакет для каждой библиотеки, к которой у меня есть прямая или косвенная зависимость, поэтому я могу установить их на лету в моем экземпляре OSGi Framework, таких как феликс или равноденствие.

Что я не хочу:

1) Имейте это в виду вручную, потому что, если я попытаюсь решить каждую зависимость зависимости, я могу потратить часы или дни на сбор и упаковку банок.

2) Вставьте все зависимости в пакет ubber/mega. Это плохая практика по нескольким книгам, которые я прочитал, сложнее поддерживать каждую зависимость индивидуально, а также, она развращает модульность.

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

Есть ли способ сделать это автоматически или мне не хватает чего-то очень большого в OSGi? Настолько велика, что мне никогда не понадобится делать то, о чем я прошу?

РЕДАКТИРОВАТЬ-2:

Некоторые, если не все, зависимости от импорта-пакета могут быть решены во время выполнения. Представьте, что OSGi Framework пытается запустить пакет, но вместо отображения сообщения об ошибке "Невозможно разрешить 8.0: отсутствует требование [8.0] osgi.wiring.package;" он будет искать этот пакет онлайн, загрузить его и установить его на лету. Жизнь будет намного проще.

Ответы

Ответ 1

Использовать условный пакет из maven-bundle-plugin для рекурсивного встраивания всех необходимых пакетов в ваш пакет JAR и активировать тег true.

Ответ 2

Если вы хотите обернуть банки, которые не являются пакетами, но просто нужно, чтобы эти банки были пакетами в виде библиотек в OSGi framework, вы можете обернуть их инструментом BND. См. Ссылку Как создавать/генерировать пакеты OSGi из существующих сторонних баннеров?

Но я вижу, что вы используете очень распространенные библиотеки, чем уже были преобразованы в пакеты osgi. Вы можете найти много библиотек, преобразованных в пакеты в SpringSource Enterprise Bundle Repository.

Но если вы не можете найти какую-либо библиотеку, которая не была преобразована в хороший пакет OSGi, вы можете использовать протокол WRAP из PAX-URL для установки этих зависимостей в OSGi. Использовать этот протокол зависит от используемой вами среды OSGi, но в apache karaf устанавливается по умолчанию. Например, чтобы установить библиотеку из репозитория maven:

[email protected]> osgi:install -s 'wrap:mvn:commons-lang/commons-lang/2.4$Bundle-SymbolicName=commons-lang&Bundle-Version=2.4'

Эта инструкция устанавливает библиотеку commons-lang из репозитория maven в среду OSGi и завершает ее как пакет OSGi с заголовками, отображаемыми в строке.

Для зависимостей автоматической установки, как вы говорите во втором редактировании, есть несколько решений, но это небольшая работа. Существует два основных решения для автоматической компоновки наборов кадров OSGi, пакетов репозитория Felix OBR и пакетов Felix Provisioning и репозитория Equinox p2. У обоих из них есть консольные команды для автоматической установки пакетов и функций. Проблема в том, что на самом деле я не могу найти хороший публичный репозиторий пакетов. Вам нужно создать собственный репозиторий со всеми пакетами, чем вам нужно.

Если вы используете плагин maven-bundle, когда вы устанавливаете артефакты в свой локальный репозиторий maven, плагин обновляет файл "repository.xml", расположенный в корневом каталоге вашего репозитория, чтобы отражать потребности и возможности ваших пакетов. Этот файл является файлом репозитория OBR.

Ответ 3

Что я хочу в качестве конечного результата: комплект для каждой библиотеки, к которой я имеют прямую или косвенную зависимость, поэтому я могу их установить на лету в моем экземпляре OSGi Framework, например, felix или equinox.

Хорошо, если я правильно понял ваш вопрос, вы хотите что-то вроде плагина maven-dependency?

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <executions>
                <execution>
                    <id>copy-dependencies</id>
                    <phase>package</phase>
                    <goals>
                        <goal>copy-dependencies</goal>
                    </goals>
                    <configuration>
                        <outputDirectory>${project.build.directory}/thridparty-libs</outputDirectory>
                        <overWriteIfNewer>true</overWriteIfNewer>
                        <includeScope>runtime</includeScope>
                        <excludeGroupIds>${project.groupId}</excludeGroupIds>
                        <excludeArtifactIds>...</excludeArtifactIds>
                    </configuration>
                </execution>
            </executions>
        </plugin>

Если вы столкнулись с проблемой, что у вас много зависимостей без osgi-манифеста, вы должны проверить, доступны ли они в репозитории корпоративных пакетов springsource http://ebr.springsource.com/repository/ и пакеты apache-servicemix на http://search.maven.org/#search|ga|1|g%3A%22org.apache.servicemix.bundles%22 (как упоминалось в моем комментарии)

Ответ 4

попробуйте p2-maven-plugin, он делает именно то, что вы описали от 1 до 4. его фактически использует tycho для сборки репозитория p2, но вы также можете используйте его для сбора и связывания зависимостей и переходных зависимостей. Im не пишут пример здесь, потому что в ссылке выше все мысли хорошо документированы примерами в простой форме для понимания.

надеюсь, что это поможет

Ответ 5

Эти функции включают ваши зависимости jars в jar в папке: OSGI-INF/lib/

В build.gradle:

**

dependencies {
    ...dependencies
}
def bundleClassPath() {
    def list = []
    configurations.compile.each {
        list += 'OSGI-INF/lib/' + it.name
    }
    return list.join(',')
}
def includeResource() {
  def list = []
  configurations.compile.each {
    list += 'OSGI-INF/lib/' + it.name + "=" + it.path
  }
  return list.join(',')
}
bundle {
  instructions << [ 
    'Bundle-ClassPath' : bundleClassPath(),
    '-includeresource' : includeResource()
  ]
}

**