Пакет использует конфликт: Import-Package при запуске пакета

При попытке установить пакет htmlunit появляется следующая ошибка:

com.springsource.com.gargoylesoftware.htmlunit_2.6.0 [370] could not be resolved.
  Reason: Package uses conflict: 
  Import-Package: org.apache.commons.logging.impl; version="1.1.1"

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

И вот мои выводы: Пакет com.springsource.com.gargoylesoftware.htmlunit_2.6.0 имеет следующие инструкции:

Import-Package: \
  org.apache.commons.logging;version="[1.1.1, 2.0.0)",\
  org.apache.commons.logging.impl;version="[1.1.1, 2.0.0)"

Единственный пакет, который имеет это в своем ограничении использования в моей OSGi, это com.springsource.org.apache.commons.logging, который имеет следующие инструкции:

Export-Package: \
  org.apache.commons.logging;version="1.1.1",\
  org.apache.commons.logging.impl;version="1.1.1";\
    uses:="javax.servlet,
           org.apache.avalon.framework.logger,
           org.apache.commons.logging,
           org.apache.log,
           org.apache.log4j"

Import-Package: \
  javax.servlet;version="[2.1.0, 3.0.0)";resolution:=optional,\
  org.apache.avalon.framework.logger;version="[4.1.3, 4.1.3]";resolution:=optional,\
  org.apache.log;version="[1.0.1, 1.0.1]";resolution:=optional,\
  org.apache.log4j;version="[1.2.15, 2.0.0)";resolution:=optional   

