Как обрабатывать записи Import-Package, которые поступают из банок в Bundle-Classpath?

Я поставил несколько банок на свой Bundle-Classpath. Строка ниже показывает запись в моем pom.xml, которая использует подключаемый модуль Felix для создания файла manigest.mf для пакета.

<Bundle-ClassPath>.,lib/com.springsource.org.h2-1.0.71.jar,lib/com.springsource.org.apache.lucene-2.3.2.jar,lib/com.springsource.org.apache.lucene.search-2.3.2.jar</Bundle-ClassPath>

У этих банок есть классы, которые импортируют пакеты, но, насколько я вижу, все они имеют MANIFEST.MF, который имеет свой собственный (точный) список операторов Import-Package.

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

Unresolved references to [com.sun.tools.javac, javax.naming, javax.naming.spi, javax.servlet, javax.servlet.http, javax.sql, javax.transaction.xa]

Все эти ошибки происходят из com.springsource.org.h2-1.0.71.jar, и все эти пакеты импортируются в манифест этого jar.

Я не могу понять:

  • Почему плагин пакета Maven жалуется, если эти пакеты уже импортированы в MANIFEST> MF com.springsource.org.h2-1.0.71.jar
  • Почему проблемы возникают только с com.springsource.org.h2-1.0.71.jar? Я попытался удалить эту конкретную банку, и сборка прошла нормально, хотя com.springsource.org.apache.lucene.search-2.3.2.jar также имеет несколько записей для Import-Package в своем MANIFEST.MF?

Что касается второго пункта, я провел небольшое расследование и чувствую, что здесь есть закономерность. Все импорты, которые com.springsource.org.apache.lucene.search-2.3.2.jar указывает в своем манифесте, выполняются com.springsource.org.apache.lucene-2.3.2.jar, который также указан на Bundle-Classpath.

Зависимости com.springsource.org.h2-1.0.71.jar, которые удовлетворяются com.springsource.org.apache.lucene-2.3.2.jar (который находится в Bundle-Classpath), не перечислены в сообщение об ошибке, однако те зависимости, которые не удовлетворяются jar-файлами в Bundle-Classpath, перечислены в сообщении об ошибке.

Не совсем уверен, что происходит. Каково правило в отношении файлов jar, которые указаны в Bundle-Classpath? Должны ли их элементы импорта (даже если они указаны в Import-Package) их манифеста быть перечислены в pom основного проекта? Или это то, что обеспечивает плагин пакета Maven? Если последнее имеет место, есть ли способ избежать принудительного исполнения?


person Parag    schedule 05.06.2013    source источник


Ответы (2)


Когда вы встраиваете любой jar-файл с помощью тега Embed-Dependency, плагин maven-bundle-plugin также будет анализировать этот jar-файл и добавлять указанные пакеты в список Import-Package пакета хоста. В основном такие пакеты являются необязательными в зависимости от используемой функции. Например, в вашем случае использования jar H2 зависит от Lucene, Servlet API для определенных функций. если ваш сценарий использования не требует этих функций, вы можете пометить эти пакеты как необязательные

<plugin>
        <groupId>org.apache.felix</groupId>
        <artifactId>maven-bundle-plugin</artifactId>
        <version>2.3.5</version>
        <extensions>true</extensions>
        <configuration>
          <obrRepository>NONE</obrRepository>
          <instructions>
            <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
            ..
            <Embed-Dependency>
              h2
            </Embed-Dependency>
            <Import-Package>
              org.osgi.service.jdbc.*;
              org.apache.lucene.*;
              javax.transaction.*;resolution:=optional,
              *
            </Import-Package>
          </instructions>
        </configuration>
      </plugin>

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

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

        <Import-Package>
          *;resolution:=optional
        </Import-Package>

Также обратите внимание, что H2 jar является допустимым пакетом OSGi, поэтому вы можете развернуть его напрямую.

person Chetan    schedule 05.06.2013
comment
Отмечать пакеты как необязательные опасно, если только код, использующий эти пакеты, действительно не предназначен для обработки таких пакетов как необязательных. Другими словами, если код в конечном итоге попытается использовать код из такого пакета, вы получите исключение. Если вы действительно не используете этот код, вы можете полностью запретить импорт, что избавит распознаватель от необходимости даже пытаться найти этот пакет. - person Marcel Offermans; 11.06.2013
comment
@MarcelOffermans Я полностью согласен с тем, что слепо отмечать пакеты как необязательные опасно. Проблема часто заключается в том, что при упаковке сторонних jar-файлов пользователь не знает, какие пакеты действительно необязательны. Другой подход, который я обычно использую, — это добавление таких пакетов в список динамического импорта. Однако плагин maven-bundle-plugin не расширяет подстановочный знак для инструкции DynamicImport-Package, поэтому составить список не так просто. - person Chetan; 12.06.2013
comment
Плагин не расширяет подстановочные знаки для DynamicImport-Package, потому что сам заголовок поддерживает подстановочные знаки, поэтому их расширение было бы неправильным. - person Marcel Offermans; 01.08.2013

правило в отношении файлов jar, которые указаны в Bundle-Classpath?

Файлы, перечисленные в пути к классам пакета, сканируются maven-bundle-plugin (mbp) для определения импорта, необходимого для каждого указанного jar. Тем самым mbp добавит необходимые импорты в main (ваш основной бандл) manifest.mf. Это означает, что пакеты должны экспортироваться внешними пакетами. Если требуемые пакеты не будут найдены вне пакета, пакет не запустится.

У вас есть 2 решения для использования сторонних jar-файлов, необходимых вашему приложению.

  1. Подготовьте пакет OSGi для каждого стороннего jar-файла. Вы можете найти пакет osgi, уже созданный для spring jar и других проектов с открытым исходным кодом, в репозитории spring здесь. Просто ищите его идеально. ты найдешь это.

  2. Используйте Bundle-classpath: при этом вам нужно будет поместить свои сторонние зависимости (и «все» их транзитивные зависимости) в свой пакет и указать каждую банку в заголовке Bundle-ClassPath. В этом случае mbp проанализирует jar-файлы пути к классам пакета и попытается возиться с вашим заголовком import-package. Вы просто избегаете этого, включив свой собственный заголовок в pom.xml. Если вы выберете свой собственный import-package , будьте осторожны, чтобы правильно включить необходимые пакеты из других (внешних) пакетов в ваш import-package.

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

person Shailesh Pratapwar    schedule 05.06.2013