В этот момент я застрял, поскольку не могу понять, в чем проблема и как ее решить, хотя из того, что я изложил выше, должно быть ясно, но не для меня: (

Любые идеи...?

Ответ 1

Скорее всего, это связано с 'import-what-you-export'.

A uses указывает, что "если вы хотите импортировать этот пакет, лучше убедитесь, что вы используете те же пакеты, что и я", что означает не только версию пакета, но и идентичный пакет, экспортированный тот же пучок. Ваш второй пакет экспортирует пакет logging и logging.impl, указав, что "если вы хотите использовать logging.impl, используйте тот же logging, который я делаю", а также экспортирует его. Это означает, что любой, кто хочет импортировать logging.impl, должен также импортировать logging из вашего пакета, поскольку он не может быть подключен к какому-либо другому пакету logging. Это приводит к проблемам, если в структуре есть другая копия logging, которая может быть решена ранее.

Вероятно, самый простой способ решить это - добавить logging в Import-Package вашего второго пакета. Таким образом, вы оставляете выбор именно того, какой пакет использовать до рамки.

В несвязанной заметке избавьтесь от всех этих операторов ";resolution:=optional, если только вы не можете действительно работать с ситуацией, когда какой-либо пакет недоступен. Я был бы очень удивлен, что ваш комплект может работать без наличия javax.servlet.

Ответ 2

Обнаружение (Eclipse) ошибки OSGI "uses-conflict" Решение большого дерева пакетов, имеющего конфликт, является утомительной работой. Самая простая ошибка для решения - "Недостающее ограничение". Это просто недостающий комплект или класс, и ошибка явно указывает, какой пакет/пакет java отсутствует. На что я хочу обратить внимание - это критическое сообщение об ошибке OSGI, называемое "use-conflict". Инструменты Equinox OSGI не предоставляют много информации о названии пакета /s, который создает конфликт версий. Есть много статей, объясняющих, как разрешить конфликт, однако ни один из них не показывает, как найти пакет, который быстро конфликтует. Ниже приведен метод определения того, какой пакет + версия вызывает конфликт. Мы начнем с некоторого воображаемого проекта: разработчик написал плагин eclipse + несколько пакетов (JAR). Плагин содержит главным образом код пользовательского интерфейса, а JAR содержат в основном общую/многоразовую логику. Разработчик упаковал их все в функцию Eclipse и пытается ее установить. Из-за "use-conflict" плагин не запускается.

У вас есть плагин. Вы устанавливаете, но он не запускается из-за "использования-конфликта",   закрыть затмение.   перезапустите eclipse через командную строку (linux):

   ./eclipse -console -consoleLog -data /tmp/eclipseTest/workspace/ -clean 

(пользователи win32 должны вызывать eclipse.exe)   Эта команда приведет к консоли osgi, которая нам понадобится позже.   при завершении загрузки eclipse вернитесь в окно командной строки eclipse. вы должны увидеть там командную строку "osgi > " (если не нажать "Enter" дважды)   найти пакеты Java вашего плагина/пакетов. предположим, что он называется com.A, B, C, D и E   запустите консоль osgi:

    osgi> ss com.A

    id    State       Bundle
    7    INSTALLED  com.A
    osgi> start 7

org.osgi.framework.BundleException: пакет "com.A [7]" не может быть разрешен. Причина: Пакет использует конфликт: Требовать-Bundle: com.B; пачка версия = "0.0.0"      на org.eclipse.osgi.framework.internal.core.AbstractBundle.getResolverError... больше стека здесь...

Теперь мы знаем, что расслоение comA зависит от расслоения com.B и что com.B имеет конфликт. Причина, конечно, в питательном использовании конфликта. (побочный комментарий: на самом деле конфликт может быть скрыт еще дальше: в каком-то другом пакете, который ком зависит от, но пока не будем игнорировать это) Идеальное состояние, к которому мы стремимся, - это:

   osgi> ss com.A
   Framework is launched.
   id    State       Bundle
   7    ACTIVE      com.A

но мы еще не находимся.

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

   osgi> bundle 10   

(10 - это случайный пучок id нашего пакета com.B, полученный из контейнера OSGI. Просто запустите консоль osgi: "ss com.B", чтобы найти свой идентификатор пакета)

  • сосредоточьтесь на разделе "Импорт-Пакет". Скопируйте его где-нибудь. При установке плагина в eclipse framework он фактически распаковывается в каталог плагина eclipse. Откройте файл-проводник и перейдите в /plugins. Найдите каталог "плохого" пакета (тот, который использует "use-conflict" ). Вероятно, он будет называться com.B. [version_or_timestamp].

  • перейти к каталогу META-INF. отредактируйте manifest.mf: начните с очистки раздела "Импорт-пакеты" (вырезать вставку этой части в блокнот)

  • перезапустите eclipse (Ctrl + C, чтобы выйти из запуска eclipse в консоли osgi, а затем снова запустить) Теперь затмение должно сказать, что пучок "АКТИВНО". если он не запускался в активном режиме, это может привести к ошибке Missing-Constraint. Это легко решить, так как ошибка довольно информативна, но это не фокус здесь.

  • До тех пор, пока use-conflict не повторится: начните повторное заполнение раздела Import-packages этого манифеста в исходное состояние. Сделайте это по одному пакету java за раз, чтобы вы могли указать, какое изменение вызывает "use-conflict"

  • при редактировании manifest.mf в блокноте убедитесь, что вы нажимаете Enter в столбце 71, а следующая строка начинается с одного пробела. Как вы могли заметить, манифест имеет такую ​​уникальную структуру новой строки, за которой вы должны следовать.

  • перезапустите eclipse (Ctrl + C в консоли osgi, затем запустите).

  • Повторно проверьте состояние пакетов, запустив команду osgi "ss com.A", попробуйте "запустить com.A" и посмотрите, не получится ли какая-либо ошибка.

  • перезапустите eclipse после каждого изменения manifest.mf, как указано выше.

Как только вы добавите плохой импорт java в ваш manifest.mf, вы увидите, что пучок помечен как "RESOLVED" (а не активен). Предположим, что первым пакетом java, который вы обнаружили для разрыва пакета, является javax.xml.bind. запустить на консоли OSGI: "пакеты javax.xml.bind", и вы должны увидеть список разрешенных наборов OSGI + версий + использование для этого пространства имен. если у вас есть более одного провайдера (т.е. более одной версии - это дерево. Посмотрите на его корни), вам может потребоваться изменить исходный пакет и заставить его импортировать определенную версию (с помощью директивы "version" в Import Раздел "Пакет", например javax.xml.bind; version = "[2.1,3]", это говорит osgi о поиске диапазона) В общем случае, если вы пишете пакет OSGI или плагин Eclipse, наилучшей практикой является указать диапазон импорта в явном виде, когда это возможно (и не использовать значение по умолчанию, равное 0.0.0 или любой версии) в заголовках Import-package. Это же правило применяется и к используемым директивам: =, которые иногда используются в заголовке Import-Package.

То же самое относится к заголовку Require-Bundle: лучше всего использовать директиву OSGI "bundle-version", чтобы убедиться, что вы получите ожидаемую версию. Если Maven используется в процессе сборки, это еще более важно, поскольку он позволяет maven корректно вычислять зависимости версии (особенно, если использовать Felix maven-bundle-plugin)

Другая проблема иногда возникает в манифесте пакетов: Импорт-пакет: javax.xml.bind; version = "[2.1.9,3]" но почему-то это не может быть удовлетворено. Вы можете расширить свой диапазон версий до более широкого, если это возможно.

Когда вы разрешили конфликт OSGI, не забудьте отредактировать свои оригинальные манифесты сборки/скрипты.

side comment: вы также можете попробовать запустить "eclipse.exe -clean", который может правильно рассчитать зависимости пакета и позволит запустить ваш плагин, но это не долгосрочное решение.